Spring Boot项目JSP无法在浏览器正常显示的问题排查求助
无法正常显示JSP页面的问题排查与解决
问题背景
跟随Spring Security角色权限控制教程开发时,JSP页面无法正常渲染,访问时返回500内部错误。
代码与配置详情
LoginController 代码
@Controller @RequestMapping("/api/page") public class LoginController { @GetMapping("/welcomePage") public ModelAndView welcomePage() { ModelAndView model = new ModelAndView(); model.setViewName("welcomePage"); return model; } @GetMapping("/homePage") public ModelAndView homePage() { ModelAndView model = new ModelAndView(); model.setViewName("homePage"); return model; } @GetMapping("/userPage") public ModelAndView userPage() { ModelAndView model = new ModelAndView(); model.setViewName("userPage"); return model; } @GetMapping("/adminPage") public ModelAndView adminPage() { ModelAndView model = new ModelAndView(); model.setViewName("adminPage"); return model; } @GetMapping("/loginPage") public ModelAndView loginPage(@RequestParam(value = "error",required = false) String error, @RequestParam(value = "logout", required = false) String logout) { ModelAndView model = new ModelAndView(); if (error != null) { model.addObject("error", "Invalid Credentials provided."); } if (logout != null) { model.addObject("message", "Logged out from successfully."); } model.setViewName("loginPage"); return model; } }
JSP文件结构与内容
JSP文件存放于/WEB-INF/view目录:
adminPage.jsp
<%@taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%> <h3>Admin Page</h3> <c:url value="/logout" var="logoutUrl" /> <form id="logout" action="${logoutUrl}" method="post" > <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> </form> <c:if test="${pageContext.request.userPrincipal.name != null}"> <a href="javascript:document.getElementById('logout').submit()">Logout</a> </c:if>
homePage.jsp
<%@taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%> <a href="${pageContext.request.contextPath}/userPage">User</a> | <a href="${pageContext.request.contextPath}/adminPage">Admin</a> | <a href="javascript:document.getElementById('logout').submit()">Logout</a> <h3>Welcome to Rest API Application</h3> <ul> <li>Java 8 tutorial</li> <li>Spring tutorial</li> <li>Gradle tutorial</li> <li>BigData tutorial</li> </ul> <c:url value="/logout" var="logoutUrl" /> <form id="logout" action="${logoutUrl}" method="post" > <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> </form>
loginPage.jsp
<%@ include file="welcomePage.html" %> <hr/> <h3>Login Form</h3> <% String profile_msg = (String) request.getAttribute("profile_msg"); if (profile_msg != null) { out.print(profile_msg); } String login_msg = (String) request.getAttribute("login_msg"); if (login_msg != null) { out.print(login_msg); } %> <br/> <form action="loginPage.jsp" method="post"> Email:<input type="text" name="email"/><br/><br/> Password:<input type="password" name="password"/><br/><br/> <input type="submit" value="login"/>" </form>
userPage.jsp
<%@taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%> <h3>User Page</h3> <c:url value="/logout" var="logoutUrl" /> <form id="logout" action="${logoutUrl}" method="post" > <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> </form> <c:if test="${pageContext.request.userPrincipal.name != null}"> <a href="javascript:document.getElementById('logout').submit()">Logout</a> </c:if>
application.properties 配置
spring.mvc.view.prefix=/webapp/WEB-INF/view/ spring.mvc.view.suffix=.jsp
错误信息
Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Mon Dec 19 20:54:05 CET 2022 There was an unexpected error (type=Internal Server Error, status=500).
POM依赖
<dependencies> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> <version>2.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.4.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.5</version> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> <scope>provided</scope> </dependency> <!--<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity5</artifactId> </dependency>--> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>jakarta.servlet.jsp.jstl</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.2</version> <configuration> <includes> <include>**/*.java</include> </includes> </configuration> </plugin> </plugins> </build>
问题排查与解决方案
1. 视图解析器路径修正
当前spring.mvc.view.prefix配置错误,Spring Boot中JSP的默认根路径无需添加/webapp/,修改为:
spring.mvc.view.prefix=/WEB-INF/view/ spring.mvc.view.suffix=.jsp
2. 移除冲突依赖
POM中同时引入了Thymeleaf和JSP依赖,Spring Boot会优先使用Thymeleaf作为视图解析器,导致JSP无法被识别。需要移除Thymeleaf依赖:
<!-- 删除该依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
同时移除重复的JSTL依赖,保留org.glassfish.web:jakarta.servlet.jsp.jstl即可。
3. 修正JSP中链接路径
LoginController的请求前缀是/api/page,但JSP中直接使用/userPage等路径会导致404,需修改为完整路径:
比如homePage.jsp中的链接改为:
<a href="${pageContext.request.contextPath}/api/page/userPage">User</a> | <a href="${pageContext.request.contextPath}/api/page/adminPage">Admin</a>
4. 调整Spring Security配置
确保Security配置允许访问JSP对应的路径,并修正登录表单提交地址:
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/api/page/welcomePage", "/api/page/loginPage").permitAll() .antMatchers("/api/page/userPage").hasRole("USER") .antMatchers("/api/page/adminPage").hasRole("ADMIN") .anyRequest().authenticated() .and() .formLogin() .loginPage("/api/page/loginPage") .loginProcessingUrl("/login") // 与登录表单action对应 .permitAll() .and() .logout() .permitAll(); }
同时修改loginPage.jsp的表单action为/login,而非loginPage.jsp,确保Spring Security能处理登录请求。
5. 日志辅助排查
查看详细日志,定位具体错误(如JSP文件找不到、类加载异常等),进一步针对性解决问题。
内容的提问来源于stack exchange,提问作者invzbl3
相关产品推荐
相关产品推荐

