我使用了spring boot + jsp,并且来自this post我知道在src/main/resources/META-INF/resources/
中放置jsp文件是否也可以打包为可执行jar。
不幸的是,当我将弹簧启动版本从1.4.2
修改为1.5.3
时,它无法支持并返回404.在跟踪其源代码并进行比较后,我知道为什么1.5.3
无法支持它。
Spring boot 1.4.2
//org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.StoreMergedWebXmlListener#onStart
private void onStart(Context context) {
ServletContext servletContext = context.getServletContext();
if(servletContext.getAttribute("org.apache.tomcat.util.scan.MergedWebXml") == null) {
servletContext.setAttribute("org.apache.tomcat.util.scan.MergedWebXml", this.getEmptyWebXml());
}
// only 1.4.2 has this line and with this code could recognise jsp files in /META-INF/resources/
TomcatResources.get(context).addClasspathResources();
}
Spring boot 1.5.3
private void onStart(Context context) {
ServletContext servletContext = context.getServletContext();
if (servletContext.getAttribute(MERGED_WEB_XML) == null) {
servletContext.setAttribute(MERGED_WEB_XML, getEmptyWebXml());
}
}
所以我想知道为什么在1.4.2之后必须删除这段代码?
TomcatResources.get(context).addClasspathResources();
因为我仍然想使用1.5.3所以我必须通过以下方式手动添加此代码
1.将TomcatEmbeddedServletContainerFactory
的源代码复制到当前类路径
2.以下修改
private void onStart(Context context) {
ServletContext servletContext = context.getServletContext();
if (servletContext.getAttribute(MERGED_WEB_XML) == null) {
servletContext.setAttribute(MERGED_WEB_XML, getEmptyWebXml());
}
// Add below code
ClassLoader loader = getClass().getClassLoader();
URL[] urLs = ((URLClassLoader) loader).getURLs();
List<URL> list = new ArrayList<>();
//String file = "file:/Users/zhugw/workspace/boot-jar-serving-jsp/boot-jar-serving-jsp-1.0-SNAPSHOT.jar!/";
String file = urLs[0].getFile().replaceFirst("BOOT-INF/classes!/", "");
URL jar = new URL("jar", "", file);
list.add(0,jar);
TomcatResources.get(context).addResourceJars(list);
}
它确实有效。我想知道是否可以这样做?
答案 0 :(得分:1)
我们在这里有相同的pb。
...
引起:java.lang.IllegalAccessError:试图访问类 org.springframework.boot.context.embedded.tomcat.TldSkipPatterns来自 类 org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory 在org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory。(TomcatEmbeddedServletContainerFactory.java:130)
...
现在在SpringBoot 1.5.8.RELEASE中,TomcatEmbeddedServletContainerFactory.prepareContext()中有以下几行:
context.addLifecycleListener(new LifecycleListener() {
@Override
public void lifecycleEvent(LifecycleEvent event) {
if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) {
TomcatResources.get(context)
.addResourceJars(getUrlsOfJarsWithMetaInfResources());
}
}
});
解决方案:我们只是删除了此覆盖。 Jar文件在类加载器中是后备的,因此应用程序可以正确识别存储在这些jar文件中的jsp文件。