为啥我的 Spring 应用程序使用 @RestController 而不是 @Controller
Posted
技术标签:
【中文标题】为啥我的 Spring 应用程序使用 @RestController 而不是 @Controller【英文标题】:Why is my Spring application working with @RestController but not with @Controller为什么我的 Spring 应用程序使用 @RestController 而不是 @Controller 【发布时间】:2021-09-10 07:27:40 【问题描述】:我正在学习有关 Spring 应用程序的教程,其中讲师正在构建一个基本的 Spring MVC 应用程序。讲师使用的是没有构建管理器的 Eclipse,但我使用的是带有 Gradle 的 IntelliJ Ultimate。我不确定这是否重要,但我包括保持透明。
在第一个项目中,讲师创建了一个如下所示的应用。
package com.example.springdemo.mvc;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.Controller;
@Controller
public class HomeController
@RequestMapping("/")
public String showPage()
return "main-menu";
当我运行项目时,我得到一个白标签错误页面。
但是,当我使用@RestController 而不是@Controller 运行程序时,它可以正常工作。讲师没有检查@RestController,我更愿意像讲师那样关注项目,但我所做的似乎没有任何效果?
我已经阅读了this page here,但它只是说我不需要@ResponseBody 注释,我的导师也没有使用它。这是因为不同的IDE吗?或者可能与部署自动化软件有关?还是完全不同的东西?我该怎么做才能让@Controller 注解在教师使用它时发挥作用?
编辑:
我刚刚注意到我的代码在使用@RestController 运行时,只在页面上显示“主菜单”字样。我正在尝试加载一个名为“main-menu.jsp”的页面。
这是我的文件夹结构
文件 spring-mvc-demo-servlet 包含以下 bean 代码:
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
编辑 2:
为了启动程序,我使用的是 IntelliJ 自动生成的 main 方法。
SpringMvcDemoApplication.java
package com.example.springdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication()
public class SpringMvcDemoApplication
public static void main(String[] args)
SpringApplication.run(SpringMvcDemoApplication.class, args);
我的 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>spring-mvc-demo</display-name>
<absolute-ordering />
<!-- Spring MVC Configs -->
<!-- Step 1: Configure Spring MVC Dispatcher Servlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-mvc-demo-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Step 2: Set up URL mapping for Spring MVC Dispatcher Servlet -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
和spring-mvc-demo-servlet.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- Step 3: Add support for component scanning -->
<context:component-scan base-package="com.example.springdemo" />
<!-- Step 4: Add support for conversion, formatting and validation support -->
<mvc:annotation-driven/>
<!-- Step 5: Define Spring MVC view resolver -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="\WEB-INF\view" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
我的应用程序.properties
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
编辑 3:
这是我的错误堆栈 strace:
2021-06-27 17:21:17.573 DEBUG 7824 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : GET "/", parameters=
2021-06-27 17:21:17.573 DEBUG 7824 --- [nio-8080-exec-4] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.example.springdemo.HomeController#showPage()
2021-06-27 17:21:17.574 DEBUG 7824 --- [nio-8080-exec-4] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, application/xhtml+xml, image/avif, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, */*;q=0.8]
2021-06-27 17:21:17.575 DEBUG 7824 --- [nio-8080-exec-4] o.s.w.servlet.view.InternalResourceView : View name 'main-menu', model
2021-06-27 17:21:17.575 DEBUG 7824 --- [nio-8080-exec-4] o.s.w.servlet.view.InternalResourceView : Forwarding to [main-menu]
2021-06-27 17:21:17.575 DEBUG 7824 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : "FORWARD" dispatch for GET "/main-menu", parameters=
2021-06-27 17:21:17.576 DEBUG 7824 --- [nio-8080-exec-4] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [Classpath [META-INF/resources/], Classpath [resources/], Classpath [static/], Classpath [public/], ServletContext [/]]
2021-06-27 17:21:17.582 DEBUG 7824 --- [nio-8080-exec-4] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
2021-06-27 17:21:17.582 DEBUG 7824 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Exiting from "FORWARD" dispatch, status 404
2021-06-27 17:21:17.583 DEBUG 7824 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND
2021-06-27 17:21:17.583 DEBUG 7824 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/error", parameters=
2021-06-27 17:21:17.583 DEBUG 7824 --- [nio-8080-exec-4] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse)
2021-06-27 17:21:17.585 DEBUG 7824 --- [nio-8080-exec-4] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, text/html;q=0.8]
2021-06-27 17:21:17.586 DEBUG 7824 --- [nio-8080-exec-4] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 404
编辑 4:
按照@chrylis 的建议,我已经使用 Thymeleaf 重建了项目。我仍然收到错误,但堆栈不同。这是新堆栈。
2021-06-27 20:51:15.304 ERROR 42244 --- [nio-8080-exec-1] org.thymeleaf.TemplateEngine : [THYMELEAF][http-nio-8080-exec-1] Exception processing template "main-menu": Error resolving template [main-menu], template might not exist or might not be accessible by any of the configured Template Resolvers
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [main-menu], template might not exist or might not be accessible by any of the configured Template Resolvers
at org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:869) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:607) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098) [thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072) [thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:366) [thymeleaf-spring5-3.0.12.RELEASE.jar:3.0.12.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:190) [thymeleaf-spring5-3.0.12.RELEASE.jar:3.0.12.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1396) [spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1141) [spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1080) [spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) [spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) [spring-webmvc-5.3.8.jar:5.3.8]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) [tomcat-embed-core-9.0.48.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) [spring-webmvc-5.3.8.jar:5.3.8]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) [tomcat-embed-core-9.0.48.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:228) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat-embed-websocket-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) [spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.8.jar:5.3.8]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) [spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.8.jar:5.3.8]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.8.jar:5.3.8]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1723) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.48.jar:9.0.48]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_291]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_291]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.48.jar:9.0.48]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_291]
2021-06-27 20:51:15.307 ERROR 42244 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template [main-menu], template might not exist or might not be accessible by any of the configured Template Resolvers] with root cause
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [main-menu], template might not exist or might not be accessible by any of the configured Template Resolvers
at org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:869) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:607) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072) ~[thymeleaf-3.0.12.RELEASE.jar:3.0.12.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:366) ~[thymeleaf-spring5-3.0.12.RELEASE.jar:3.0.12.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:190) ~[thymeleaf-spring5-3.0.12.RELEASE.jar:3.0.12.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1396) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1141) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1080) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.8.jar:5.3.8]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.48.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.8.jar:5.3.8]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.48.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:228) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.8.jar:5.3.8]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.8.jar:5.3.8]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.8.jar:5.3.8]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1723) [tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.48.jar:9.0.48]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_291]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_291]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.48.jar:9.0.48]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_291]
编辑 5:
回到我原来的构建,但摆脱了 web.xml,正如用户 @Asmin 所建议的那样。我似乎得到了更好的堆栈跟踪,现在表明它正在尝试打开名为 main-menu.jsp 的文件。但是,它说找不到资源。我尝试将spring.mvc.view.prefix
更改为读取为
spring.mvc.view.prefix=/WEB-INF/
spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.prefix=/resource/WEB-INF/view/
spring.mvc.view.prefix=F:/Projects/spring-mvc-demo/src/main/resources/WEB-INF/view/
它们中的每一个都返回相同的资源未找到堆栈跟踪。
2021-06-28 20:25:08.403 DEBUG 28116 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/", parameters=
2021-06-28 20:25:08.406 DEBUG 28116 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.example.springdemo.mvc.HomeController#showPage()
2021-06-28 20:25:08.420 DEBUG 28116 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, application/xhtml+xml, image/avif, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, */*;q=0.8]
2021-06-28 20:25:08.420 DEBUG 28116 --- [nio-8080-exec-1] o.s.w.servlet.view.InternalResourceView : View name 'main-menu', model
2021-06-28 20:25:08.421 DEBUG 28116 --- [nio-8080-exec-1] o.s.w.servlet.view.InternalResourceView : Forwarding to [/WEB-INF/view/main-menu.jsp]
2021-06-28 20:25:08.424 DEBUG 28116 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : "FORWARD" dispatch for GET "/WEB-INF/view/main-menu.jsp", parameters=
2021-06-28 20:25:08.426 DEBUG 28116 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [Classpath [META-INF/resources/], Classpath [resources/], Classpath [static/], Classpath [public/], ServletContext [/]]
2021-06-28 20:25:08.426 WARN 28116 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler : Path with "WEB-INF" or "META-INF": [WEB-INF/view/main-menu.jsp]
2021-06-28 20:25:08.426 DEBUG 28116 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
2021-06-28 20:25:08.426 DEBUG 28116 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Exiting from "FORWARD" dispatch, status 404
2021-06-28 20:25:08.427 DEBUG 28116 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND
2021-06-28 20:25:08.428 DEBUG 28116 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/error", parameters=
2021-06-28 20:25:08.428 DEBUG 28116 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse)
2021-06-28 20:25:08.442 DEBUG 28116 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, text/html;q=0.8]
2021-06-28 20:25:08.445 DEBUG 28116 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 404
【问题讨论】:
您期望的行为究竟是什么?你有read the documentation 为@RestController
吗?
我不确定你在这里问什么。我期待加载一个页面,该页面在页面正文中包含我的 main-menu.jsp 文件。我链接到一个页面,我在该页面上阅读了 2 个注释的差异。就像我在帖子中所说的那样,@Controller
和 @RestController
之间的唯一区别是 @RestController
捆绑了 @Controller
和 @ResponseBody
。讲师的代码不使用@ResponseBody
,但使用@Controller
运行良好。为什么我的工作方式和他的不一样?
从您的错误消息中可以看出您正在使用 Spring Boot,这是构建 Spring 应用程序的现代方式,但 bean
XML sn-p 表明您正在尝试混合配置策略(具体来说,配置为在外部容器中使用,而不是使用现代的“只需运行main
”方法)。您需要提供有关如何启动应用程序的更多信息。
我已将我的文件添加到原始问题中。我肯定在使用 main 方法来启动我的应用程序,它是由 IntelliJ 自动生成的。我确实注意到讲师没有主要方法。在 Eclipse 中,他简单地右键单击包并选择运行为 >>> 在服务器上运行。从您的评论看来,我必须调整他给我的 xml 文件以允许我从 main 方法运行?
您的讲师似乎使用了过时的设置(即“在服务器上运行”位)。您是否需要严格按照课程进行?
【参考方案1】:
你要做的是检查@Controller
和@RestController
之间的简单区别
当您使用简单的@Controller
时,它只是创建一个地图模型并返回一个视图,但我们需要在我们的 Rest APIS 中实时响应 json,因此您需要使用@RestController
,因为
@RestController
= @Controller
+@ResponseBody
但是当您使用@Controller
时,如果您想直接在JSON 中写入数据,则必须使用@ResponseBody
。
谢谢
这是参考
https://www.javacodegeeks.com/2017/08/difference-restcontroller-controller-annotation-spring-mvc-rest.html#:~:text=The%20%40Controller%20is%20a%20common,of%20%40Controller%20%2B%20%40ResponseBody%20.
【讨论】:
【参考方案2】:几天前我遇到了类似的问题。看来您正在尝试使用 Spring Boot。请尝试删除 web.xml 并按照以下代码 sn-ps 进行某些更改。这对我有用。
DemoApplication.java
@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder)
return builder.sources(DemoApplication.class);
public static void main(String[] args)
SpringApplication.run(DemoApplication.class, args);
application.properties
spring.mvc.view.prefix= /WEB-INF/
spring.mvc.view.suffix= .jsp
Project Structure for adding jsp files
Home Controller.java
@Controller
@Slf4j
public class HomeController
@RequestMapping(value = "/home", method = RequestMethod.GET)
public String home(Locale locale, Model model)
log.info("Welcome home! The client locale is .", locale);
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "home1";
PS:这是使用@Controller 运行的配置。
【讨论】:
嗨 Asmin,您的建议非常适合我的构建,但现在它似乎无法识别我的视图所在的文件夹。您有什么建议可以帮助我获得它跑步?我已经用第 5 次编辑更新了我的帖子,其中包含我到目前为止所做的事情和我的堆栈跟踪。感谢您的帮助。 再想一想,我相信我需要提出一个新问题。您的解决方案适用于我最初的问题,即如何让@Controller
在我的代码中工作。新问题现在显示找不到资源。谢谢您的帮助。我会继续并将您的答案标记为解决方案。
@skidwiz 请尝试我的答案所附的项目结构,并将您的观点从资源之外带入新文件夹 webapp。让我知道它是否有效。以上是关于为啥我的 Spring 应用程序使用 @RestController 而不是 @Controller的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 Spring 应用程序使用 @RestController 而不是 @Controller
为啥在将 Spring Data JPA 与 Spring Boot 结合使用时,我的数据库自定义没有得到应用?