Spring MVC执行流程已是JAVA面试中陈词滥调的问题,置信各位小伙伴也是信手拈来。明天咱们来谈谈另一个面试中必会必知的问题: @RestController
和@Controller
的区别?
- Spring MVC中的REST实现
- @Controller + @ResponseBody注解
- @RestController注解
Spring MVC 与 REST
基于注解的MVC框架简化了创立RESTful web服务的过程。传统的Spring MVC控制器和RESTful web服务控制器之间的要害区别是HTTP响应体的创立形式。传统的MVC控制器依赖于视图技术,基于REST的web服务控制器仅返回对象,而对象数据间接以JSON/XML的模式写入HTTP响应。
Spring MVC对 REST 的反对
反对以下形式来创立 REST 资源:
- 控制器能够解决所有的HTTP办法,蕴含四个次要的REST办法:GET、PUT、DELETE以及POST;
- 音讯转换器(Message conversion)将资源的JAVA表述模式转换为发送给客户端的表述模式;
- 借助于 SpringMVC 的一系列注解,构建 REST API;
- 借助 RestTemplate,Spring利用可能不便地应用REST资源;
典型的Spring MVC工作流
在传统的工作流中,ModelAndView对象是从控制器转发到客户机的,通过在办法上加@ResponseBody,Spring间接从控制器返回数据,而不须要查找视图。从4.0版本开始,随着@RestController正文的引入,这个过程失去了进一步简化。上面将解释每种办法。
应用@Controller + @ResponseBody注解
@Controller用于标记在一个类上,应用它标记的类就是一个Spring MVC Controller对象,散发处理器会扫描应用该注解的类的办法,并检测该办法是否应用了@RequestMapping注解。
@ResponseBody注解用于将Controller的办法返回的对象,通过适当的HttpMessageConverter转换为指定格局后,写入到Response对象的body数据区,通常用来返回 JSON 或者 XML 数据,返回 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:
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:
应用@RestController注解
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@ResponseBodypublic @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
了。
参考资料:
- 跟开涛学SpringMVC
- SpringMVC中Controller的@ResponseBody注解剖析
- 【SpringBoot】 http申请注解之@RestController
- @RestController注解初步了解
- Spring Framework: @RestController vs. @Controller
本文作者:Srivatsan Sundararajan, 翻译:laocaicaicai
原文链接:https://dzone.com/articles/sp...
译文首发:http://blog.didispace.com/tr-...
本文有spring4all技术翻译组实现,更多国外前沿常识和干货好文,欢送关注公众号:后端面试那些事儿。