You can but you need some manual coding, as default servlet (part of container /tomcat/ that serves static resources) does know nothing about your jars. You need to
- implement your own servlet that can read data from classpath
- map it to some URL
- use URL in JSP with some parameter / path identifying the requested file
I implemented simple prototype, it does handle only CSS files and it does not cover any corner cases. But it works and you can extend it as you need:
Servlet is simple, it just takes part or URL behind its mapping and loads resource from classpath (e.g. jar):
package cz.literak.demo;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
public class JarServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String path = request.getPathInfo();
setContentType(path, response);
InputStream streamIn = null;
try {
streamIn = getClass().getResourceAsStream(path);
PrintWriter writer = response.getWriter();
int c;
while ((c = streamIn.read()) != -1) {
writer.write(c);
}
} catch (IOException e) {
streamIn.close();
}
}
private void setContentType(String path, HttpServletResponse response) {
if (path.toLowerCase().endsWith(".css")) {
response.setContentType("text/css");
}
// TODO other mime types
}
}
You need to register the servlet and its mapping:
<servlet>
<servlet-name>JarDefault</servlet-name>
<servlet-class>cz.literak.demo.JarServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>JarDefault</servlet-name>
<url-pattern>/jar/*</url-pattern>
</servlet-mapping>
And you can use it this way:
<link rel="stylesheet" type="text/css" href="jar/styles/layout.css"/>
I copied file layout.css under directory styles in one jar that is part of my war. Easy, is not it?