I'm developing a web application in java using Spring MVC 3.2.2. I'm having problems loading jsp page from within the jar file.
The Sring MVC web application that the following structure:
|-META-INF
|-WEB-INF
|-spring
| |- app-config.xml
|-classes
|-lib
| |-external.jar
| |-WEB-INF
| | |-views
| | |-external.jsp
| |-classes
| |-controller-for-external.class
|-views
|-... jsp
Config in app-config.xml
<context:annotation-config />
<context:component-scan base-package="com" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<mvc:resources mapping="/views/**" location="classpath:/WEB-INF/views/" />
<mvc:annotation-driven />
Controller for external.jsp
@Controller
public class ExternalController {
protected final Log logger = LogFactory.getLog(getClass());
@RequestMapping(value="/external.htm")
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Map<String, Object> myModel = new HashMap<String, Object>();
myModel.put("msg", "External page loaded");
return new ModelAndView("external", "model", myModel);
}
}
web.xml file
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>Springapp</display-name>
<servlet>
<servlet-name>springapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/app-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/app-config.xml</param-value>
</context-param>
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
</web-app>
When a try to show external.jsp page, spring don't want search it and show error HTTP 404 - /springapp/WEB-INF/views/external.jsp
Thanks Vivin for your solution. It worked for me.
In my case, I had:
testModule.jar
testProject.war
It may be important to say that Servlet 3.0 do not handle fragments on an Eclipse deployment scenario in Glassfish 3.1.2 (it maybe works in JBoss or others, to be confirmed). Actually, I set testModule.jar in deployment assembly of testProject.war and when I deploy through Eclipse, it generates a folder testModule.jar instead of a JAR file.
But it's working when exporting as a WAR.
EDIT:
To get it working with Eclipse deployment, you have to check an option in Glassfish 3.1.2 properties : Deploy as jar. I think it's a recent option implemented in the last plugin version. Visible on Kepler but not on Juno.
I did it using Vivin's solution. Here's the folder structure of my JAR in Eclipse.
Included the jar in the WEB-INF/lib folder of my WAR:
Also added the following in my pom.xml of WAR:
Included the jsp in my Web Project using :
Structure works for me
jar module (jar)
main web app module (war)
And ViewResolver config (I'm using Thymeleaf):
You can do this if you are using Servlet 3.0. However, it won't work with the way you have your JSPs packaged. You have to package resources into a JAR file in a specific way:
META-INF/resources
directory of your JAR.web-fragment.xml
file inMETA-INF
. This is similar to a typicalweb.xml
with some differences. See here for some details. There is also an example I found here. This is optional.WEB-INF/lib
of your WAR.Now you should be able to refer to those JSPs within your app's context. Basically
META-INF/resources
is mapped to the document root of your webapp. Look at this for more details. Keep in mind that this is not limited to JSPs. You can put images, JavaScript, or even CSS in there.