spring boot 自定义请求参数解析注解

时间:2021-11-15 20:36:17

介绍

一些请求参数, 需要解析成某个自定义的类, 而spring boot中并没有提供这样自动转换的注解, 但是,spring boot 预留了扩展接口,所以,我们可以自定义实现一个注解.

例如: http://localhost:8999/new/test?a={"name":"aaa", "age":18}&b=123
我们可以通过自定义注解,来把 a 对应的值转换成我们系统中的类

创建注解

package com.example.demo.conf;

import java.lang.annotation.*;

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestJson {
    String value();
}

创建请求参数解析实现类

package com.example.demo.conf;

import com.alibaba.fastjson.JSONObject;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

public class RequestJsonHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(RequestJson.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        RequestJson requestJson = parameter.getParameterAnnotation(RequestJson.class);
        String value = requestJson.value();
        Class clazz = parameter.getParameterType();
        String jsonData = webRequest.getParameter(value);
        if (jsonData == null) {
            return clazz.newInstance();
        }
        Object object = JSONObject.parseObject(jsonData, clazz);
        return object;
    }
}

注入spring boot

package com.example.demo;

import com.example.demo.conf.RequestJsonHandlerMethodArgumentResolver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.util.List;

@SpringBootApplication
public class DemoApplication extends WebMvcConfigurerAdapter{

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new RequestJsonHandlerMethodArgumentResolver());
        super.addArgumentResolvers(argumentResolvers);
    }
}

测试

Controller

package com.example.demo.controller;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.conf.RequestJson;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @GetMapping("/new/test")
    public Object newTest(@RequestJson("a") Person person, @RequestParam("b") Integer b) {
        System.out.println("a : " + JSONObject.toJSONString(person));
        System.out.println("b : " + b);
        return "ok";
    }

    public static class Person {
        private String name;
        private Integer age;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }
    }
}

请求

请求url: http://localhost:8999/new/test?a={"name":"aaa", "age":18}&b=123

打印结果:

a : {“age”:18,”name”:”aaa”}
b : 123