zoukankan      html  css  js  c++  java
  • 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) {
    

    成功

  • 相关阅读:
    Objective-C NSFileManager 文件管理总结
    ScrollView在RelativeLayout失效问题
    解决myeclipse中struts2 bug问题包的替换问题
    SOA究竟是个啥
    Flash--元件和实例
    MyEclipse中加入web项目到tomcat
    [C]if (CONDITION)语句中CONDITION的情况
    GTK经常使用控件之笔记本控件( GtkNotebook )
    org.apache.solr.handler.dataimport.DataImportHandlerException: Data Config problem: 对实体 &quot;characterEn
    Android自动测试之Monkey工具
  • 原文地址:https://www.cnblogs.com/charlottepl/p/15594115.html
Copyright © 2011-2022 走看看