springmvc @RequestBody String类型参数的使用

作者:zoyation 时间:2023-03-08 09:30:05 

springmvc @RequestBody String类型参数

通过如下配置:


  <bean id="mappingJacksonHttpMessageConverter"
         class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
       <property name="supportedMediaTypes">
           <list>
               <value>text/html;charset=UTF-8</value>
               <value>application/json;charset=UTF-8</value>
           </list>
       </property>
   </bean>
   <!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 -->
   <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
   <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
       <property name="messageConverters">
           <list>
               <ref bean="mappingJacksonHttpMessageConverter"/>
               <!-- JSON转换器 -->
           </list>
       </property>
   </bean>

在spring mvc的Controller层使用@RequestBody接收Content-Type为application/json的数据时,默认支持Map方式和对象方式参数


@RequestMapping(value = "/[code]/saveUser", method = RequestMethod.POST)
   @ResponseBody
   public JsonResult saveUser(@PathVariable("code") Integer code, @RequestBody Map<String, Object> datas,@RequestBody User user) {
   。。。
   }

如果是一个参数时也需要用个Map或者对象处理,使用String会报解析错误,具体看:AbstractJackson2HttpMessageConverter的方法read(Type type, Class


@Override
   public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage)
           throws IOException, HttpMessageNotReadableException {
       JavaType javaType = getJavaType(type, contextClass);
       return readJavaType(javaType, inputMessage);
   }
   private Object readJavaType(JavaType javaType, HttpInputMessage inputMessage) {
       try {
           return this.objectMapper.readValue(inputMessage.getBody(), javaType);
       }
       catch (IOException ex) {
           throw new HttpMessageNotReadableException("Could not read JSON: " + ex.getMessage(), ex);
       }
   }

为了让@RequestBody支持String参数(目前只支持接收单个参数)

重写org.springframework.http.converter.json.MappingJackson2HttpMessageConverter类


package com.test.converter.json
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.LinkedHashMap;
/**
* 处理@RequestBody注解为String的情况,只支持接收单个参数的情况
* Created by test
* Date:2017/1/4
* Time:17:33
*/
public class CustomerMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
   @Override
   protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
       Class<?> deseriClazz = getClazz(clazz);
       Object param = super.readInternal(deseriClazz, inputMessage);
       return getTrueObject(clazz, param);
   }
   @Override
   public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage)
           throws IOException, HttpMessageNotReadableException {
       Type deseriType = getType(type);
       Object param = super.read(deseriType, contextClass, inputMessage);
       return getTrueObject(type, param);
   }
   /**
    * 通过返回参数类型决定是否处理参数,如果是String类型的参数,将解析后的HashMap里的值返回(只支持单个参数)
    *
    * @param type  返回参数类型
    * @param param 参数值
    * @return 实际参数值
    */
   private Object getTrueObject(Type type, Object param) {
       if (type == String.class) {
           Object backParam = null;
           if (param != null && param instanceof LinkedHashMap) {
               LinkedHashMap paramMap = (LinkedHashMap) param;
               if (paramMap.size() == 1) {
                   backParam = paramMap.get(paramMap.keySet().iterator().next());
               }
           }
           param = backParam;
       }
       return param;
   }
   /**
    * 获取解析参数用的Type
    *
    * @param type 参数类型
    * @return
    */
   private Type getType(Type type) {
       Type deseriClazz;
       if (type == String.class) {
           //jackson不支持String默认用LinkedHashMap
           deseriClazz = LinkedHashMap.class;
       } else {
           deseriClazz = type;
       }
       return deseriClazz;
   }
   /**
    * 获取解析参数用的Type
    * @param clazz 参数类型
    * @return
    */
   private Class<?> getClazz(Class<?> clazz) {
       Class<?> deseriClazz;
       if (clazz == String.class) {
           //jackson不支持String默认用LinkedHashMap
           deseriClazz = LinkedHashMap.class;
       } else {
           deseriClazz = clazz;
       }
       return deseriClazz;
   }
}

spring mvc xml配置文件修改:


<bean id="mappingJacksonHttpMessageConverter"
         class="com.test.converter.json.CustomerMappingJackson2HttpMessageConverter">
       <property name="supportedMediaTypes">
           <list>
               <value>text/html;charset=UTF-8</value>
               <value>application/json;charset=UTF-8</value>
           </list>
       </property>
   </bean>

Controller层:


@RequestMapping(value = "/delUser", method = RequestMethod.POST)
   @ResponseBody
   public JsonResult delUser(@RequestBody String id) {
   。。。
   }

