springmvc @RequestBody String類型參數(shù)的使用
springmvc @RequestBody String類型參數(shù)
通過如下配置:
<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轉(zhuǎn)換器 -->
</list>
</property>
</bean>
在spring mvc的Controller層使用@RequestBody接收Content-Type為application/json的數(shù)據(jù)時,默認(rèn)支持Map方式和對象方式參數(shù)
@RequestMapping(value = "/[code]/saveUser", method = RequestMethod.POST)
@ResponseBody
public JsonResult saveUser(@PathVariable("code") Integer code, @RequestBody Map<String, Object> datas,@RequestBody User user) {
。。。
}
如果是一個參數(shù)時也需要用個Map或者對象處理,使用String會報(bào)解析錯誤,具體看: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參數(shù)(目前只支持接收單個參數(shù))
重寫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的情況,只支持接收單個參數(shù)的情況
* 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);
}
/**
* 通過返回參數(shù)類型決定是否處理參數(shù),如果是String類型的參數(shù),將解析后的HashMap里的值返回(只支持單個參數(shù))
*
* @param type 返回參數(shù)類型
* @param param 參數(shù)值
* @return 實(shí)際參數(shù)值
*/
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;
}
/**
* 獲取解析參數(shù)用的Type
*
* @param type 參數(shù)類型
* @return
*/
private Type getType(Type type) {
Type deseriClazz;
if (type == String.class) {
//jackson不支持String默認(rèn)用LinkedHashMap
deseriClazz = LinkedHashMap.class;
} else {
deseriClazz = type;
}
return deseriClazz;
}
/**
* 獲取解析參數(shù)用的Type
* @param clazz 參數(shù)類型
* @return
*/
private Class<?> getClazz(Class<?> clazz) {
Class<?> deseriClazz;
if (clazz == String.class) {
//jackson不支持String默認(rèn)用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接收請求參數(shù)分析
第一種情況,什么也不設(shè)置,無參數(shù)傳遞
注解為 @Controller @RequestMapping

可以看到傳遞的為SpringMVC的BindingAwareModelMap類型,SpringMVC中的隱含模型就是這個類型,其作用域等價(jià)于 request 域,當(dāng)添加Model、ModelMap參數(shù)時,SpringMVC實(shí)際傳入的就是這個隱含模型;向這個隱含模型種設(shè)置值后,在返回的頁面中就能通過request域取值。
第二種情況,加個參數(shù)試試 => .../testmap?test1=2342
結(jié)果類型還是一樣,且參數(shù)不會被傳入,當(dāng)然使用request肯定能取出來。

第三種情況,給Map參數(shù)添加@RequestParam注解
1、Get請求 =>http://localhost:8080/ssm/v2/testmap?test1=234234
成功傳入了參數(shù),注意這個Map類型為LinkedHashMap,而不是隱含模型了

再添加個Model參數(shù)看看,隱含模型中依然沒有值
所以添加@RequestParam注解后,SpringMVC會將 Get 請求中封裝進(jìn)對應(yīng)的參數(shù)中,如果參數(shù)是Map就封裝稱LinkedHashMap而不再傳入隱含模型

2、Post請求, 再測試測試Post請求
與Get的結(jié)果一致:參數(shù)無@RequestParam注解時,Map接收隱含模型;添加@RequestParam注解時,Map接收LinkedHashMap;隱含模型中無值。

第四種情況,給Map參數(shù)添加@RequestBody注解,且請求方式為Post
出乎意料的也成功傳入了,與@RequestParam注解結(jié)果類似,也是LinkedHashMap


復(fù)雜點(diǎn)的Json數(shù)據(jù)也能解析接收成功


小結(jié)一下吧
SpringMVC處理請求用Map類型接收參數(shù)時,如果參數(shù)無注解,則會傳入BindingAwareModelMap類型,等價(jià)于Model、ModelMap參數(shù);
參數(shù)添加@RequestParam注解時,會將參數(shù)包裝稱LinkedHashMap對象,參數(shù)的key為Map的key,參數(shù)值為Map的key,支持Get、Post方法(應(yīng)該支持Put、Delete,沒有測,倆方法與Post類似);
添加@RequestBody注解時,接收J(rèn)son類型數(shù)據(jù),也會包裝成LinkedHashMap對象,該注解不支持Get請求,Get請求沒有請求體不能傳Json。
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
- 解讀@RequestBody的正確使用方法
- 快速解決SpringMVC @RequestBody 用map接收請求參數(shù)的問題
- 詳解SpringMVC @RequestBody接收J(rèn)son對象字符串
- @ResponseBody 和 @RequestBody 注解的區(qū)別
- SpringMVC restful 注解之@RequestBody進(jìn)行json與object轉(zhuǎn)換
- 關(guān)于Springboot | @RequestBody 接收到的參數(shù)對象屬性為空的問題
- Springboot攔截器如何獲取@RequestBody參數(shù)
- 親測SpringBoot參數(shù)傳遞及@RequestBody注解---踩過的坑及解決
- springMvc注解之@ResponseBody和@RequestBody詳解
- SpringBoot中@RequestBody的偽表單提交場景
相關(guān)文章
一文帶你掌握J(rèn)ava?ReentrantLock加解鎖原理
這篇文章將為大家詳細(xì)介紹一下Java中ReentrantLock?加鎖和釋放鎖的原理,以及和?Synchronized?的對比。文中的示例代碼講解詳細(xì),希望對大家有所幫助2022-12-12
使用java批量寫入環(huán)境變量的實(shí)現(xiàn)
本文主要介紹了使用java批量寫入環(huán)境變量,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-03-03
Java實(shí)現(xiàn)注冊登錄跳轉(zhuǎn)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)注冊登錄跳轉(zhuǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
Spring boot + mybatis + Vue.js 
這篇文章主要介紹了Spring boot + mybatis + Vue.js + ElementUI 實(shí)現(xiàn)數(shù)據(jù)的增刪改查實(shí)例代碼(二),非常不錯,具有參考借鑒價(jià)值,需要的朋友可以參考下2017-05-05
SpringBoot中關(guān)于static和templates的注意事項(xiàng)以及webjars的配置
今天小編就為大家分享一篇關(guān)于SpringBoot中關(guān)于static和templates的注意事項(xiàng)以及webjars的配置,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01
論java如何通過反射獲得方法真實(shí)參數(shù)名及擴(kuò)展研究
這篇文章主要為大家介紹了java如何通過反射獲得方法的真實(shí)參數(shù)名以及擴(kuò)展研究,有需要的朋友可以借鑒參考下,希望能夠有所幫助祝大家多多進(jìn)步早日升職加薪2022-01-01

