Spring boot, JSP file as view not loading when run in IntelliJ - spring

I've created a simple Spring Boot Web Application in intelliJ. I've placed a simple .jsp file in the /src/main/resources/templates/ folder which contains some basic HTML.
I'm trying to return this in a controller but I'm getting this error;
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Fri Sep 09 10:37:46 BST 2016
There was an unexpected error (type=Not Found, status=404).
No message available
I'm assuming that Spring is unable to find the .jsp file, but there's no other errors appearing in the console to give me any further information.
Here's my simple controller;
#Controller
#RequestMapping("/test")
public class TestController {
#RequestMapping("")
public ModelAndView index() {
return new ModelAndView("test");
}
}
I've included the following in my application.properties file;
spring.mvc.view.prefix = /templates/
spring.mvc.view.suffix = .jsp
My POM file includes the following dependencies;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
I'm using Spring Boot with embedded tomcat.
I've tried changing the path to the views inside application.properties to;
classpath:/templates/ but that also didn't make any difference.
Finally, here is the structure of my project;
When running the application, I'm just using the 'Run' option in IntelliJ.

I have recently experienced the same situation with below dependency:-
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
If I change the "scope" to "default", run the application with Intellij, it works fine.
But if I want to keep the "scope" as "provided", I have to use the command line (terminal) and execute the following:-
mvn clean spring-boot:run
It works for me.

Setting working directory helped me --- by default, it was empty.
Edit your configuration for Spring boot application in Idea.
Set up the working directory, like it's done on a screenshot below:

If I make the tomcat-embed-jasper dependency default scope (not marked "provided") then everything works ... with spring boot 1.5.2 and idea 2017.1. Otherwise, it's kind of difficult to change this - if you change it in the IDEA project structure, it just gets lost the next time it updates the project from maven or gradle. I haven't figured out a way to otherwise make it work.
Things are further complicated if you use the Spring runner in IDEA -- though I recommend that regardless. It makes things nicer when IDEA fully knows your project is Spring.

There is a special hint for IntelliJ user in the Spring Boot reference documentation Chapter 27.1.7 Template engines:
IntelliJ IDEA orders the classpath differently depending on how you
run your application. Running your application in the IDE via its main
method will result in a different ordering to when you run your
application using Maven or Gradle or from its packaged jar. This can
cause Spring Boot to fail to find the templates on the classpath. If
you’re affected by this problem you can reorder the classpath in the
IDE to place the module’s classes and resources first. Alternatively,
you can configure the template prefix to search every templates
directory on the classpath: classpath*:/templates/.

After banging head here and there I figured out how to fix this problem. keep in mind I am using Windows 10 machine and IntelliJ version is 2021.2.2. Here are the steps:
In IntelliJ IDE Click on Run -> Edit Configurations...
In the Working Directory text field put %MODULE_WORKING_DIR%, I guess for linux it may be $MODULE_WORKING_DIR
Click Apply button
Click OK button
Run your Application
It will work.

A bit late but this worked for me.
Add your .jsp files at this path:
src/main/resources/META-INF/resources/
And if you want to configure the configure.properties file, add these lines in it:
spring.mvc.view.prefix= /WEB-INF/views/
spring.mvc.view.suffix= .jsp
Credit : https://www.logicbig.com/tutorials/spring-framework/spring-boot/boot-serve-dynamic.html

The following will make the application work with IntelliJ:
Under main, create the folder structure webapp/WEB-INF/jsps/ - the last part of the folder structure can be named anything, but it is where the jsps will reside.
Remove the properties:
spring.mvc.view.prefix = /templates/
spring.mvc.view.suffix = .jsp
from your application.properties file, and in a Configuration class explicitly create an InternalResourceViewResolver bean, and set these properties there.
This is what your Configuration class will look like:
#Configuration
#EnableWebMvc
public class WebMvcConfig {
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsps/");
resolver.setSuffix(".jsp");
return resolver;
}
}
Give that a try - it should work in IntelliJ

