本地无法直接访问localhost:8080跳转到欢迎页index.html页面;报错javax.servlet.http.HttpServletRequest.getHttpServlet...

问题起因:本地无法直接访问localhost:8080跳转到欢迎页index.html页面。

最后我发现我的问题其实是我不能在controller层用forward进行请求转发,但是redirect重定向功能却可以用。
代码解释也就是

return "forward:/XXX.html"  //访问该接口报错
return "redirect:/XXX.html"  //接口正常跳转

下面记录解决过程,希望对你能有帮助。

一:项目创建的流程。

在这里插入图片描述

这个springboot的版本是2.3.0,我也曾试过2.2.7以及2.2.2以及2.1.8的版本还有几个相近的版本,都没有用还是会报错。

在这里插入图片描述

仅仅勾选spring Web。

在这里插入图片描述

然后新建resources/static/index.html.

在这里插入图片描述

启动项目,注意提示,自动装配类确实把我新建的index.html设置为了欢迎页面,说明问题不在于装配的过程。

在这里插入图片描述

访问localhost:8080,页面报错500。console窗口报错如下:
java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.getHttpServletMapping()Ljavax/servlet/http/HttpServletMapping;
	at org.apache.catalina.core.ApplicationHttpRequest.setRequest(ApplicationHttpRequest.java:709) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationHttpRequest.<init>(ApplicationHttpRequest.java:115) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationDispatcher.wrapRequest(ApplicationDispatcher.java:917) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:358) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:171) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:316) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1373) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1118) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1057) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[servlet-api.jar:na]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[servlet-api.jar:na]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_60]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_60]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60]

 ERROR 15908 --- [nio-8080-exec-5] o.a.c.c.C.[Tomcat].[localhost]           : Exception Processing ErrorPage[errorCode=0, location=/error]

java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.getHttpServletMapping()Ljavax/servlet/http/HttpServletMapping;
	at org.apache.catalina.core.ApplicationHttpRequest.setRequest(ApplicationHttpRequest.java:709) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationHttpRequest.<init>(ApplicationHttpRequest.java:115) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationDispatcher.wrapRequest(ApplicationDispatcher.java:917) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:358) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312) ~[tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:394) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:253) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:348) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:173) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_60]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_60]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.35.jar:9.0.35]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60]
二:为了解决这个问题,我试着把用 WebMvcConfigurer 或者Controller 来人为做一个跳转来访问欢迎页。
  • 用WebMvcConfigurer重写方法来实现操作

单纯的路由跳转,而不做任何逻辑处理

implements WebMvcConfigurer(官方推荐)

②extends WebMvcConfigurationSupport

WebMvcConfigurerAdapter (已被淘汰)
@Configuration
public class helloD implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index.html");
        //registry.addViewController("/").setViewName("index.html");
    }
}
  • 用Controller来操作
@Controller
public class helloA {
    @RequestMapping("/")
    public String helloa(){
        return "forward:/index.html";
    }
}
结果:两种方式仍然报错,和一开始的错误一摸一样。后
  • 然后我试着用Controller下面不再使用上面的forward转发的方式进行跳转至index.html,而是写redirect进行重定向:
@Controller
public class helloE {
    @RequestMapping("/")
    public String hello(){
        return "redirect:/index.html";
    }
}
结果:没有报错! 成功帮我在静态资源下面找到了index.html。
但这种结果不是我想要的,正常情况下我用redirect和forward进行跳转应该都可以!为什么我不能用forward跳转。
三:降低springboot的版本。

后来我发现了一个点,那就是95%的错误行提示都指向了一个[tomcat-embed-core-9.0.35.jar:9.0.35]的包下面的javax包,上网搜了一下资料,大部分都说tomcat版本在8.5左右是用的比较多的。

然后我去依赖中将SpingBoot的版本从2.3.0依次下降到2.0.5,tomcat的jar包也随着降到了8.X。

结果,在2.0.5的版本居然一切回归正常。。都正常了额
<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.0.5.RELEASE</version>
四:下载新的JDK

后来,我仍然不满足,难不成要一直用低版本?!

于是我卸载IDEA,重新安装,从2018.3到2020.1的版本都试过破解和试用期,结果还是没起任何作用;再后来我尝试把所有的编码格式弄成了UTF-8,仍然不行!之后就是各种查阅资料,看博客,没有进展。

到这里已经花了快一整天时间了,基本筋疲力尽,身心俱疲。这玩意简直诛心。。

直到我破天荒地点开了一篇不是和我的问题很相关的博客,里面谈到tomcat-embed-core.jar下的javax包是有实现或调用了JDK中javax包里面的函数。
我突然意识到JDK可能有问题,于是我重新从Oracle下载新的JDK(密码早忘了又一波曲折),然后重新配置环境,换上新的JDK 。
果然,一切又回归正常。。包括springboot最新的2.3.1版本也不会出现问题。

