SpringBoot自定义注解接收json参数

SpringBoot如果接受json参数的话需要定义实体类然后使用@RequestBody注解,但是如果每个接口都创建一个实体类的话太麻烦,因此可以使用自定义注解的方法接收。从网上发现了这篇博客,解决了一个大大的疑惑。。转载: 大佬的博客

  1. RequestJson
package com.school.service.config;

import java.lang.annotation.*;

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestJson {
    /**
     * 值
     */
    String value() default "";

    /**
     * 是否必须
     */
    boolean require() default false;
}

  1. RequestJsonHandlerMethodArgumentResolver
package com.school.service.config;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.core.MethodParameter;
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;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.rmi.ServerException;

@Slf4j
public class RequestJsonHandlerMethodArgumentResolver  implements HandlerMethodArgumentResolver {

    /**
     * key
     */
    private static final String JSON_BODY_KEY = "JSON_BODY_KEY";

    @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 {

        // 获取jsonNode
        JsonNode jsonNode = getJsonBody(webRequest);

        RequestJson requestSingleParam = parameter.getParameterAnnotation(RequestJson.class);
        // 名
        String value = determineParamName(parameter, requestSingleParam);
        // 结果
        JsonNode paramValue = jsonNode.get(value);
        // 是否必须
        boolean require = requestSingleParam.require();
        if (paramValue == null && require) {
            throw new ServerException("parameter[" + value + "]不能为空。");
        }

        if (paramValue == null) {
            return null;
        }
        Class<?> parameterType = parameter.getParameterType();
        Constructor<?> constructor = parameterType.getConstructor(String.class);
        Object param = null;
        try {
            param = constructor.newInstance(paramValue.asText());
        } catch (Exception e) {
            log.error("bind method parameters error", e);
            throw new ServerException("parameter[" + value + "] format error for input value[" + paramValue.toString() + "]");
        }
        return param;
    }

    private String determineParamName(MethodParameter parameter, RequestJson requestSingleParam) {
        String value = requestSingleParam.value();
        if (value == null  || value.isEmpty()) {
            value = parameter.getParameterName();
        }
        return value;
    }

    private JsonNode getJsonBody(NativeWebRequest webRequest) throws JsonProcessingException {

        // 有就直接获取
        String jsonBody = (String) webRequest.getAttribute(JSON_BODY_KEY, NativeWebRequest.SCOPE_REQUEST);
        // 没有就从请求中读取
        if (jsonBody == null) {
            try {
                HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
                jsonBody = IOUtils.toString(servletRequest.getReader());
                webRequest.setAttribute(JSON_BODY_KEY, jsonBody, NativeWebRequest.SCOPE_REQUEST);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return new ObjectMapper().readTree(jsonBody);
    }
}

  1. 配置config
package com.school.service.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.io.File;
import java.util.List;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

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

  1. 使用
public Result register(@RequestJson String userCode, @RequestJson String nickName, @RequestJson String password) {

成功

posted @ 2021-11-23 17:07  两小无猜  阅读(1732)  评论(0编辑  收藏  举报