【找不到视图问题解决】@RestController 与 @Controller注解的使用区别

avatar
作者
猴君
阅读量:1

一、问题描述

苍穹外卖在菜品分页查询功能实现的过程中,出现了找不到视图的情况

2024-07-12 21:54:20.860 ERROR 22488 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Could not resolve view with name 'admin/dish/page' in servlet with name 'dispatcherServlet'] with root cause  javax.servlet.ServletException: Could not resolve view with name 'admin/dish/page' in servlet with name 'dispatcherServlet' 	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1383) ~[spring-webmvc-5.3.22.jar:5.3.22] 	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1148) ~[spring-webmvc-5.3.22.jar:5.3.22] 	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1087) ~[spring-webmvc-5.3.22.jar:5.3.22] 	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.22.jar:5.3.22] 	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.22.jar:5.3.22] 	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.22.jar:5.3.22] 	at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.65.jar:4.0.FR] 	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.22.jar:5.3.22] 	at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.65.jar:4.0.FR] 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.65.jar:9.0.65] 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.22.jar:5.3.22] 	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.22.jar:5.3.22] 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.65.jar:9.0.65] 	at java.base/java.lang.Thread.run(Thread.java:1623) ~[na:na]  

原来的代码

@Controller @RequestMapping("/admin/dish") @Api(tags="菜品相关接口") @Slf4j public class DishController {      @Autowired     private DishService dishService;      /**      * 分页查询菜品      */      @GetMapping("/page")      @ApiOperation("菜品分页查询")      public Result<PageResult> page( DishPageQueryDTO dishPageQueryDTO){          log.info("菜品分页查询:{}",dishPageQueryDTO);          PageResult pageResult = dishService.pageQuery(dishPageQueryDTO);          return Result.success(pageResult);      } } 

二、解决的措施

将注解@Controller 更换成 @RestController即可。控制器方法返回的请求体,但注解却需要直接解析的是视图,导致Spring MVC视图解析失败

具体原因我们得去思考以下这两个注解到底有什么的不同

@RestController 和 @Controller 是Spring框架中用于处理HTTP请求的注解,它们之间存在一些关键的区别,主要体现在它们对响应体的处理方式上。

@Controller

  • @Controller 注解用于标记在一个类上,表明这个类是一个Spring MVC Controller处理器。
  • 当处理器方法返回字符串时,它通常被解释为视图名(View Name),然后Spring MVC会尝试解析这个视图名并渲染相应的视图。当使用@Controller注解时,通常会结合JSP、Thymeleaf等模板引擎来渲染HTML页面。
  • @Controller注解的处理器方法可以直接返回视图名(String类型),也可以返回ModelAndView对象,后者包含了视图名和模型数据。
  • 如果需要返回JSON或XML等非HTML内容,则需要在处理器方法中使用@ResponseBody注解,或者将方法返回类型设置为ResponseEntityHttpEntity等,来指定响应体。


@RestController

  • @RestController@Controller@ResponseBody的组合注解。该类下的所有方法默认都会应用@ResponseBody注解。
  • 使用@RestController注解的控制器类,其方法默认返回的数据会直接写入HTTP响应体(Response Body)中,通常用于构建restful  Web服务。
  • 常见的返回类型包括ResponseEntityHttpEntityString(直接作为JSON或XML字符串返回)、以及任何可以被自动转换为JSON或XML的对象(Spring MVC通过消息转换器自动完成转换)。
  • 当你需要构建restful API时,@RestController是一个更合适的选择,因为它简化了代码,避免了在每个方法上都添加@ResponseBody注解。

使用@Controller时,通常用于返回视图名以渲染页面,适用于传统的Web应用。

使用@RestController时,通常用于构建restful API,返回的数据会直接作为响应体返回给客户端,适合前后端分离的应用场景。

三、猜测

所以我就在猜测,难道 菜品分页查询 这个功能需要用到 @ResponseBody这个注解么?不然为什么将@Controller 更换成 @RestController问题就迎刃而解了?于是我尝试修改代码如下:

果然解决了

所以@ResponseBody到底有什么用呢,再来探讨一下

@ResponseBody是Spring MVC中用于将控制器方法的返回值绑定到HTTP响应体上

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!