关于java:说说Spring中的-RestController-和-Controller

2次阅读

共计 4771 个字符,预计需要花费 12 分钟才能阅读完成。

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
@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 了。

参考资料

  • 跟开涛学 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 技术翻译组实现,更多国外前沿常识和干货好文,欢送关注公众号:后端面试那些事儿。

正文完
 0