├── .gitignore ├── src └── main │ ├── java │ └── io │ │ └── github │ │ └── chujianyun │ │ ├── Application.java │ │ ├── domain │ │ ├── User2.java │ │ ├── Dog2.java │ │ ├── User.java │ │ └── Dog.java │ │ ├── annotation │ │ └── MultiRequestBody.java │ │ ├── config │ │ └── WebConfig.java │ │ ├── controller │ │ └── DemoController.java │ │ └── bean │ │ └── MultiRequestBodyArgumentResolver.java │ └── docs │ └── spring-servlet-demo.xml ├── README.md ├── pom.xml └── multi-requestbody.iml /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Java template 3 | # Compiled class file 4 | *.class 5 | 6 | # Log file 7 | *.log 8 | 9 | # BlueJ files 10 | *.ctxt 11 | 12 | # Mobile Tools for Java (J2ME) 13 | .mtj.tmp/ 14 | .idea/ 15 | 16 | # Package Files # 17 | *.jar 18 | *.war 19 | *.nar 20 | *.ear 21 | *.zip 22 | *.tar.gz 23 | *.rar 24 | 25 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 26 | hs_err_pid* 27 | 28 | -------------------------------------------------------------------------------- /src/main/java/io/github/chujianyun/Application.java: -------------------------------------------------------------------------------- 1 | package io.github.chujianyun; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 5 | import org.springframework.context.annotation.ComponentScan; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * @author Wangyang Liu 10 | * @date 2018/08/27 11 | */ 12 | @Configuration 13 | @EnableAutoConfiguration 14 | @ComponentScan 15 | public class Application { 16 | public static void main(String[] args) { 17 | SpringApplication.run(Application.class, args); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/io/github/chujianyun/domain/User2.java: -------------------------------------------------------------------------------- 1 | package io.github.chujianyun.domain; 2 | 3 | /** 4 | * @author Wangyang Liu 5 | * @date 2018/08/28 6 | */ 7 | public class User2 { 8 | 9 | private String name; 10 | 11 | private Integer age; 12 | 13 | private Dog dog; 14 | 15 | public String getName() { 16 | return name; 17 | } 18 | 19 | public void setName(String name) { 20 | this.name = name; 21 | } 22 | 23 | public Integer getAge() { 24 | return age; 25 | } 26 | 27 | public void setAge(Integer age) { 28 | this.age = age; 29 | } 30 | 31 | public Dog getDog() { 32 | return dog; 33 | } 34 | 35 | public void setDog(Dog dog) { 36 | this.dog = dog; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/io/github/chujianyun/domain/Dog2.java: -------------------------------------------------------------------------------- 1 | package io.github.chujianyun.domain; 2 | 3 | /** 4 | * @author Wangyang Liu 5 | * @date 2018/08/28 6 | */ 7 | public class Dog2 { 8 | 9 | private String name; 10 | 11 | private String color; 12 | 13 | private User user; 14 | 15 | public String getName() { 16 | return name; 17 | } 18 | 19 | public void setName(String name) { 20 | this.name = name; 21 | } 22 | 23 | public String getColor() { 24 | return color; 25 | } 26 | 27 | public void setColor(String color) { 28 | this.color = color; 29 | } 30 | 31 | public User getUser() { 32 | return user; 33 | } 34 | 35 | public void setUser(User user) { 36 | this.user = user; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/io/github/chujianyun/domain/User.java: -------------------------------------------------------------------------------- 1 | package io.github.chujianyun.domain; 2 | 3 | /** 4 | * @author Wangyang Liu 5 | * @date 2018/08/27 6 | */ 7 | public class User { 8 | 9 | private String name; 10 | 11 | private Integer age; 12 | 13 | public String getName() { 14 | return name; 15 | } 16 | 17 | public void setName(String name) { 18 | this.name = name; 19 | } 20 | 21 | public Integer getAge() { 22 | return age; 23 | } 24 | 25 | public void setAge(Integer age) { 26 | this.age = age; 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "User{" + 32 | "name='" + name + '\'' + 33 | ", age=" + age + 34 | '}'; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/io/github/chujianyun/annotation/MultiRequestBody.java: -------------------------------------------------------------------------------- 1 | package io.github.chujianyun.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Controller中方法接收多个JSON对象 10 | * 11 | * @author Wangyang Liu 12 | * @date 2018/08/27 13 | */ 14 | @Target(ElementType.PARAMETER) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | public @interface MultiRequestBody { 17 | /** 18 | * 是否必须出现的参数 19 | */ 20 | boolean required() default true; 21 | 22 | /** 23 | * 当value的值或者参数名不匹配时,是否允许解析最外层属性到该对象 24 | */ 25 | boolean parseAllFields() default true; 26 | 27 | /** 28 | * 解析时用到的JSON的key 29 | */ 30 | String value() default ""; 31 | } -------------------------------------------------------------------------------- /src/main/java/io/github/chujianyun/domain/Dog.java: -------------------------------------------------------------------------------- 1 | package io.github.chujianyun.domain; 2 | 3 | /** 4 | * @author Wangyang Liu 5 | * @date 2018/08/27 6 | */ 7 | public class Dog { 8 | 9 | private String name; 10 | 11 | private String color; 12 | 13 | 14 | public String getName() { 15 | return name; 16 | } 17 | 18 | public void setName(String name) { 19 | this.name = name; 20 | } 21 | 22 | public String getColor() { 23 | return color; 24 | } 25 | 26 | public void setColor(String color) { 27 | this.color = color; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return "Dog{" + 33 | "name='" + name + '\'' + 34 | ", color='" + color + '\'' + 35 | '}'; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spring-MultiRequestBody 2 | ## 项目主要功能 3 | 为Spring多@RequestBody支持,来解决Controller中POST方式JSON格式请求时 4 | 1. 无法直接用@RequestBody解析基本类型包装类的问题。 5 | 2. 无法使用@RequestBody接收多个实体的问题。 6 | 7 | ## 项目优势 8 | 1. 支持通过注解的value指定JSON的key来解析对象。 9 | 2. 支持通过注解无value,直接根据参数名来解析对象 10 | 3. 支持基本类型的注入 11 | 4. 支持GET和其他请求方式注入 12 | 5. 支持通过注解无value且参数名不匹配JSON串key时,根据属性解析对象。 13 | 6. 支持多余属性(不解析、不报错)、支持参数“共用”(不指定value时,参数名不为JSON串的key) 14 | 7. 支持当value和属性名找不到匹配的key时,对象是否匹配所有属性。 15 | 16 | ## 重要更新记录 17 | - 2019年02月25日 新增xml方式参考配置 18 | 19 | - 2019年02月07日 fix 当list参数为空时,parameterType.newInstance会导致异常 20 | 21 | - 2018年12月28日 新增测试用例,完善解析部分代码 22 | 23 | - 2018年10月23日 完善项目格式 24 | 25 | - 2018年08月28日 创建第一版 26 | 27 | ## 参考资料 28 | * 对应博文: [明明如月小角落CSDN](https://blog.csdn.net/w605283073/article/details/82119284) 29 | * 其他参考:[StackOverFlow讨论](https://stackoverflow.com/questions/12893566/passing-multiple-variables-in-requestbody-to-a-spring-mvc-controller-using-ajax) 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/main/java/io/github/chujianyun/config/WebConfig.java: -------------------------------------------------------------------------------- 1 | package io.github.chujianyun.config; 2 | 3 | import io.github.chujianyun.bean.MultiRequestBodyArgumentResolver; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.http.converter.HttpMessageConverter; 7 | import org.springframework.http.converter.StringHttpMessageConverter; 8 | import org.springframework.web.method.support.HandlerMethodArgumentResolver; 9 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 10 | 11 | import java.nio.charset.Charset; 12 | import java.util.List; 13 | 14 | /** 15 | * Web Config Demo 16 | * 17 | * @author Wangyang Liu liuwangyangedu@163.com 18 | * @date 2018/08/27 19 | */ 20 | @Configuration 21 | public class WebConfig extends WebMvcConfigurerAdapter { 22 | @Override 23 | public void addArgumentResolvers(List argumentResolvers) { 24 | // 添加MultiRequestBody参数解析器 25 | argumentResolvers.add(new MultiRequestBodyArgumentResolver()); 26 | } 27 | 28 | @Bean 29 | public HttpMessageConverter responseBodyConverter() { 30 | // 解决中文乱码问题 31 | return new StringHttpMessageConverter(Charset.forName("UTF-8")); 32 | } 33 | 34 | @Override 35 | public void configureMessageConverters(List> converters) { 36 | super.configureMessageConverters(converters); 37 | converters.add(responseBodyConverter()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.chujianyun 8 | multi-requestbody 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | UTF-8 14 | 1.8 15 | 1.8 16 | 17 | 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter-parent 22 | 1.5.1.RELEASE 23 | 24 | 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-web 30 | 31 | 32 | 33 | org.apache.commons 34 | commons-lang3 35 | 3.1 36 | 37 | 38 | 39 | 40 | commons-io 41 | commons-io 42 | 2.6 43 | 44 | 45 | 46 | 47 | 48 | com.alibaba 49 | fastjson 50 | 1.2.35 51 | 52 | 53 | 54 | 55 | 56 | 57 | GNU General Public License, version 2 58 | https://www.gnu.org/licenses/old-licenses/gpl-2.0.html 59 | repo 60 | 61 | 62 | 63 | https://github.com/chujianyun/Spring-MultiRequestBody 64 | https://github.com/chujianyun/Spring-MultiRequestBody.git 65 | https://github.com/chujianyun/Spring-MultiRequestBody 66 | 67 | 68 | 69 | liuwangyang 70 | liuwangyangedu@163.com 71 | https://github.com/chujianyun 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | org.springframework.boot 80 | spring-boot-maven-plugin 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/main/docs/spring-servlet-demo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | application/json 32 | text/html 33 | text/plain 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | QuoteFieldNames 50 | 51 | 52 | 53 | 54 | 55 | WriteNullListAsEmpty 56 | 57 | WriteNullStringAsEmpty 58 | 59 | WriteNullBooleanAsFalse 60 | 61 | 62 | 63 | PrettyFormat 64 | DisableCircularReferenceDetect 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /src/main/java/io/github/chujianyun/controller/DemoController.java: -------------------------------------------------------------------------------- 1 | package io.github.chujianyun.controller; 2 | 3 | 4 | import io.github.chujianyun.annotation.MultiRequestBody; 5 | import io.github.chujianyun.domain.Dog; 6 | import io.github.chujianyun.domain.User; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * Controller Demo 15 | * 16 | * @author Wangyang Liu 17 | * @date 2018/08/27 18 | */ 19 | @Controller 20 | @RequestMapping("/xhr/test") 21 | public class DemoController { 22 | 23 | 24 | @RequestMapping("/testStr") 25 | @ResponseBody 26 | public String multiRequestBodyDemo1(@MultiRequestBody String test1, @MultiRequestBody String test2) { 27 | 28 | System.out.println(test1 + "-->" + test2); 29 | return ""; 30 | } 31 | 32 | @RequestMapping("/testChar") 33 | @ResponseBody 34 | public String multiRequestBodyDemo1(@MultiRequestBody char id) { 35 | 36 | System.out.println(id); 37 | return ""; 38 | } 39 | 40 | @RequestMapping("/demo") 41 | @ResponseBody 42 | public String multiRequestBodyDemo1(@MultiRequestBody Dog dog, @MultiRequestBody User user) { 43 | System.out.println(dog.toString() + user.toString()); 44 | return dog.toString() + ";" + user.toString(); 45 | } 46 | 47 | 48 | @RequestMapping("/demo2") 49 | @ResponseBody 50 | public String multiRequestBodyDemo2(@MultiRequestBody("dog") Dog dog, @MultiRequestBody User user) { 51 | System.out.println(dog.toString() + user.toString()); 52 | return dog.toString() + ";" + user.toString(); 53 | } 54 | 55 | @RequestMapping("/demo3") 56 | @ResponseBody 57 | public String multiRequestBodyDemo3(@MultiRequestBody("dog") Dog dog, @MultiRequestBody("user") User user) { 58 | System.out.println(dog.toString() + user.toString()); 59 | return dog.toString() + ";" + user.toString(); 60 | } 61 | 62 | @RequestMapping("/demo4") 63 | @ResponseBody 64 | public String multiRequestBodyDemo4(@MultiRequestBody("dog") Dog dog, @MultiRequestBody Integer age) { 65 | System.out.println(dog.toString() + age.toString()); 66 | return dog.toString() + ";age属性为:" + age.toString(); 67 | } 68 | 69 | 70 | @RequestMapping("/demo5") 71 | @ResponseBody 72 | public String multiRequestBodyDemo5(@MultiRequestBody("color") String color, @MultiRequestBody("age") Integer age) { 73 | return "color=" + color + "; age=" + age; 74 | } 75 | 76 | @RequestMapping("/demo6") 77 | @ResponseBody 78 | public String multiRequestBodyDemo6(@MultiRequestBody("dog") Dog dog, @MultiRequestBody Integer age) { 79 | System.out.println(dog.toString() + age.toString()); 80 | return dog.toString() + ";age属性为:" + age.toString(); 81 | } 82 | 83 | 84 | @RequestMapping("/demo7") 85 | @ResponseBody 86 | public String multiRequestBodyDemo7(@MultiRequestBody(required = false) Dog dog, @MultiRequestBody("age") Integer age) { 87 | return "dog=" + dog + "; age=" + age; 88 | } 89 | 90 | 91 | @RequestMapping("/demo10") 92 | @ResponseBody 93 | public String multiRequestBodyDemo10(@MultiRequestBody(parseAllFields = false, required = false) Dog dog) { 94 | return dog.toString(); 95 | } 96 | 97 | @RequestMapping("/demo99") 98 | @ResponseBody 99 | public String multiRequestBodyDemo99(@MultiRequestBody(parseAllFields = false, required = false) Character demo) { 100 | return demo.toString(); 101 | } 102 | 103 | @RequestMapping("/testList") 104 | @ResponseBody 105 | public String multiRequestBodyDemo1(@MultiRequestBody List test, @MultiRequestBody String str) { 106 | 107 | return test.toString() + str; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /multi-requestbody.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/main/java/io/github/chujianyun/bean/MultiRequestBodyArgumentResolver.java: -------------------------------------------------------------------------------- 1 | package io.github.chujianyun.bean; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.JSONException; 5 | import com.alibaba.fastjson.JSONObject; 6 | import io.github.chujianyun.annotation.MultiRequestBody; 7 | import org.apache.commons.io.IOUtils; 8 | import org.apache.commons.lang3.StringUtils; 9 | import org.springframework.core.MethodParameter; 10 | import org.springframework.web.bind.support.WebDataBinderFactory; 11 | import org.springframework.web.context.request.NativeWebRequest; 12 | import org.springframework.web.method.support.HandlerMethodArgumentResolver; 13 | import org.springframework.web.method.support.ModelAndViewContainer; 14 | 15 | import javax.servlet.http.HttpServletRequest; 16 | import java.io.IOException; 17 | import java.lang.reflect.Field; 18 | import java.util.HashSet; 19 | import java.util.Set; 20 | 21 | /** 22 | * MultiRequestBody解析器 23 | * 解决的问题: 24 | * 1、单个字符串等包装类型都要写一个对象才可以用@RequestBody接收; 25 | * 2、多个对象需要封装到一个对象里才可以用@RequestBody接收。 26 | * 主要优势: 27 | * 1、支持通过注解的value指定JSON的key来解析对象。 28 | * 2、支持通过注解无value,直接根据参数名来解析对象 29 | * 3、支持基本类型的注入 30 | * 4、支持GET和其他请求方式注入 31 | * 5、支持通过注解无value且参数名不匹配JSON串key时,根据属性解析对象。 32 | * 6、支持多余属性(不解析、不报错)、支持参数“共用”(不指定value时,参数名不为JSON串的key) 33 | * 7、支持当value和属性名找不到匹配的key时,对象是否匹配所有属性。 34 | * 35 | * @author Wangyang Liu QQ: 605283073 36 | * @date 2018/08/27 37 | */ 38 | public class MultiRequestBodyArgumentResolver implements HandlerMethodArgumentResolver { 39 | 40 | private static final String JSONBODY_ATTRIBUTE = "JSON_REQUEST_BODY"; 41 | 42 | /** 43 | * 设置支持的方法参数类型 44 | * 45 | * @param parameter 方法参数 46 | * @return 支持的类型 47 | */ 48 | @Override 49 | public boolean supportsParameter(MethodParameter parameter) { 50 | // 支持带@MultiRequestBody注解的参数 51 | return parameter.hasParameterAnnotation(MultiRequestBody.class); 52 | } 53 | 54 | /** 55 | * 参数解析,利用fastjson 56 | * 注意:非基本类型返回null会报空指针异常,要通过反射或者JSON工具类创建一个空对象 57 | */ 58 | @Override 59 | public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { 60 | 61 | String jsonBody = getRequestBody(webRequest); 62 | 63 | JSONObject jsonObject = JSON.parseObject(jsonBody); 64 | // 根据@MultiRequestBody注解value作为json解析的key 65 | MultiRequestBody parameterAnnotation = parameter.getParameterAnnotation(MultiRequestBody.class); 66 | //注解的value是JSON的key 67 | String key = parameterAnnotation.value(); 68 | Object value; 69 | // 如果@MultiRequestBody注解没有设置value,则取参数名FrameworkServlet作为json解析的key 70 | if (StringUtils.isNotEmpty(key)) { 71 | value = jsonObject.get(key); 72 | // 如果设置了value但是解析不到,报错 73 | if (value == null && parameterAnnotation.required()) { 74 | throw new IllegalArgumentException(String.format("required param %s is not present", key)); 75 | } 76 | } else { 77 | // 注解为设置value则用参数名当做json的key 78 | key = parameter.getParameterName(); 79 | value = jsonObject.get(key); 80 | } 81 | 82 | // 获取的注解后的类型 Long 83 | Class parameterType = parameter.getParameterType(); 84 | // 通过注解的value或者参数名解析,能拿到value进行解析 85 | if (value != null) { 86 | //基本类型 87 | if (parameterType.isPrimitive()) { 88 | return parsePrimitive(parameterType.getName(), value); 89 | } 90 | // 基本类型包装类 91 | if (isBasicDataTypes(parameterType)) { 92 | return parseBasicTypeWrapper(parameterType, value); 93 | // 字符串类型 94 | } else if (parameterType == String.class) { 95 | return value.toString(); 96 | } 97 | // 其他复杂对象 98 | return JSON.parseObject(value.toString(), parameterType); 99 | } 100 | 101 | // 解析不到则将整个json串解析为当前参数类型 102 | if (isBasicDataTypes(parameterType)) { 103 | if (parameterAnnotation.required()) { 104 | throw new IllegalArgumentException(String.format("required param %s is not present", key)); 105 | } else { 106 | return null; 107 | } 108 | } 109 | 110 | // 非基本类型,不允许解析所有字段,必备参数则报错,非必备参数则返回null 111 | if (!parameterAnnotation.parseAllFields()) { 112 | // 如果是必传参数抛异常 113 | if (parameterAnnotation.required()) { 114 | throw new IllegalArgumentException(String.format("required param %s is not present", key)); 115 | } 116 | // 否则返回null 117 | return null; 118 | } 119 | // 非基本类型,允许解析,将外层属性解析 120 | Object result; 121 | try { 122 | result = JSON.parseObject(jsonObject.toString(), parameterType); 123 | } catch (JSONException jsonException) { 124 | // TODO:: 异常处理返回null是否合理? 125 | result = null; 126 | } 127 | 128 | // 如果非必要参数直接返回,否则如果没有一个属性有值则报错 129 | if (!parameterAnnotation.required()) { 130 | return result; 131 | } else { 132 | boolean haveValue = false; 133 | Field[] declaredFields = parameterType.getDeclaredFields(); 134 | for (Field field : declaredFields) { 135 | field.setAccessible(true); 136 | if (field.get(result) != null) { 137 | haveValue = true; 138 | break; 139 | } 140 | } 141 | if (!haveValue) { 142 | throw new IllegalArgumentException(String.format("required param %s is not present", key)); 143 | } 144 | return result; 145 | } 146 | } 147 | 148 | /** 149 | * 基本类型解析 150 | */ 151 | private Object parsePrimitive(String parameterTypeName, Object value) { 152 | final String booleanTypeName = "boolean"; 153 | if (booleanTypeName.equals(parameterTypeName)) { 154 | return Boolean.valueOf(value.toString()); 155 | } 156 | final String intTypeName = "int"; 157 | if (intTypeName.equals(parameterTypeName)) { 158 | return Integer.valueOf(value.toString()); 159 | } 160 | final String charTypeName = "char"; 161 | if (charTypeName.equals(parameterTypeName)) { 162 | return value.toString().charAt(0); 163 | } 164 | final String shortTypeName = "short"; 165 | if (shortTypeName.equals(parameterTypeName)) { 166 | return Short.valueOf(value.toString()); 167 | } 168 | final String longTypeName = "long"; 169 | if (longTypeName.equals(parameterTypeName)) { 170 | return Long.valueOf(value.toString()); 171 | } 172 | final String floatTypeName = "float"; 173 | if (floatTypeName.equals(parameterTypeName)) { 174 | return Float.valueOf(value.toString()); 175 | } 176 | final String doubleTypeName = "double"; 177 | if (doubleTypeName.equals(parameterTypeName)) { 178 | return Double.valueOf(value.toString()); 179 | } 180 | final String byteTypeName = "byte"; 181 | if (byteTypeName.equals(parameterTypeName)) { 182 | return Byte.valueOf(value.toString()); 183 | } 184 | return null; 185 | } 186 | 187 | /** 188 | * 基本类型包装类解析 189 | */ 190 | private Object parseBasicTypeWrapper(Class parameterType, Object value) { 191 | if (Number.class.isAssignableFrom(parameterType)) { 192 | Number number = (Number) value; 193 | if (parameterType == Integer.class) { 194 | return number.intValue(); 195 | } else if (parameterType == Short.class) { 196 | return number.shortValue(); 197 | } else if (parameterType == Long.class) { 198 | return number.longValue(); 199 | } else if (parameterType == Float.class) { 200 | return number.floatValue(); 201 | } else if (parameterType == Double.class) { 202 | return number.doubleValue(); 203 | } else if (parameterType == Byte.class) { 204 | return number.byteValue(); 205 | } 206 | } else if (parameterType == Boolean.class) { 207 | return value.toString(); 208 | } else if (parameterType == Character.class) { 209 | return value.toString().charAt(0); 210 | } 211 | return null; 212 | } 213 | 214 | /** 215 | * 判断是否为基本数据类型包装类 216 | */ 217 | private boolean isBasicDataTypes(Class clazz) { 218 | Set classSet = new HashSet<>(); 219 | classSet.add(Integer.class); 220 | classSet.add(Long.class); 221 | classSet.add(Short.class); 222 | classSet.add(Float.class); 223 | classSet.add(Double.class); 224 | classSet.add(Boolean.class); 225 | classSet.add(Byte.class); 226 | classSet.add(Character.class); 227 | return classSet.contains(clazz); 228 | } 229 | 230 | /** 231 | * 获取请求体JSON字符串 232 | */ 233 | private String getRequestBody(NativeWebRequest webRequest) { 234 | HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class); 235 | 236 | // 有就直接获取 237 | String jsonBody = (String) webRequest.getAttribute(JSONBODY_ATTRIBUTE, NativeWebRequest.SCOPE_REQUEST); 238 | // 没有就从请求中读取 239 | if (jsonBody == null) { 240 | try { 241 | jsonBody = IOUtils.toString(servletRequest.getReader()); 242 | webRequest.setAttribute(JSONBODY_ATTRIBUTE, jsonBody, NativeWebRequest.SCOPE_REQUEST); 243 | } catch (IOException e) { 244 | throw new RuntimeException(e); 245 | } 246 | } 247 | return jsonBody; 248 | } 249 | } 250 | --------------------------------------------------------------------------------