最近需要做些接口服務,服務協議定為JSON,為了整合在Spring中,一開始確實費了很大的勁,經朋友提醒才發現,SpringMVC已經強悍到如此地步,佩服!
?
相關參考:?Spring 注解學習手札(一) 構建簡單Web應用?Spring 注解學習手札(二) 控制層梳理?Spring 注解學習手札(三) 表單頁面處理?Spring 注解學習手札(四) 持久層淺析?Spring 注解學習手札(五) 業務層事務處理?Spring 注解學習手札(六) 測試?Spring 注解學習手札(七) 補遺——@ResponseBody,@RequestBody,@PathVariable?Spring 注解學習手札(八) 補遺——@ExceptionHandler? SpringMVC層跟JSon結合,幾乎不需要做什么配置,代碼實現也相當簡潔。再也不用為了組裝協議而勞煩辛苦了!?
一、Spring注解@ResponseBody,@RequestBody和HttpMessageConverter ?
Spring 3.X系列增加了新注解
@ResponseBody ,
@RequestBody ?
@RequestBody ?將HTTP請求正文轉換為適合的HttpMessageConverter對象。@ResponseBody ?將內容或對象作為 HTTP 響應正文返回,并調用適合HttpMessageConverter的Adapter轉換對象,寫入輸出流。 HttpMessageConverter 接口,需要開啟<mvc:annotation-driven? /> 。?AnnotationMethodHandlerAdapter 將會初始化7個轉換器,可以通過調用AnnotationMethodHandlerAdapter 的getMessageConverts() 方法來獲取轉換器的一個集合 List<HttpMessageConverter>?
引用 ByteArrayHttpMessageConverter?
StringHttpMessageConverter?
ResourceHttpMessageConverter?
SourceHttpMessageConverter?
XmlAwareFormHttpMessageConverter?
Jaxb2RootElementHttpMessageConverter?
MappingJacksonHttpMessageConverter
可以理解為,只要有對應協議的解析器,你就可以通過幾行配置,幾個注解完成協議——對象的轉換工作!
?
PS:Spring默認的json協議解析由Jackson完成。?
二、servlet.xml配置 ?
Spring的配置文件,簡潔到了極致,對于當前這個需求只需要三行核心配置:? Xml代碼??
<context:component-scan?base-package="org.zlex.json.controller"?/>?? <context:annotation-config?/>?? <mvc:annotation-driven?/>?? 三、pom.xml配置 ? 閑言少敘,先說依賴配置,這里以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 兩個包,其余依賴包Maven會幫你完成。至于log4j ,我還是需要看日志嘛。
?
包依賴圖:?
至于版本,看項目需要吧!?
四、代碼實現 ?
域對象:? Java代碼??
public?class?Person?implements?Serializable?{?? ?? ????private?int?id;?? ????private?String?name;?? ????private?boolean?status;?? ?? ????public?Person()?{?? ???????? ????}?? }?? 這里需要一個空構造,由Spring轉換對象時,進行初始化。
?
@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 一一對應,按名匹配。
?這是restful式風格。?
如果映射名稱有所不一,可以參考如下方式:? 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 綁定輸入參數,非常適合Restful風格。因為隱藏了參數與路徑的關系,可以提升網站的安全性,靜態化頁面,降低惡意攻擊風險。 POST模式下,使用@RequestBody 綁定請求對象,Spring會幫你進行協議轉換,將Json、Xml協議轉換成你需要的對象。 @ResponseBody 可以標注任何對象,由Srping完成對象——協議的轉換。 做個頁面測試下:?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>?? 四、簡單測試 ? Get方式測試:?
Post方式測試:?
五、常見錯誤?
POST操作時,我用$.post()方式,屢次失敗,一直報各種異常:? 引用 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()直接請求會有點小問題,盡管我標識為json 協議,但實際上提交的ContentType 還是application/x-www-form-urlencoded 。需要使用$.ajaxSetup()標示下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');?? };?? 效果是一樣!
?
詳見附件!
總結
以上是生活随笔 為你收集整理的@ResponseBody,@RequestBody,@PathVariable 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。