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

一、问题描述

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

java 复制代码
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]

原来的代码

java 复制代码
@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注解,或者将方法返回类型设置为ResponseEntity、HttpEntity等,来指定响应体。

@RestController

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

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

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

三、猜测

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

果然解决了

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

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

相关推荐
vx-程序开发5 小时前
【计算机毕设】51300童装超市管理系统的设计与实现
java·vue.js·spring boot·源码·课程设计·毕设·大作业
ym hyd 1116 小时前
题库建立与考试系统源码 Java+SpringBoot+Vue3 前后分离
java·开发语言·vue.js·spring boot·毕设
萧瑟余晖7 小时前
Spring Boot Starter机制与自定义详解
spring boot
vx-程序开发8 小时前
【计算机毕设】52744基于微信小程序的民宿智能预订系统
java·spring boot·毕业设计·源码·课程设计·毕设·大作业
萧瑟余晖8 小时前
Spring Boot 配置体系详解
spring boot
专业程序开发源9 小时前
springboot古城景区管理系统88564-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·php·课程设计
小蒜学长9 小时前
基于微信小程序的遇见咖啡店点餐系统设计与实现(代码+数据库+LW)
java·spring boot·后端·微信小程序·咖啡店点餐系统
小蒜学长9 小时前
基于SSM+VUE的电影售票平台的设计与实现(代码+数据库+LW)
java·vue.js·spring boot·后端·ssm框架·电影售票平台
Q264336502310 小时前
【有源码】基于Spring Boot+Vue的骑行爱好者平台的设计与实现-计算机毕设选题推荐
java·vue.js·spring boot·毕业设计·课程设计·数据可视化·源代码
FYKJ_201010 小时前
SpringSecurity教室智能预约系统73972-计算机课程设计、毕业设计
java·vue.js·spring boot·python·mysql·spring·django