虽然说现在都前后端分离了,后端不再玩前端那一套了,但是有时候写一些自己的东西的时候还是会需要用到一点的,在自己练习SpringBoot中使用JSP就遇到了下面的坑。

1.tomcat-embed-jasper包依赖

SpringMVC中jsp请求流程:

  1. servlet容器收到请求,分发到SpringMVC的DispatcherServlet
  2. SpringMVC经过处理,返回jsp视图名称,随后通过InternalResourceViewResolver解析得到InternalResourceView
  3. InternalResourceView通过forward方式服务器内部跳转
  4. servlet容器再次收到请求,由于本次请求中url中带有.jsp后缀,所以分发给JspServlet处理
  5. JspServlet在第一次被调用时使用jsp引擎解析jsp文件,并生成servlet,并注册,随后调用

问题:
   当InternalResourceView进行forward之后,请求又进入到了SpringMVC的DispatcherServlet中,但是因为JspServlet没有被注册到Servlet容器中,所以请求分发到DispatcherServlet来处理,所以导致了JSP页面找不到。

解决:
   添加tomcat-embed-jasper依赖。

 <dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
</dependency>

原因:

  1. 外置Tomcat时不需要添加上面这个包的依赖,因为Tomcat自动引入了这个包,并且JspServlet也被Tomcat自动引入了注册了
  2. 内置Tomcat中这个包是独立出来的,需要我们单独引入,并且内置Tomcat不会自动注册JspServlet。
  3. 那为什么只引入了这个包就可以了呢,是因为SpringBoot帮我们引入了
//tomcat启动准备
protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
  File docBase = getValidDocumentRoot();
  docBase = (docBase != null ? docBase : createTempDir("tomcat-docbase"));
  final TomcatEmbeddedContext context = new TomcatEmbeddedContext();
  ...
  //是否Classpath中有org.apache.jasper.servlet.JspServlet这个类
  //有就注册
  if (shouldRegisterJspServlet()) {
  addJspServlet(context);
  addJasperInitializer(context);
  context.addLifecycleListener(new StoreMergedWebXmlListener());
  }
}
2.JSP放在哪

   JSP页面是放在webapp/WEB-INF/下的文件夹中,而idea的maven工程是没有这个文件夹的,这时候需要添加一个web,修改下路径即可。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3. 访问报404错误

在这里插入图片描述
  这是因为idea默认路径是工程的路径 而不是模块的路径 所以导致多模块无法定位到/WEB-INF/jsp/index.jsp,而独立的模块工程路径就是模块路径,所以在多模块项目下可以指定工作路径就是当前模块:
在这里插入图片描述

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