我可以从lib中的JAR内部提供JSP吗,还是有解决方法?
我在Tomcat 7中将一个Web应用程序部署为WAR文件。该应用程序构建为一个多模块项目:
通常,我们可以将我们的JSP文件放入webapp项目中,并相对于上下文来引用它们:
/WEB-INF/jsp/someMagicalPage.jsp
问题在于我们如何处理特定于客户扩展项目的JSP文件,该文件不应总是包含在WAR中。 不幸的是,我看不出JAR文件里面的JSP。 尝试classpath:jsp/customerMagicalPage.jsp
由于使用ServletContext.getResource()
,所以classpath:jsp/customerMagicalPage.jsp
产生的文件在JspServlet中找不到。
传统上,我们通过maven解开客户扩展JAR,找到JSP,并在构建它时将它们放入WAR中来“解决”这个问题。 但是,理想的情况是,您只需将Tom JAR放入Tomcat中的WAR WAR文件中,并且可以发现扩展 - 这适用于除JSP之外的所有应用程序。
无论如何要解决这个问题吗? 一种标准的方式,一种特定于Tomcat的方式,一种黑客或者解决方法? 例如,我一直在考虑在应用程序启动时解压缩JSP ......
Tomcat 7支持的Servlet 3.0包括将jsps打包成jar的功能。
你需要:
META-INF/resources
目录下 META-INF
目录中包含一个web-fragment.xml
文件 WEB-INF/lib
目录下 然后,您应该能够在您的上下文中引用您的jsps。 例如,如果你有一个jsp的META-INF/resources/test.jsp
你应该可以在你的上下文的根目录中引用它作为test.jsp
作为一种解决方法,我创建了一个类,该类打开一个jar文件,查找匹配特定模式的文件,并将这些文件提取到相对于上下文路径的给定位置。
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.annotation.PostConstruct;
import javax.servlet.ServletContext;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.context.ServletContextAware;
/**
* Allows extraction of contents of a JAR file. All files matching a given Ant path pattern will be extracted into a
* specified path.
*/
public class JarFileResourcesExtractor implements ServletContextAware {
private String resourcePathPattern;
private String jarFile;
private String destination;
private ServletContext servletContext;
private AntPathMatcher pathMatcher = new AntPathMatcher();
/**
* Creates a new instance of the JarFileResourcesExtractor
*
* @param resourcePathPattern
* The Ant style path pattern (supports wildcards) of the resources files to extract
* @param jarFile
* The jar file (located inside WEB-INF/lib) to search for resources
* @param destination
* Target folder of the extracted resources. Relative to the context.
*/
private JarFileResourcesExtractor(String resourcePathPattern, String jarFile, String destination) {
this.resourcePathPattern = resourcePathPattern;
this.jarFile = jarFile;
this.destination = destination;
}
/**
* Extracts the resource files found in the specified jar file into the destination path
*
* @throws IOException
* If an IO error occurs when reading the jar file
* @throws FileNotFoundException
* If the jar file cannot be found
*/
@PostConstruct
public void extractFiles() throws IOException {
try {
String path = servletContext.getRealPath("/WEB-INF/lib/" + jarFile);
JarFile jarFile = new JarFile(path);
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (pathMatcher.match(resourcePathPattern, entry.getName())) {
String fileName = entry.getName().replaceFirst(".*/", "");
File destinationFolder = new File(servletContext.getRealPath(destination));
InputStream inputStream = jarFile.getInputStream(entry);
File materializedJsp = new File(destinationFolder, fileName);
FileOutputStream outputStream = new FileOutputStream(materializedJsp);
copyAndClose(inputStream, outputStream);
}
}
}
catch (MalformedURLException e) {
throw new FileNotFoundException("Cannot find jar file in libs: " + jarFile);
}
catch (IOException e) {
throw new IOException("IOException while moving resources.", e);
}
}
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
public static int IO_BUFFER_SIZE = 8192;
private static void copyAndClose(InputStream in, OutputStream out) throws IOException {
try {
byte[] b = new byte[IO_BUFFER_SIZE];
int read;
while ((read = in.read(b)) != -1) {
out.write(b, 0, read);
}
} finally {
in.close();
out.close();
}
}
}
然后在Spring XML中将它配置为一个bean:
<bean id="jspSupport" class="se.waxwing.util.JarFileResourcesExtractor">
<constructor-arg index="0" value="jsp/*.jsp"/>
<constructor-arg index="1" value="myJarFile-1.1.0.jar"/>
<constructor-arg index="2" value="WEB-INF/classes/jsp"/>
</bean>
这不是一个真正烦人的问题的最佳解决方案。 现在的问题是,在我睡觉的时候,维护这些代码的人会来杀我吗?
有这样的解决方法 - 您可以将您的JSP预编译为servlet。 因此,您将获得可放入JAR中的.class文件并将其映射到web.xml中的某些URL。
链接地址: http://www.djcxy.com/p/74667.html上一篇: Can I serve JSPs from inside a JAR in lib, or is there a workaround?
下一篇: Maven