Is It Possible with Spring Boot to Serve Up Jsps with a Jar Packaging

Is it possible with Spring Boot to serve up JSPs with a JAR packaging?

As @Andy Wilkinson said, there are limitations related to JSP. Please package your application as war and execute as jar. This is documented at spring site.

With Tomcat it should work if you use war packaging, i.e. an executable war will work (...). An executable jar will not work because of a hard coded file pattern in Tomcat.

  • 27.3.5 JSP limitations
  • jsp sample

Deprecated, old answer

Yes, this is possible with Spring Boot.

Take look at this example: https://github.com/mariuszs/spring-boot-web-jsp-example.

For doing this use spring-boot-maven-plugin or gradle equivalent.

With this plugin jar is executable and can serve JSP files.

$ mvn package
$ java -jar target/mymodule-0.0.1-SNAPSHOT.war

(Note the extension of the artifact in the above command .war)
or just

$ mvn spring-boot:run

Why does Spring boot not support jsp while it can render the page if we add proper jar reference

Embedded Tomcat package (which is used in springboot to create executable jar)does not include JSP by default, we must add the module “org.apache.tomcat.embed:tomcat-embed-jasper” as well.That is the reason why we are adding tomcat-embed-jasper as dependency in springboot, so that we can use the jstl tags in jsp.

The main reason why springboot does not work properly with jsp as view resolver , when *jar is used as packaging is because of a hard coded file pattern in Tomcat.The issue is that when you are using java -*.jar to deploy a springboot application , the jsp files will not be present in the embedded tomcat and while trying to serve the request you will get a 404 PAGE NOT FOUND. This is because of the jar packaging ,that the jsp files are not getting copied from the WEB-INF folder.If you keep the jsp files under the META-INF/resources folder while using jar as packaging it should work.

Thymeleaf allows using templates as prototypes, meaning they can be viewed as static files and put in resources/templates folder for spring to pick up.But jsp files will have jstl tags etc which needs to be transpiled by the jasper before rendering , so they cannot be set as static files according to my knowledge.

When using a WAR(Webapplication archive), the packing will automatically take the resources from the following project structure :

 |-- pom.xml
`-- src
`-- main
|-- java
| `-- com
| `-- example
| `-- projects
| `-- SampleAction.java
|-- resources
| `-- images
| `-- sampleimage.jpg
`-- webapp
|-- WEB-INF
| `-- web.xml
|-- index.jsp
`-- jsp
`-- websource.jsp

Guides and official sample for using springboot with jsp : Guide , Sample Repo

The WAR packaging structure insists on keeping jsp files under webapp/ folder and it will work as expected. The maven war goal will copy the files from the webapp folder to the WEB-INF and all resource files like jsp will be at the root of the war packaging.From here, the maven-repackage goal or spring boot repackaging takes care of making the jar/war executable.So, if the files are present in the orginal war , it will be in the executable one as well.The springboot executable war structure is as follows :

example.war
|
+-META-INF
| +-MANIFEST.MF
+-org
| +-springframework
| +-boot
| +-loader
| +-<spring boot loader classes>
+-WEB-INF
+-classes
| +-com
| +-mycompany
| +-project
| +-YourClasses.class
+-lib
| +-dependency1.jar
| +-dependency2.jar
+-lib-provided
+-servlet-api.jar
+-dependency3.jar

So for the comment :

If you put your jsp files in the folder src/main/resources , anything that is put in this directory will be automatically copied to the WEB-INF/classes as per the WAR documentation.

So , if you keep your jsp files under src/main/resources and configure the following in yml or property file, it should work for WAR archives.I haven't tried it so not sure.

spring.mvc.view.prefix = /WEB-INF/classes/templates
spring.mvc.view.suffix = .jsp

Is it possible with Spring Boot to serve up JSPs with a stand alone JAR packaging

If you are using embedded Tomcat, Spring Boot doesn't support using JSPs in an executable jar:

With Tomcat it should work if you use war packaging, i.e. an executable war will work, and will also be deployable to a standard container (not limited to, but including Tomcat). An executable jar will not work because of a hard coded file pattern in Tomcat.

It works when you try java -jar target/mymodule-0.0.1-SNAPSHOT.jar because the JSPs are available on the filesystem from src/main/webapp which Spring Boot configures as a document root for convenience during development. When you move into the target directory, the src/main/webapp folder is no longer available so the JSPs stop working.

Spring boot executable jar unable to load jsp file?

As M.Deinum pointed out in comments, it's not possible to develop a web application whose view technology is JSP and build as an executable jar. In order to do so either, you have to change the view technology or change build type to war.

Package a spring boot application including JSPs and static resources

The following example works with Spring Boot 1.3.3.RELEASE:
https://github.com/ghillert/spring-boot-jsp-demo

The key is to put the static jsp content in:

/src/main/resources/META-INF/resources/WEB-INF/jsp

and ensure you define the view prefix/suffix in your application.properties:

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

JSPs with Spring Boot

JSP's are part of legacy Java Enterprise applications and are not the core of Spring Boot/MVC and it's more modern Template Engine approach (although Spring is based on Java EE). If you have any good reason to use JSP's, it could work. But with Spring, the MVC approach/implementation is to use the more modern template engines with technologies like Thymeleaf, FreeMarker, Groovy Markup, and Mustache.

Question 1 If you have configured your pom.xml correctly, you can use different starters to configure how your application is deployed/run. JSP's are not a standard solution for Spring and should be configured seperately, it needs to be configured so that it will compile the JSP's into their respective location so that Tomcat reads it from the webapps folder. To compile and render JSP's your pom.xml needs both spring-boot-starter-web and tomcat-embed-jasper including the tag <scope>provided</scope>.

Question 2 Spring comes with an embedded Tomcat server (spring-boot-starter-web). When you run mvn spring-boot:run it will start a Tomcat server and deploy your Spring Boot application on the Tomcat localhost:8080. mvn clean, before spring-boot:run, just deletes the output of a build by deleting the build directory.

Question 3 Each .HTML template or .JSP file have their respective location in the project before compiling, so therefore some .JSP's are not compiled in your folders.

A Java Enterprise application and it's corresponding JSP's use a different project structure than Spring: All JSP's will be compiled from the "src/main/webapp/WEB-INF/jsp/" if you have the right dependencies and run spring-boot:run. If you manually create a project, through compiling by cmd -jar, you should include your JSP's in the "/webapp/" folder and the Java.classes in WEB-INF/classes/MyServlet.class.

By using, for instance Thymeleaf (spring-boot-starter-thymeleaf), if you build your artifacts the IDE will compile templates from /resources/templates and work from there on your MVC project, where you can integrate your REST controllers seamlessly.

Tomcat stays pivotal in how your enterprise application is deployed, only that you need to adjust your project in Spring so that it will map and compile the right files into the .WAR before deploying.

My advice would be, for MVC, to use the template engines instead of the legacy JSP's. of course, there will use cases for JSP's inside a Spring project but it requires a differect structure and dependencies.



Related Topics



Leave a reply



Submit