一路简直多舛,不过多多少少还是学会了一些东西,又想起哈弗图书馆墙上的一句训言-‘痛苦的享受’,学习哪有轻松的,只有慢慢啃呀。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 创建数据库和表 首先,我们需要创建一个数据库和一张表来存储用户注册信息。假设我们的数据库名为`userdb`,表名为`user`,包含以下四个字段: ``` id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL, password VARCHAR(50) NOT NULL, email VARCHAR(50) NOT NULL ``` 其中,`id`为主键,自增长,`username`、`password`和`email`分别为用户名、密码和邮箱,均不能为空。 2. 创建注册页面 我们可以创建一个名为`register.jsp`的页面,用于用户注册。页面包含一个表单,用户可以输入自己的用户名、密码和邮箱。表单提交后,我们需要将用户输入的信息保存到数据库中。 代码如下: ``` <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>用户注册</title> </head> <body> <h1>用户注册</h1> <form action="register" method="post"> <label for="username">用户名:</label> <input type="text" id="username" name="username" required> <br> <label for="password">密码:</label> <input type="password" id="password" name="password" required> <br> <label for="email">邮箱:</label> <input type="email" id="email" name="email" required> <br> <input type="submit" value="注册"> </form> </body> </html> ``` 3. 创建注册处理程序 我们需要创建一个名为`RegisterServlet`的Java Servlet来处理注册请求。当用户提交注册表单时,`RegisterServlet`会读取表单中的用户名、密码和邮箱,然后将它们插入到数据库中。 代码如下: ``` import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/register") public class RegisterServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 读取表单中的数据 String username = request.getParameter("username"); String password = request.getParameter("password"); String email = request.getParameter("email"); // 将用户输入的数据插入到数据库中 Connection conn = null; PreparedStatement stmt = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/userdb?useSSL=false", "root", "password"); String sql = "INSERT INTO user (username, password, email) VALUES (?, ?, ?)"; stmt = conn.prepareStatement(sql); stmt.setString(1, username); stmt.setString(2, password); stmt.setString(3, email); stmt.executeUpdate(); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } finally { try { if (stmt != null) stmt.close(); if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } // 注册成功,跳转到登录页面 response.sendRedirect("login.jsp"); } } ``` 在`doPost`方法中,我们首先读取表单中的数据,然后将它们插入到数据库中。插入操作完成后,我们使用`sendRedirect`方法将用户重定向到登录页面。 4. 创建登录页面 我们可以创建一个名为`login.jsp`的页面,用于用户登录。页面包含一个表单,用户可以输入自己的用户名和密码。表单提交后,我们需要验证用户输入的用户名和密码是否正确。 代码如下: ``` <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>用户登录</title> </head> <body> <h1>用户登录</h1> <form action="login" method="post"> <label for="username">用户名:</label> <input type="text" id="username" name="username" required> <br> <label for="password">密码:</label> <input type="password" id="password" name="password" required> <br> <input type="submit" value="登录"> </form> </body> </html> ``` 5. 创建登录处理程序 我们需要创建一个名为`LoginServlet`的Java Servlet来处理登录请求。当用户提交登录表单时,`LoginServlet`会读取表单中的用户名和密码,然后查询数据库中是否存在该用户。 代码如下: ``` import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @WebServlet("/login") public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 读取表单中的数据 String username = request.getParameter("username"); String password = request.getParameter("password"); // 查询数据库中是否存在该用户 Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/userdb?useSSL=false", "root", "password"); String sql = "SELECT * FROM user WHERE username = ? AND password = ?"; stmt = conn.prepareStatement(sql); stmt.setString(1, username); stmt.setString(2, password); rs = stmt.executeQuery(); if (rs.next()) { // 登录成功,将用户信息保存到Session中 HttpSession session = request.getSession(); session.setAttribute("username", username); session.setAttribute("password", password); // 跳转到首 response.sendRedirect("index.jsp"); } else { // 登录失败,返回登录页面 response.sendRedirect("login.jsp"); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } finally { try { if (rs != null) rs.close(); if (stmt != null) stmt.close(); if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } ``` 在`doPost`方法中,我们首先读取表单中的数据,然后查询数据库中是否存在该用户。如果存在,则将用户信息保存到Session中,然后跳转到首;否则,返回登录页面。 6. 首 我们可以创建一个名为`index.jsp`的页面,作为登录成功后的首页面中可以显示用户的用户名和密码。 代码如下: ``` <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>首</title> </head> <body> <h1>欢迎您,<%=session.getAttribute("username")%></h1> <p>您的密码是:<%=session.getAttribute("password")%></p> </body> </html> ``` 在页面中,我们使用`session.getAttribute`方法来读取Session中保存的用户信息。 7. 部署和运行 最后,我们需要将上述代码部署到Servlet容器中,并启动容器。在浏览器中访问`http://localhost:8080/register.jsp`,即可进入注册页面。填写表单并提交后,即可完成用户注册。注册成功后,页面会自动跳转到登录页面。在登录页面中输入用户名和密码,即可登录系统,并进入首。在首中,可以看到用户的用户名和密码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值