After many trials, it worked for me. Its the combination of 2 steps.
1) Maven packaging must be set to 'war', then only it puts everything under 'webapp' into the target war file.
If packaging is 'jar', its omitting the 'webapp' directory.
2) Running spring boot main class from IntelliJ is not working.
Run the application from command prompt using command: 'mvn spring-boot:run'

In IntelliJ you CAN NOT put provided under tomcat-embed-jasper!
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>

After many trails, I was able to fix the issue:
In IntelliJ 2019.02.04, Spring Boot configuration, select workspace $MODULE_WRK_DIR.

Controller:
#Controller
public class TestController {
#RequestMapping("/")
public String index() {
return "test.jsp";
}
}
Add this to application.properties:
spring.mvc.view.prefix=WEB-INF/
And put your jsp file in src/main/webapp/WEB-INF

if someone is still facing this issue on IntelliJ IDEA then just invalidate cache & restart the IDE. It will clear all downloaded dependencies & re-download all of them again. Hope this should solve your problem.

Related

Unable to serve JSP in Spring Boot applications

I have tried several tutorials to serve JSP pages using Spring Boot. They all return a 404 page not found error.
To overcome the known limitations, I'm using a WAR packaging, with the following dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
I have defined the path where JSP pages are in application.properties:
spring.mvc.view.prefix= /WEB-INF/jsp/
spring.mvc.view.suffix= .jsp
When requesting a JSP page, the following WARN is displayed:
WARN 10251 --- [io-8080-exec-11] o.s.w.s.r.ResourceHttpRequestHandler : Path with "WEB-INF" or "META-INF": [WEB-INF/jsp/hello.jsp]
Have JSP been deprecated in Spring Boot 2? Do you have any Spring Boot 2 working example with JSP ?
can you please try adding scope in your dependency just like this
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
I'm using Intellij IDEA. I found out that we cannot just run the SpringBootApplication main class directly. We need to let the maven do the work.
Short solution: maven run you application by the command below from your module root directory
mvn clean package spring-boot:run
You can also add a run configuration using Maven so that you don't have to type the command every time.
Some said JSPs folder should be put under src/main/resources/META-INF/resources/WEB-INF/jsp. This indeed solves the spring boot application run problem though, it will fail when you run the application using tomcat. So we still need to keep the structure if we are going to deploy the application to Tomcat.
Unfortunately, I couldn't find any Spring Boot 2 example able to serve JSP pages as they all return a 404 error. As a workaround I have configured the application to be deployed on WildFly, as described in this tutorial and run my application with JSP on WildFly.
If you want example here it is.
This also help you.

SpringBoot cannot provide jsp files in webapp Folder

I am new in springboot trying to simple webapp.
Using springboot 2.1.0 application.properties file like below.
I have jsp files in src/main/webapp/WEB-INF/jsp
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
My controller is .
#Controller
class WelcomeController {
#GetMapping("/")
fun showWelcomePage(model: Model): String {
model["name"] = "asdas"
return "welcome"
}
}
When I put jsp files in /main/resources/META-INF/resources/WEB-INF/jsp it works otherwise got below error
There was an unexpected error (type=Not Found, status=404).
/WEB-INF/jsp/welcome.jsp
Also pom has tomcat-embed-jasper dependency
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
Any idea?
Ensure that jasper dependency and embedded tomcat dependency versions should be same otherwise it will be an issue.
Also try putting a jsp page outside itself like src/main/webapp/abc.jsp and remove view resolver and return directly like "abc.jsp" and see if that works.
see this at 7:30
are you using intellij? i had experience about same spring boot (jsp view) project is working in eclipse, but it's not work in intellij. i requested to jetbrain about this issue, they are say to me that "it's right, but we recomment use template engine like handlebars"

logging.config configuration for spring boot

