虽然互联网上的每个页面都说@RestController是@Component的规范。但我不知道它是否必须与DispatcherServlet相关。但是当我尝试通过在@RestController和@Component之间切换来尝试以下代码时,我看不到相同的行为:
首先,我尝试使用@RestController:
@RestComponent
public class TestController {
@RequestMapping(value="/testController", method=RequestMethod.POST,consumes=MediaType.APPLICATION_JSON_VALUE)
public void testController() {
System.out.println("Hello");
}
}
我在控制台中得到以下输出:
你好
其次,我尝试使用@Component + @ResponseBody:
@Component
@ResponseBody
public class TestController {
@RequestMapping(value="/testController", method=RequestMethod.POST,consumes=MediaType.APPLICATION_JSON_VALUE)
public void testController() {
System.out.println("Hello");
}
}
我在邮递员上遇到错误:
{
"timestamp": 1570998345860,
"status": 405,
"error": "Method Not Allowed",
"message": "Request method 'POST' not supported",
"path": "/testController"
}
如果两个注释都相同,那么输出为何不同?
下面是@RestController和@Controller的源代码,它显示了@RestController和@Controller都是@Component的规范:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
}
也许它必须与DispatcherServlet有关。 Dispatcher Servlet可能仅检查@RestController注释类中的URL。
最佳答案
仅仅因为@RestController
是@Component
并不意味着您可以通过切换到更广泛的@Component
来实现相同的功能。即使添加了@ResponseBody
,您也无法实现等效的功能(不支持通过请求方法POST
表示)。
用@Component
替换@Controller
,因为@RestController
具有与@Controller
+ @ResponseBody
完全相同的功能。您还可以在@RestController
的元注释中看到此内容,您会看到它用@Controller
进行元注释,而不仅仅是@Component
。反过来,@Controller
用@Component
进行元注释。