内容简介:使用spring boot和embedded tomcat开发时出现404找不到jsp问题的处理
初使用spring boot时,出现程序中配置了相应的指向地址,但前端界面始终报找不到jsp界面的404错误.但相同的程序在另一位同事时却正常工作.因此,有必要从源码角度分析一下,spring boot如何和embedded tomcat进行相应的整合.
本文开发时使用的为idea,相应的jsp放置在标准的src/main/webapp目录下,并且spring mvc也配置了 spring.mvc.view.prefix各项网上都能找到的配置信息.
首先是先将一个最简单的jsp文件放置在src/main/webapp,然后启动程序,直接访问此jsp(不通过mvc跳转), 仍然返回404.这就表示实际上这个src/main/webapp并没有被spring boot中tomcat所识别. 一般认为这个目录就是一个放置资源信息的地址目录,那么这里404表示在启动过程中,这个目录并没有被正常找到.
因为spring boot并没有一个显示配置项来配置此位置(从hello的demo来看),因此此地址的查找为一个简单的逻辑过程.从tomcat的角度来看,这属于一个documentRoot,即项目文件根目录,从尝试从整个源码中搜索有关于documentRoot,或者说对于tomcat一个上下文来讲为docBase的概念.最终找到的位置为 TomcatEmbeddedServletContainerFactory#prepareContext 方法.
简单的代码来看,主要的代码如下所示:
File docBase = getValidDocumentRoot(); docBase = (docBase != null ? docBase : createTempDir("tomcat-docbase")); context.setDocBase(docBase.getAbsolutePath());
这里尝试找到documentRoot,如果没找到就使用临时目录,并设置相应的docBase.那么继续查看如何来找到documentRoot处理.代码如下所示:
//1 获取显式设置的根目录 //默认情况下,在整个spring boot中,无其它地方会调用setDocumentRoot方法 File file = getDocumentRoot(); // If document root not explicitly set see if we are running from a war archive //2 如果没有,如果当前运行环境为一个war包,则认为就是当前war目录 //即当前jar包是放到一个xx.war中的 file = file != null ? file : getWarFileDocumentRoot(); // If not a war archive maybe it is an exploded war //3 如果仍没有,那么如果当前运行环境在一个有 WEB-INF的路径下,则认为是一个目录结构形式的web项目 // 即当前jar包放到一个目录下,此目录是类似xxx/WEB-INF/xxx的类似结构,如常规的xx/WEB-INF/lib/spring.jar这样的结构 file = file != null ? file : getExplodedWarFileDocumentRoot(); // Or maybe there is a document root in a well-known location //4 尝试探测一些常见的目录,如果找到就认为是相应的位置 file = file != null ? file : getCommonDocumentRoot(); ...... return file;
从上面的代码来看,只能是第4点找到相应的目录,此代码如下:
//COMMON_DOC_ROOTS = { "src/main/webapp", "public","static" }; for (String commonDocRoot : COMMON_DOC_ROOTS) { File root = new File(commonDocRoot); if (root.exists() && root.isDirectory()) { return root.getAbsoluteFile(); } } return null;
这里,是通过获取一个文件夹对象,并判断文件夹是否存在来决定是否找到位置.那么按理在程序中的src/main/webapp是满足第1个条件的,但这里并不满足,惟一的可能性就是因为这里的file对象是相对路径,其的地址与我们的地址不匹配. 在断点情况下,可通过file.getAbsoluteFile来查看其具体位置.
那么,java相对文件的位置是如何确定,这就涉及到 java 命令工作目录的概念.在System.getProperties存在属性名为user.dir的属性,此值就是命令的工作目录.在程序中所有的相对文件均以此目录作为基准地址.
在idea中,可以通过run configurations进行相应的调整,在配置working directory中可以设置.在此程序中,我们需要将其调整为程序目录(如果为程序目录\target,则需要调整过来).
重新调整之后,再次运行,则相应的jsp则会被找到. 直接输入jsp,默认应该输出相应的内容,如果直接出现下载框,即jsp没有被解析,则检查 org.apache.tomcat.embed:tomcat-embed-jasper 在pom.xml有没有被引入.此依赖包作于处理jsp.
后注:
在上文中的第1步中的documentRoot,在spring boot中,可以通过编写一个EmbeddedServletContainerCustomizer来动态指定,如下参考所示:
@Component public class DocumentDirectoryCustomizer implements EmbeddedServletContainerCustomizer { public void customize(ConfigurableEmbeddedServletContainer container) { container.setDocumentRoot(new File("你想指定的位置")); } }
只需要将其设置为一个spring bean即可
以上所述就是小编给大家介绍的《使用spring boot和embedded tomcat开发时出现404找不到jsp问题的处理》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Google用AI设计AI芯片,不到24小时就能设计出Tensor处理单元
- 放弃 OpenStack?恐怕还不到时候
- 意想不到的MySQL复制延迟原因
- 盘点一下不到100行的给力代码
- Xcode 静态链接库找不到的问题
- 裁员过后,找不到工作的程序员们
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。