遇到的问题:Spring Boot应用中添加了一个Controller用于测试,如:
@Controller
@RequestMapping("/test")
public class TestController {
@GetMapping("/getString")
public String testGetString() {
return "hello world";
}
}
使用Postman调用/test/getString,结果如下:
代码中将@Controller换成@RestController, 则返回成功!
理解:两者的定义分别为:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
String value() default "";
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
* @since 4.0.1
*/
String value() default "";
}
可以看到@RestController是在@Controller的基础上增加一个@ResponseBody标签,参考
@Controller是个MVC的概念,它的方法可以处理request,方法和request之间通过@RequestMapping(或@GetMapping, @PostMapping等)映射,方法本身不返回,返回内容写在HttpServletResponse中:
@Controller
@RequestMapping("/test")
public class TestController {
@GetMapping("/getString1")
public void getString1(HttpServletRequest request, HttpServletResponse response)throws Exception{
response.getWriter().write("hello world");
}
}
当然,方法也可以返回值,根据MVC模型,@Controller的方法应该返回ModelAndView, 如果返回类型是String的话,该值应该是一个template的名称。
@Controller
@RequestMapping("/test")
public class TestController {
@GetMapping("/getTemplate")
public String getTemplate() {
return "test";
}
}
template是View的基础,可以将View理解成template+Model,所以为了返回正确的ModelAndView,在pom.xml中引入:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
在resources/templates文件夹下添加test.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Test</title>
</head>
<body>
<h1>这是一个测试页面</h1>
</body>
</html>
使用Postman调用/test/getTemplate,返回页面:
结论: @RestController适合用于接口编写,@Controller合适MVC的处理,如果要在Controller中编写接口,只需要在具体方法前添加@ResponseBody。