I wanted to configure location of log4j.xml file in my spring boot application.
For that I have added logging.config property to my application.properties configuration, indicating log4j.xml file path.
But seems this property is ignored.
But it should work accorindg to spring boot docs:
logging.config= # location of config file (default classpath:logback.xml for logback)
Have I did something wrong?
Spring Boot includes some starters that can be used if you want to exclude or swap specific technical facets. It's using logback by default, if you're gonna use log4j add spring-boot-starter-log4j in your classpath. For example, with maven it would be something like this:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>1.2.4.RELEASE</version>
</dependency>
and for log4j 1.x:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.2.4.RELEASE</version>
</dependency>
Then add logging.config to your application.properties:
logging.config = classpath:path/to/log4j.xml
I find out that in some cases external logging config(logback.xml)is not ignored: when application is started from application folder, it works properly.
Some clarification on this point: application is run through script, which can be called from any place.
I have not yet gone deep and found out why it works in that way, but if I provide config file path as an argument during the start up, it will work. So we just add this argument to running script:
--spring.config.location=/configPath/application.properties
Probably this problem is caused by Spring loading stages.
If you have any idea what is the root cause of this problem , please share:)
According to spring boot docs :
If you are using the starter poms for assembling dependencies that means you have to exclude Logback and then include your chosen version of Log4j instead.
like this :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
</dependency>
I spend few days to understand whether this should even work and I have doubts regarding this. Despite it is clearly mentioned in the documentation how to use Custom Log Configuration, some treat it differently. There many issues regarding this property is not working here and there on spring github issue tracker, like this and this. And another valid point is that logging configuration must be done as earlier as possible to correctly log application initialization. Thus system property looks like most savvy option here. And you can keep it within your application code. The only requirements would be to set it before spring context initialization.
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
// to start from command line
System.setProperty("logging.config", "classpath:portal-log4j2.yaml");
SpringApplication.run(Application.class, args);
}
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
// to start within container
System.setProperty("logging.config", "classpath:portal-log4j2.yaml");
// this has SpringApplication::run() inside
super.onStartup(servletContext);
}
}
Because all apps in Tomcat web container is loaded within the same JVM, there is no sense to deal with custom logging.config but use single config for the whole container with default file name.

Netbeans 8 won't reload static Thymeleaf files

I am using Spring Boot and Thymeleaf via Maven. I can't seem to get Netbeans to automatically re-deploy any of my Thymeleaf template files when I make changes. In order to see the changes I need to do a full clean/build/run. This takes way too long.
The templates are in src/main/resources/templates. I have an application.properties file in src/main/resources/ with spring.thymeleaf.cache=false and spring.template.cache=false.
I have "Compile on save", "Copy resources on save" and "Deploy on save" turned on in the project settings.
My maven build produces a war file that Netbeans deploys to Tomcat and I am using the annotation #EnableAutoConfiguration.
Netbeans does hot deploy changes to the Java classes but not for any of the static files in src/main/resources/.
Software in use:
Mac OS X 10.9.4
Java 1.8
Netbeans 8.0.1
Tomcat 8.0.12
Spring Boot 1.1.7
Thymeleaf 2.1.3 (via Spring Boot)
Any guidance is much appreciated.
An option would be to look into configuring Thymeleaf's FileTemplateResolver
To do that with Spring Boot, define a bean implementing the ITemplateResolver interface with the name defaultTemplateResolver, when present, Spring Boot would take it instead of its default, here is how that would be done, and assuming you have component scanning active so this configuration class will be picked up automatically:
#Configuration
public class ThymeleafConfiguration {
#Bean
public ITemplateResolver defaultTemplateResolver() {
TemplateResolver resolver = new FileTemplateResolver();
resolver.setSuffix(".html");
resolver.setPrefix("path/to/your/templates");
resolver.setTemplateMode("HTML5");
resolver.setCharacterEncoding("UTF-8");
resolver.setCacheable(false);
return resolver;
}
}
The prefix should be a relative path that when added to your runtime working directory (cwd), would resolve to the templates directory. If you are unsure, set that to the full absolute path, but then there would be no point of the above bean. Since setting the spring.thymeleaf.prefix property to an absolute path would probably have the same effect.
Have been looking for a solution to my eclipse+thymeleaf+sprint boot reloading templates dynamically for a log while....
Finally I found this question here and spring.thymeleaf.cache=false and spring.template.cache=false fixed my issue.
Besides setting the Thymeleaf views as non-cacheable by ie. spring.thymeleaf.cache=false in your application.properties,
try explicitly defining the resource directory in your pom.xml:
<build>
...
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
...
</build>
To deal with that, the spring-boot-maven-plugin in the pom.xml should seems like this:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
</dependencies>
</plugin>
And add this to your application properties:
spring.thymeleaf.cache=false
It usually works to Spring beans too.
Just to say this works nicely for me using an external instance of Tomcat:
Run Tomcat with JRebel or Spring Loaded javaagent as a VM option
Turn off "Compile on save", "Copy resources on save" and "Deploy on save"
Add a custom action in Netbeans that executes the compile goal
Run that when you want to see an update
http://wiki.netbeans.org/MavenBestPractices#Binding_Maven_goals_to_IDE_actions
https://github.com/spring-projects/spring-loaded
https://zeroturnaround.com/software/jrebel/quickstart/standalone/
Or you can you use the embedded tomcat with spring-boot-maven-plugin and Spring Loaded instead, then you won't need the compile action:
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-hotswapping.html
I had this problem too. I notice Netbeans reload automaticaly webpages that are in
/src/main/webapp/
You have to move all your templates from /src/main/resources/templates to this directory.
Also you have to change the spring boot property on application.properties file:
spring.thymeleaf.prefix=templates/
That works for me
I had this same issue on Netbeans 8.0.2 and Windows. I was building a WAR to be deployed to Tomcat, but I wanted to try out Spring Boot. It looks like newer versions of Netbeans might resolve this with the Spring Boot plugin or using Eclipse. It seemed nutty to swap IDEs over something tiny like this. I tried all of the suggestions I could find; spring loaded, caching properties, extending the TemplateResolver...I couldn't get any of them to work. I finally stumbled on this blog and following these instructions solved my issue.