springmvc用Map接收请求参数分析

第一种情况,什么也不设置,无参数传递

注解为 @Controller @RequestMapping

springmvc @RequestBody String类型参数的使用

可以看到传递的为SpringMVC的BindingAwareModelMap类型,SpringMVC中的隐含模型就是这个类型,其作用域等价于 request 域,当添加Model、ModelMap参数时,SpringMVC实际传入的就是这个隐含模型;向这个隐含模型种设置值后,在返回的页面中就能通过request域取值。

第二种情况,加个参数试试 => .../testmap?test1=2342

结果类型还是一样,且参数不会被传入,当然使用request肯定能取出来。

springmvc @RequestBody String类型参数的使用

第三种情况,给Map参数添加@RequestParam注解

1、Get请求 =>http://localhost:8080/ssm/v2/testmap?test1=234234

成功传入了参数,注意这个Map类型为LinkedHashMap,而不是隐含模型了

springmvc @RequestBody String类型参数的使用

再添加个Model参数看看,隐含模型中依然没有值

所以添加@RequestParam注解后,SpringMVC会将 Get 请求中封装进对应的参数中,如果参数是Map就封装称LinkedHashMap而不再传入隐含模型

springmvc @RequestBody String类型参数的使用

2、Post请求, 再测试测试Post请求

与Get的结果一致:参数无@RequestParam注解时,Map接收隐含模型;添加@RequestParam注解时,Map接收LinkedHashMap;隐含模型中无值。

springmvc @RequestBody String类型参数的使用

第四种情况,给Map参数添加@RequestBody注解,且请求方式为Post

出乎意料的也成功传入了,与@RequestParam注解结果类似,也是LinkedHashMap

springmvc @RequestBody String类型参数的使用

springmvc @RequestBody String类型参数的使用

复杂点的Json数据也能解析接收成功

springmvc @RequestBody String类型参数的使用

springmvc @RequestBody String类型参数的使用

小结一下吧

SpringMVC处理请求用Map类型接收参数时,如果参数无注解,则会传入BindingAwareModelMap类型,等价于Model、ModelMap参数;

参数添加@RequestParam注解时,会将参数包装称LinkedHashMap对象,参数的key为Map的key,参数值为Map的key,支持Get、Post方法(应该支持Put、Delete,没有测,俩方法与Post类似);

添加@RequestBody注解时,接收Json类型数据,也会包装成LinkedHashMap对象,该注解不支持Get请求,Get请求没有请求体不能传Json。

来源:https://blog.csdn.net/yangxingzou/article/details/54092578

标签:springmvc,@RequestBody,String
0
投稿

猜你喜欢

  • Android中EditText显示明文与密码的两种方式

    2021-09-13 07:35:39
  • Android View与Compose互相调用实例探究

    2021-06-11 09:07:29
  • Spring Boot2.3 新特性分层JAR的使用

    2021-08-03 12:55:50
  • Android UI设计系列之ImageView实现ProgressBar旋转效果(1)

    2021-06-07 11:08:21
  • Android中TelephonyManager类的方法实例分析

    2021-07-29 10:35:28
  • SpringBoot Data JPA 关联表查询的方法

    2021-08-08 13:59:23
  • Android中ImageView的使用方法

    2023-11-19 02:03:41
  • Android日期显示和日期选择库

    2021-09-04 10:54:17
  • Mybatis源码解析之事务管理

    2023-01-14 10:59:34
  • 详解mybatis-plus配置找不到Mapper接口路径的坑

    2022-03-12 10:37:45
  • Android Handler消息派发机制源码分析

    2023-12-18 17:32:55
  • java编写的文件管理器代码分享

    2023-11-20 13:28:52
  • Android编程判断当前应用是否在后台运行的方法示例

    2021-10-29 12:09:36
  • Java语言一元运算符实例解析

    2023-01-14 15:31:22
  • C#实现把图片转换成二进制以及把二进制转换成图片的方法示例

    2023-08-10 15:25:51
  • java去除字符串中的空格、回车、换行符、制表符的小例子

    2022-04-13 12:33:44
  • Android的OkHttp包中的HTTP拦截器Interceptor用法示例

    2022-01-31 06:31:25
  • Spring的@Validation和javax包下的@Valid区别以及自定义校验注解

    2021-06-20 04:06:35
  • C++构造函数初始化列表的实现详解

    2022-05-21 09:54:10
  • Java文件读写IO/NIO及性能比较详细代码及总结

    2021-11-28 12:56:30
  • asp之家 软件编程 m.aspxhome.com