Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

It is written everywhere that Spring boot does not support jsp view. In its official document there are three reasons

  • With Jetty and Tomcat, it should work if you use war packaging. An executable war will work when launched with java -jar, and will also be deployable to any standard container. JSPs are not supported when using an executable jar.
  • Undertow does not support JSPs.
  • Creating a custom error.jsp page does not override the default view for error handling. Custom error pages should be used instead.

For the first item, 'JSPs are not supported when using an executable jar'. But when I add reference to tomcat-embed-jasper and set correct resource path in application.properties, the jsp file can also be rendered well.

I guess this may mean that Spring boot not support jsp without invovling other reference libs such as tomcat-embed-jasper.

But for thymleaf, we also have to import spring-boot-starter-thymeleaf. Why can we say that Spring boot support thymleaf with involving extra libs.

So how can I understand the first item in document?

like image 455
Robin Sun Avatar asked Jun 11 '19 05:06

Robin Sun


People also ask

Why JSP is not used in spring boot?

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.

How do you enable JSP in spring boot?

Project Dependencies Default embedded servlet container for Spring Boot Starter Web is tomcat. To enable support for JSP's, we would need to add a dependency on tomcat-embed-jasper.

Can we use JSP with spring boot?

When building Web Applications, JavaServer Pages (JSP) is one option we can use as a templating mechanism for our HTML pages. On the other hand, Spring Boot is a popular framework we can use to bootstrap our Web Application.


1 Answers

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
like image 155
Ananthapadmanabhan Avatar answered Nov 14 '22 21:11

Ananthapadmanabhan