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的BindingAwareModelMap类型,SpringMVC中的隐含模型就是这个类型,其作用域等价于 request 域,当添加Model、ModelMap参数时,SpringMVC实际传入的就是这个隐含模型;向这个隐含模型种设置值后,在返回的页面中就能通过request域取值。
第二种情况,加个参数试试 => .../testmap?test1=2342
结果类型还是一样,且参数不会被传入,当然使用request肯定能取出来。
第三种情况,给Map参数添加@RequestParam注解
1、Get请求 =>http://localhost:8080/ssm/v2/testmap?test1=234234
成功传入了参数,注意这个Map类型为LinkedHashMap,而不是隐含模型了
再添加个Model参数看看,隐含模型中依然没有值
所以添加@RequestParam注解后,SpringMVC会将 Get 请求中封装进对应的参数中,如果参数是Map就封装称LinkedHashMap而不再传入隐含模型
2、Post请求, 再测试测试Post请求
与Get的结果一致:参数无@RequestParam注解时,Map接收隐含模型;添加@RequestParam注解时,Map接收LinkedHashMap;隐含模型中无值。
第四种情况,给Map参数添加@RequestBody注解,且请求方式为Post
出乎意料的也成功传入了,与@RequestParam注解结果类似,也是LinkedHashMap
复杂点的Json数据也能解析接收成功
小结一下吧
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


猜你喜欢
- 正则: “.”和"\""."点儿,在正则表达式中表示任意一个字符。"\"在正则表
- 前言记录下SpringBoot修改yml配置文件后无需重启服务的方式(打包后生效),效果如下:具体实现实现代码pom.xml<depe
- 前言小伙伴们在使用C#开发时,可能需要将一些信息写入到txt,这里就给大家介绍几种常用的方法。方法:1.将由字符串组成的数组写入txt此种方
- java 中cookie的详解Java对cookie的操作比较简单,主要介绍下建立cookie和读取cookie,以及如何设定cookie的
- Android应用中能很方便的完成这些功能,很多的应用中都有“分享”功能?如何分享呢?下面给大家说说看。最近有人问到Android分享功能用
- 需求分析需求一:图片列表查询,从后台返回数据,将数据展示在页面上需求二:新增图片,将新增图书的数据传递到后台,并在控制台打印说明:此次案例的
- 关于静态类型检查和动态类型检查的解释:静态类型检查:基于程序的源代码来验证类型安全的过程;动态类型检查:在程序运行期间验证类型安全的过程;J
- Apache Thrift 是 Facebook 实现的一种高效的、支持多种编程语言的远程服务调用的框架。和其它RPC框架相比,它主要具有如
- package com.anno;import java.lang.annotation.Retention; import j
- Android的Camera相关应用开发中,有一个必须搞清楚的知识点,就是Camera的预览方向和拍照方向图像的Sensor方向:手机Cam
- android Notification实例详解1.使用Builder模式来创建2.必须要设置一个smallIcon,还可以设置setTic
- C# 的析构以及垃圾回收实例分析看书时,自己写的例子代码,了解到几个知识点,记载下来。同时发现自己手写代码的能力比较弱,还是得多写一下。us
- 线程启动:1.start() 和 run()的区别说明start() : 它的作用是启动一个新线程,新线程会执行相应的run()方法。sta
- 版本对照各版本的文档说明:https://docs.spring.io/spring-data/elasticsearch/docs/1、在
- 本文实例为大家分享了Struts2框架拦截 器实例的示例代码,供大家参考,具体内容如下在看拦截 器的小例子的前我们先来看看sturts2的原
- 有时候数据库文档需要整理,可是只能手动的复制粘贴,心中一万只草泥马奔腾而过。。。screw简洁好用的数据库表结构文档生成工具。1. 创建项目
- 封装在如何理解面向对象这篇文章中,提到所谓的封装就是“功能都给你做好了,你不必去理解它是怎么写出来的,直接使用即可。”。但你得清楚一点,那就
- 今天给大家介绍一下如何实现一款简约时尚的安卓登陆界面。大家先看一下效果图当用户输入时动态出现删除按钮 现在先罗列一下技术点:1.如何使用圆角
- 本文实例讲述了Android开发使用URLConnection进行网络编程。分享给大家供大家参考,具体如下:URL的openConnecti
- UI编程通常都会伴随事件处理,Android也不例外,它提供了两种方式的事件处理:基于回调的事件处理和基于 * 的事件处理。对于基于 * 的