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> <!-- 啟動(dòng)SpringMVC的注解功能,完成請(qǐng)求和注解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ù)時(shí),默認(rèn)支持Map方式和對(duì)象方式參數(shù)
@RequestMapping(value = "/[code]/saveUser", method = RequestMethod.POST) @ResponseBody public JsonResult saveUser(@PathVariable("code") Integer code, @RequestBody Map<String, Object> datas,@RequestBody User user) { 。。。 }
如果是一個(gè)參數(shù)時(shí)也需要用個(gè)Map或者對(duì)象處理,使用String會(huì)報(bào)解析錯(cuò)誤,具體看: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ù)(目前只支持接收單個(gè)參數(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的情況,只支持接收單個(gè)參數(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里的值返回(只支持單個(gè)參數(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接收請(qǐng)求參數(shù)分析
第一種情況,什么也不設(shè)置,無參數(shù)傳遞
注解為 @Controller @RequestMapping
可以看到傳遞的為SpringMVC的BindingAwareModelMap類型,SpringMVC中的隱含模型就是這個(gè)類型,其作用域等價(jià)于 request 域,當(dāng)添加Model、ModelMap參數(shù)時(shí),SpringMVC實(shí)際傳入的就是這個(gè)隱含模型;向這個(gè)隱含模型種設(shè)置值后,在返回的頁面中就能通過request域取值。
第二種情況,加個(gè)參數(shù)試試 => .../testmap?test1=2342
結(jié)果類型還是一樣,且參數(shù)不會(huì)被傳入,當(dāng)然使用request肯定能取出來。
第三種情況,給Map參數(shù)添加@RequestParam注解
1、Get請(qǐng)求 =>http://localhost:8080/ssm/v2/testmap?test1=234234
成功傳入了參數(shù),注意這個(gè)Map類型為L(zhǎng)inkedHashMap,而不是隱含模型了
再添加個(gè)Model參數(shù)看看,隱含模型中依然沒有值
所以添加@RequestParam注解后,SpringMVC會(huì)將 Get 請(qǐng)求中封裝進(jìn)對(duì)應(yīng)的參數(shù)中,如果參數(shù)是Map就封裝稱LinkedHashMap而不再傳入隱含模型
2、Post請(qǐng)求, 再測(cè)試測(cè)試Post請(qǐng)求
與Get的結(jié)果一致:參數(shù)無@RequestParam注解時(shí),Map接收隱含模型;添加@RequestParam注解時(shí),Map接收LinkedHashMap;隱含模型中無值。
第四種情況,給Map參數(shù)添加@RequestBody注解,且請(qǐng)求方式為Post
出乎意料的也成功傳入了,與@RequestParam注解結(jié)果類似,也是LinkedHashMap
復(fù)雜點(diǎn)的Json數(shù)據(jù)也能解析接收成功
小結(jié)一下吧
SpringMVC處理請(qǐng)求用Map類型接收參數(shù)時(shí),如果參數(shù)無注解,則會(huì)傳入BindingAwareModelMap類型,等價(jià)于Model、ModelMap參數(shù);
參數(shù)添加@RequestParam注解時(shí),會(huì)將參數(shù)包裝稱LinkedHashMap對(duì)象,參數(shù)的key為Map的key,參數(shù)值為Map的key,支持Get、Post方法(應(yīng)該支持Put、Delete,沒有測(cè),倆方法與Post類似);
添加@RequestBody注解時(shí),接收J(rèn)son類型數(shù)據(jù),也會(huì)包裝成LinkedHashMap對(duì)象,該注解不支持Get請(qǐng)求,Get請(qǐng)求沒有請(qǐng)求體不能傳Json。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
@ConfigurationProperties綁定配置信息至Array、List、Map、Bean的實(shí)現(xiàn)
這篇文章主要介紹了@ConfigurationProperties綁定配置信息至Array、List、Map、Bean的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05Java的Hibernate框架中復(fù)合主鍵映射的創(chuàng)建和使用教程
復(fù)合主鍵映射用起來比普通的增加主鍵字段要復(fù)雜,這里我們就來共同學(xué)習(xí)Java的Hibernate框架中復(fù)合主鍵映射的創(chuàng)建和使用教程,需要的朋友可以參考下2016-07-07Java?將list集合數(shù)據(jù)按照時(shí)間字段排序的方法
這篇文章主要介紹了Java?將list集合數(shù)據(jù)按照時(shí)間字段排序,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03解決idea中maven項(xiàng)目無端顯示404錯(cuò)誤的方法
這篇文章主要介紹了解決idea中maven項(xiàng)目無端顯示404錯(cuò)誤的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12詳解使用MyBatis Generator自動(dòng)創(chuàng)建代碼
這篇文章主要介紹了使用MyBatis Generator自動(dòng)創(chuàng)建代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-12-12java 畫pdf用itext調(diào)整表格寬度、自定義各個(gè)列寬的方法
這篇文章主要介紹了java 畫pdf用itext調(diào)整表格寬度、自定義各個(gè)列寬的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-01-01