Spring MVC執行流程已經是JAVA面試中老生常談的問題,相信各位小夥伴也是信手拈來。今天咱們來談談另外一個面試中必會必知的問題: @RestController
和@Controller
的區別?html
基於註解的MVC框架簡化了建立RESTful web服務的過程。傳統的Spring MVC控制器和RESTful web服務控制器之間的關鍵區別是HTTP響應體的建立方式。傳統的MVC控制器依賴於視圖技術,基於REST的web服務控制器僅返回對象,而對象數據直接以JSON/XML的形式寫入HTTP響應。java
支持如下方式來建立 REST 資源:web
在傳統的工做流中,ModelAndView對象是從控制器轉發到客戶機的,經過在方法上加@ResponseBody,Spring直接從控制器返回數據,而不須要查找視圖。從4.0版本開始,隨着@RestController註釋的引入,這個過程獲得了進一步簡化。下面將解釋每種方法。面試
@Controller用於標記在一個類上,使用它標記的類就是一個Spring MVC Controller對象,分發處理器會掃描使用該註解的類的方法,並檢測該方法是否使用了@RequestMapping註解。spring
@ResponseBody註解用於將Controller的方法返回的對象,經過適當的HttpMessageConverter轉換爲指定格式後,寫入到Response對象的body數據區,一般用來返回 JSON 或者 XML 數據,返回 JSON 數據的狀況比較多。json
Spring有一個在後臺註冊的HttpMessageConverters列表。HTTPMessageConverter的職責是根據預約義的mime類型將請求主體轉換爲特定的類,而後再轉換回響應主體。每當發出的請求點擊@ResponseBody時,Spring循環遍歷全部已註冊的HttpMessageConverters,尋找第一個符合給定mime類型和類的請求,而後將其用於實際的轉換。
建立實體類:後端
package com.laocaicai.week1.entity; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "Dog") public class DogEntity { String name; String breed; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getBreed() { return breed; } public void setBreed(String breed) { this.breed = breed; } public DogEntity() { } }
建立Controller:api
package com.laocaicai.week1.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import com.laocaicai.week1.entity.DogEntity; @Controller @RequestMapping("dogs") public class DogController { DogEntity dog = new DogEntity(); @RequestMapping(value = "/{name}", method = RequestMethod.GET, produces = "application/json") public @ResponseBody DogEntity getDogInJSON(@PathVariable String name) { dog.setName(name); dog.setBreed("中國細犬"); return dog; } @RequestMapping(value = "/{name}.xml", method = RequestMethod.GET, produces = "application/xml") public @ResponseBody DogEntity getDogInXML(@PathVariable String name) { dog.setName(name); dog.setBreed("中國細犬"); return dog; } }
在Spring配置文件中添加
和
標籤,前者用於激活註釋並掃描包以查找和註冊應用程序上下文中的bean,後者增長了對讀取和寫入JSON/XML的支持(對於返回JSON格式數據,須要導入jackson-databind依賴;對於XML格式,須要導入jaxb-api-osgi依賴)
使用URL:http://localhost:8687/week_1/dogs/哮天犬
,輸出JSON:服務器
使用URL:http://localhost:8687/week_1/dogs/哮天犬.xml
,輸出XML:網絡
Spring 4.0引入了@RestController
,@RestController
註解是一種快捷方式,它所聲明的控制器在返回響應時,就如同使用了@ResponseBody
註解同樣。它會告訴Spring 將返回類型序列化爲合適的格式,默認狀況下爲JSON 格式。經過用@RestController
註釋控制器類,您再也不須要向全部請求映射方法添加@ResponseBody
。
package org.springframework.web.bind.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.stereotype.Controller; @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Controller @ResponseBody public @interface RestController { String value() default ""; }
要在咱們的示例中使用@RestController
,咱們所須要作的就是將@Controller
修改成@RestController
並從每一個方法中刪除@ResponseBody
。生成的類應該以下所示
package com.laocaicai.week1.controller; import com.laocaicai.week1.entity.DogEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("2dogs") public class DogRestController { DogEntity dog = new DogEntity(); @RequestMapping(value = "/{name}", method = RequestMethod.GET, produces = "application/json") public DogEntity getDogInJSON(@PathVariable String name) { dog.setName(name); dog.setBreed("中國細犬"); return dog; } @RequestMapping(value = "/{name}.xml", method = RequestMethod.GET, produces = "application/xml") public DogEntity getgetDogInXMLInXML(@PathVariable String name) { dog.setName(name); dog.setBreed("中國細犬"); return dog; } }
注意,咱們再也不須要將
@ResponseBody
添加到請求映射方法中,在進行更改以後,再次在服務器上運行應用程序會產生與以前相同的輸出。
經過本篇的介紹,小夥伴們會發現使用@RestController
很是簡單,是從Spring v4.0開始建立MVC RESTful web服務的首選方法。@RestController
(Spring4+)至關於@Controller
+ @ResponseBody
,返回json或者xml格式數據;若是在控制器類上使用@RestController
來代替@Controller
的話,Spring將會爲該控制器的全部處理方法應用消息轉換功能,咱們沒必要爲每一個方法都添加@ResponseBody
了。
參考資料:
本文做者:Srivatsan Sundararajan, 翻譯:laocaicaicai
原文連接: https://dzone.com/articles/sp...
譯文首發: http://blog.didispace.com/tr-...
本文有spring4all技術翻譯組完成,更多國外前沿知識和乾貨好文,歡迎關注公衆號:後端面試那些事兒。