@Controller VS @RestController

遇到的問題:Spring Boot應用中添加了一個Controller用於測試,如:html

@Controller
@RequestMapping("/test")
public class TestController {

    @GetMapping("/getString")
    public String testGetString() {
        return "hello world";
    }

}

使用Postman調用/test/getString,結果以下:java

代碼中將@Controller換成@RestController, 則返回成功!spring

 

理解:二者的定義分別爲:app

@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標籤,參考spring-boot

@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的名稱。.net

@Controller
@RequestMapping("/test")
public class TestController {

    @GetMapping("/getTemplate")
    public String getTemplate() {
        return "test";
    }
}

template是View的基礎,能夠將View理解成template+Model,因此爲了返回正確的ModelAndView,在pom.xml中引入:3d

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

在resources/templates文件夾下添加test.html:code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Test</title>
</head>
<body>
<h1>這是一個測試頁面</h1>

</body>
</html>

使用Postman調用/test/getTemplate,返回頁面:component

 

結論: @RestController適合用於接口編寫,@Controller合適MVC的處理,若是要在Controller中編寫接口,只須要在具體方法前添加@ResponseBody。

相關文章
相關標籤/搜索