Spring Boot + Jetty & hot deployment

I've read the Hot swapping in Spring Boot but didn't find something that will help my case.
I have a spring-boot app on embedded jetty servers using thymeleaf. My app will serve html,css,js(AngularJS) and REST services.
Folder structure is like this:
/java
----
/resources
/static
/js
/css
/templates (html)
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
But css/html/js is not hot deployed when I change them. I have to restart server every time.
+bonus = when page loads it locks resources (js) and even Ant script cannot replace them.
Can I set scanIntervalSeconds anywhere?
--EDIT--
Main.java
#Configuration
#ComponentScan
#EnableJpaRepositories
#EnableAutoConfiguration
#Import({RepositoryRestMvcConfiguration.class, PersistenceConfig.class, ThymeleafConfig.class})
public class Main {
public static void main(String[] args) throws Exception {
SpringApplication.run(Main.class, args);
}
}
I've run it by right click on class and Debug in IDEA.
How are you launching the app? If you use an IDE with debug mode it should work (except for the locking problem which I believe is Windows OS), or if you launch it with "mvn spring-boot:run", or "gradle bootRun".
I develop using NetBeans 8.0.1.
I fixed the issue of not reloaded static resources in src/main/resources like css (in src/main/resources/resources/css (yes, really twice "resources"!), html-thymeleaf-templates (in src/main/resources/templates) the following way:
My Spring Boot webapp is a JAR project (pom.xml)
Add src/main/resources/application.properties:
spring.template.cache=false
spring.thymeleaf.cache=false
Added custom maven build: Project - Properties - Custom... - Goals...
Execute Goals: spring-boot:run
Set Properties:
jpda.listen=maven (to run it in debug mode)
Env.spring.profiles.active=DEV (optional, but I need it for different SpringConfig-....properties in development, production,...)
Just run the custom maven build for starting the webapp in debug mode. Changes in Thymeleaf-Templates (that are in src/main/resources/templates, eg. index.html (not .xhtml!)) are visible immediately on browser reload.
if you move the css and java script to a folder under
src/main/java/webapp it should work.
for some reason resources under src/main/java/resources didnt seem to get hot deployed when changed.
to fix this as the above post suggested I added
spring.template.cache=false
spring.thymeleaf.cache=false
to Application.properties inside the resources folder.
Note:
I also added this
-javaagent:springloaded-1.2.0.RELEASE.jar -noverify
as a vm runtime argument.

Resources