最近需要做些接口服務(wù),服務(wù)協(xié)議定為JSON,為了整合在Spring中,一開(kāi)始確實(shí)費(fèi)了很大的勁,經(jīng)朋友提醒才發(fā)現(xiàn),SpringMVC已經(jīng)強(qiáng)悍到如此地步,佩服!
?
相關(guān)參考:?Spring 注解學(xué)習(xí)手札(一) 構(gòu)建簡(jiǎn)單Web應(yīng)用?Spring 注解學(xué)習(xí)手札(二) 控制層梳理?Spring 注解學(xué)習(xí)手札(三) 表單頁(yè)面處理?Spring 注解學(xué)習(xí)手札(四) 持久層淺析?Spring 注解學(xué)習(xí)手札(五) 業(yè)務(wù)層事務(wù)處理?Spring 注解學(xué)習(xí)手札(六) 測(cè)試?Spring 注解學(xué)習(xí)手札(七) 補(bǔ)遺——@ResponseBody,@RequestBody,@PathVariable?Spring 注解學(xué)習(xí)手札(八) 補(bǔ)遺——@ExceptionHandler? SpringMVC層跟JSon結(jié)合,幾乎不需要做什么配置,代碼實(shí)現(xiàn)也相當(dāng)簡(jiǎn)潔。再也不用為了組裝協(xié)議而勞煩辛苦了!?
一、Spring注解@ResponseBody,@RequestBody和HttpMessageConverter ?
Spring 3.X系列增加了新注解
@ResponseBody ,
@RequestBody ?
@RequestBody ?將HTTP請(qǐng)求正文轉(zhuǎn)換為適合的HttpMessageConverter對(duì)象。@ResponseBody ?將內(nèi)容或?qū)ο笞鳛?HTTP 響應(yīng)正文返回,并調(diào)用適合HttpMessageConverter的Adapter轉(zhuǎn)換對(duì)象,寫(xiě)入輸出流。 HttpMessageConverter 接口,需要開(kāi)啟<mvc:annotation-driven? /> 。?AnnotationMethodHandlerAdapter 將會(huì)初始化7個(gè)轉(zhuǎn)換器,可以通過(guò)調(diào)用AnnotationMethodHandlerAdapter 的getMessageConverts() 方法來(lái)獲取轉(zhuǎn)換器的一個(gè)集合 List<HttpMessageConverter>?
引用 ByteArrayHttpMessageConverter?
StringHttpMessageConverter?
ResourceHttpMessageConverter?
SourceHttpMessageConverter?
XmlAwareFormHttpMessageConverter?
Jaxb2RootElementHttpMessageConverter?
MappingJacksonHttpMessageConverter
可以理解為,只要有對(duì)應(yīng)協(xié)議的解析器,你就可以通過(guò)幾行配置,幾個(gè)注解完成協(xié)議——對(duì)象的轉(zhuǎn)換工作!
?
PS:Spring默認(rèn)的json協(xié)議解析由Jackson完成。?
二、servlet.xml配置 ?
Spring的配置文件,簡(jiǎn)潔到了極致,對(duì)于當(dāng)前這個(gè)需求只需要三行核心配置:? Xml代碼??
<context:component-scan?base-package="org.zlex.json.controller"?/>?? <context:annotation-config?/>?? <mvc:annotation-driven?/>?? 三、pom.xml配置 ? 閑言少敘,先說(shuō)依賴配置,這里以Json+Spring為參考:?pom.xml ?
Xml代碼??
<dependency>?? ????????<groupId>org.springframework</groupId>?? ????????<artifactId>spring-webmvc</artifactId>?? ????????<version>3.1.2.RELEASE</version>?? ????????<type>jar</type>?? ????????<scope>compile</scope>?? ????</dependency>?? ????<dependency>?? ????????<groupId>org.codehaus.jackson</groupId>?? ????????<artifactId>jackson-mapper-asl</artifactId>?? ????????<version>1.9.8</version>?? ????????<type>jar</type>?? ????????<scope>compile</scope>?? ????</dependency>?? ????<dependency>?? ????????<groupId>log4j</groupId>?? ????????<artifactId>log4j</artifactId>?? ????????<version>1.2.17</version>?? ????????<scope>compile</scope>?? ????</dependency>?? 主要需要spring-webmvc 、jackson-mapper-asl 兩個(gè)包,其余依賴包Maven會(huì)幫你完成。至于log4j ,我還是需要看日志嘛。
?
包依賴圖:?
至于版本,看項(xiàng)目需要吧!?
四、代碼實(shí)現(xiàn) ?
域?qū)ο?#xff1a;? Java代碼??
public?class?Person?implements?Serializable?{?? ?? ????private?int?id;?? ????private?String?name;?? ????private?boolean?status;?? ?? ????public?Person()?{?? ???????? ????}?? }?? 這里需要一個(gè)空構(gòu)造,由Spring轉(zhuǎn)換對(duì)象時(shí),進(jìn)行初始化。
?
@ResponseBody,@RequestBody,@PathVariable? 控制器:? Java代碼??
@Controller?? public?class?PersonController?{?? ?? ???? ????@RequestMapping(value?=?"/person/profile/{id}/{name}/{status}",?method?=?RequestMethod.GET)?? ????public?@ResponseBody?? ????Person?porfile(@PathVariable?int?id,?@PathVariable?String?name,?? ????????????@PathVariable?boolean?status)?{?? ????????return?new?Person(id,?name,?status);?? ????}?? ?? ???? ????@RequestMapping(value?=?"/person/login",?method?=?RequestMethod.POST)?? ????public?@ResponseBody?? ????Person?login(@RequestBody?Person?person)?{?? ????????return?person;?? ????}?? }?? 備注:@RequestMapping(value = "/person/profile/{id}/{name}/{status}", method = RequestMethod.GET) 中的{id}/{name}/{status} 與@PathVariable int id, @PathVariable String name,@PathVariable boolean status 一一對(duì)應(yīng),按名匹配。
?這是restful式風(fēng)格。?
如果映射名稱有所不一,可以參考如下方式:? Java代碼??
@RequestMapping(value?=?"/person/profile/{id}",?method?=?RequestMethod.GET)?? public?@ResponseBody?? Person?porfile(@PathVariable("id")?int?uid)?{?? ????return?new?Person(uid,?name,?status);?? }?? GET模式下,這里使用了@PathVariable 綁定輸入?yún)?shù),非常適合Restful風(fēng)格。因?yàn)殡[藏了參數(shù)與路徑的關(guān)系,可以提升網(wǎng)站的安全性,靜態(tài)化頁(yè)面,降低惡意攻擊風(fēng)險(xiǎn)。 POST模式下,使用@RequestBody 綁定請(qǐng)求對(duì)象,Spring會(huì)幫你進(jìn)行協(xié)議轉(zhuǎn)換,將Json、Xml協(xié)議轉(zhuǎn)換成你需要的對(duì)象。 @ResponseBody 可以標(biāo)注任何對(duì)象,由Srping完成對(duì)象——協(xié)議的轉(zhuǎn)換。 做個(gè)頁(yè)面測(cè)試下:?JS ?
Js代碼??
$(document).ready(function()?{?? ????$("#profile").click(function()?{?? ????????profile();?? ????});?? ????$("#login").click(function()?{?? ????????login();?? ????});?? });?? function?profile()?{?? ????var?url?=?'http://localhost:8080/spring-json/json/person/profile/';?? ????var?query?=?$('#id').val()?+?'/'?+?$('#name').val()?+?'/'?? ????????????+?$('#status').val();?? ????url?+=?query;?? ????alert(url);?? ????$.get(url,?function(data)?{?? ????????alert("id:?"?+?data.id?+?"\nname:?"?+?data.name?+?"\nstatus:?"?? ????????????????+?data.status);?? ????});?? }?? function?login()?{?? ????var?mydata?=?'{"name":"'?+?$('#name').val()?+?'","id":"'?? ????????????+?$('#id').val()?+?'","status":"'?+?$('#status').val()?+?'"}';?? ????alert(mydata);?? ????$.ajax({?? ????????type?:?'POST',?? ????????contentType?:?'application/json',?? ????????url?:?'http://localhost:8080/spring-json/json/person/login',?? ????????processData?:?false,?? ????????dataType?:?'json',?? ????????data?:?mydata,?? ????????success?:?function(data)?{?? ????????????alert("id:?"?+?data.id?+?"\nname:?"?+?data.name?+?"\nstatus:?"?? ????????????????????+?data.status);?? ????????},?? ????????error?:?function()?{?? ????????????alert('Err...');?? ????????}?? ????});?? Table ?
Html代碼??
<table>?? ????<tr>?? ????????<td>id</td>?? ????????<td><input?id="id"?value="100"?/></td>?? ????</tr>?? ????<tr>?? ????????<td>name</td>?? ????????<td><input?id="name"?value="snowolf"?/></td>?? ????</tr>?? ????<tr>?? ????????<td>status</td>?? ????????<td><input?id="status"?value="true"?/></td>?? ????</tr>?? ????<tr>?? ????????<td><input?type="button"?id="profile"?value="Profile——GET"?/></td>?? ????????<td><input?type="button"?id="login"?value="Login——POST"?/></td>?? ????</tr>?? </table>?? 四、簡(jiǎn)單測(cè)試 ? Get方式測(cè)試:?
Post方式測(cè)試:?
五、常見(jiàn)錯(cuò)誤?
POST操作時(shí),我用$.post()方式,屢次失敗,一直報(bào)各種異常:? 引用 org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported?
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported?
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
直接用$.post()直接請(qǐng)求會(huì)有點(diǎn)小問(wèn)題,盡管我標(biāo)識(shí)為json 協(xié)議,但實(shí)際上提交的ContentType 還是application/x-www-form-urlencoded 。需要使用$.ajaxSetup()標(biāo)示下ContentType 。?
Js代碼??
function?login()?{?? ????var?mydata?=?'{"name":"'?+?$('#name').val()?+?'","id":"'?? ????????????+?$('#id').val()?+?'","status":"'?+?$('#status').val()?+?'"}';?? ????alert(mydata);?? ????$.ajaxSetup({?? ????????contentType?:?'application/json'?? ????});?? ????$.post('http://localhost:8080/spring-json/json/person/login',?mydata,?? ????????????function(data)?{?? ????????????????alert("id:?"?+?data.id?+?"\nname:?"?+?data.name?? ????????????????????????+?"\nstatus:?"?+?data.status);?? ????????????},?'json');?? };?? 效果是一樣!
?
詳見(jiàn)附件!
總結(jié)
以上是生活随笔 為你收集整理的@ResponseBody,@RequestBody,@PathVariable 的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。