Spring MVC Cannot configure views' path - spring

I have a project that uses Spring Boot 2.2.5 (Spring version 5) - here is a link to a bare minimum project demonstrating my problem. In all the tutorials I followed they claim views' path can either be configured inside application.properties like this:
spring.mvc.view.prefix=/WEB-INF/jsp
spring.mvc.view.suffix=.jsp
or inside WebMvcConfigurationSupport derived class like this:
#Override
public void configureViewResolvers(final ViewResolverRegistry registry) {
registry.jsp("classpath:/", ".jsp");
}
or like this:
#Override
public void configureViewResolvers(final ViewResolverRegistry registry) {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
registry.viewResolver(resolver);
}
None of which work in my case. Spring will always serve .jsp files from src/main/webapp and from nowhere else in spite of my configuration or lack of it. No other file types will be served from that directory, not even HTML.
Some tutorials claim that when not configured Spring will serve anywhere from
src/main/resources/static
src/main/resources/public
src/main/resources/resources
src/main/java/META-INF/resources
I am yet to see this.
CSS and Javascript files will be served from src/main/resources but only if I have this in my MVC configuration:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/");
}
Configuring this from application.properties doesn't work
spring.resources.static-locations=classpath:/
In relation to this are there other special folder names like classpath: that can be used? I tried webapp: but it doesn't seem to be expanded
UPDATE: I thought for a moment that maybe subclassing WebMvcConfigurationSupport is to blame since it acts like #EnableWebMvc. Subclassing WebMvcConfigurer brought the following error. Placing #EnableWebMvc solves it.
An attempt was made to call a method that does not exist. The attempt was made from the following location:
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration.requestMappingHandlerAdapter(WebMvcAutoConfiguration.java:369)
The following method did not exist:
'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration.requestMappingHandlerAdapter(org.springframework.web.accept.ContentNegotiationManager, org.springframework.format.support.FormattingConversionService, org.springframework.validation.Validator)'
I read somewhere that JSP view are not supported inside embedded servlets. What a nice feature! Anyway I don't thing this is related to my problem.
I would like to stick to JSP and avoid Thymeleaf as my project is based on React. I will create MVC pages in order to be Search engine friendly, though but I will figure this out along the way.
Here is a screenshot of my project's layout

Related

How to set default landing page in Spring Boot project

I have a Spring Boot project with webapp folder like:
webapp\
myapp\
api\
dashboard.xhtml
auth\
login.xhtml
register.xthml
When I run the sever I need to always enter the url http://localhost:8080/myapp/auth/login.xhtml to begin.
I found this very annoying and want to automatically redirect to this url when I enter just http://localhost:8080.
How can I achieve this?
You can make a new configuration inheriting the WebMvcConfigurer class.
In Spring Boot, the MVC part is measuring automatically, so you wouldn't do any more request controlling part in case you are new to it.
The WebMvcConfigurer class offers addViewControllers virtual function, so that you can override it and add your own controller inside it.
Just like:
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/")
.setViewName("forward:/helloworld.xhtml");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
For more detailed part, you can find it here.

Automatically finding Thymeleaf templates with Spring Boot

How can I get Spring Boot and Thymeleaf to automatically find and map template files to be processed when accessed by the browser?
src/main/resources/templates/index.xhtml
src/main/resources/templates/bar.xhtml
src/main/resources/application.properties contains spring.thymeleaf.suffix=.xhtml
FooController.java contains #RequestMapping("/foo") and a #PostMapping method that returns bar
If I enter http://localhost:8080/ in the browser, Thymeleaf processes and displays the index.xhtml page with no extra configuration needed. But http://localhost:8080/index, http://localhost:8080/index.xhtml, and http://localhost:8080/index.html all result in 404 Not Found.
My index view does a POST to foo; FooController is activated and returns bar; and Thymeleaf processes and shows bar.xhtml, even though bar.xhtml isn't mapped anywhere in the configuration. Yet accessing http://localhost:8080/bar, http://localhost:8080/bar.xhtml, and http://localhost:8080/bar.html in a browser all result in 404 Not Found.
Why does GET http://localhost:8080/ process the index.xhtml template, but GET http://localhost:8080/index does not?
How can Thymleaf use bar as a view, but I cannot access http://localhost:8080/bar directly?
How can I configure Thymeleaf so that I can add src/main/resources/templates/example.xhtml and have it processed automatically as a template that I can access via http://localhost:8080/example in the browser, with no explicit configuration specifically for the example.xhtml file?
If I absolutely have to configure controllers (see my answer below), is there a way that I can at least do this in some declarative file, outside of my code?
As noted in Spring in Action, Fifth Edition, I can do something like this in a #Configuration class that implements WebMvcConfigurer
#Override
public void addViewControllers(final ViewControllerRegistry registry) {
registry.addViewController("/bar");
}
That will allow me to process bar.xhtml automatically. (I presume there is some default configuration registry.addViewController("/").setViewName("index"), which is why my index.xhtml file is getting processed by accessing the root path.
And I can even use the following to automatically pick up any template:
#Override
public void addViewControllers(final ViewControllerRegistry registry) {
registry.addViewController("/**");
}
Unfortunately this removes the mapping from / to /index, and also prevents accessing any static resources from src/main/resources. I'm not sure how to tell Thymeleaf to use a template if it can, and fall back to a static file if not.

Spring MVC + Thymeleaf: not loading some resources

I am new to Thymeleaf and Spring MVC.
I have been dealing with the following problem: some resources (css or images) don't get loaded by my webpage while other do. They are in the same path and folder, the syntax is the same (i have checked by just switching the name of the resource and it worked).
For example, my Thymeleaf Template can find and read my own css files, but it won't read the bootstrap-4 one.
Here is my project structure:
And here an example of the code trying to read bootstrap.css:
The same problem happens with images of the same format.
Any ideas of what could be causing the issue?
Thank you in advance
You can register a resource handler by extending a WebMvcConfigurerAdapter.
Something like this.
#EnableWebMvc
#Configuration
public class SpringWebConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/styles/**").addResourceLocations("/styles/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/images/**").addResourceLocations("/images/");
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
Anyway, the css files should be in the css directory
Okay so I understood what the problem was: intelliJ.
It didn't see the new files added to the project.
Running mvn clean install fixed the problem

In spring-boot app, how to load static content (image for example) into jsp from local folder instead of resources folder?

I'm trying to load an image into jsp page from my local system folder which is on desktop. But in spring-boot, the image gets loaded only if it's put into resources folder. How to resolve this issue?
I already tried the below code from https://www.baeldung.com/spring-mvc-static-resources, but no luck.
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/files/**")
.addResourceLocations("file:/opt/files/");
}
I had error saying
javax.servlet.ServletException: Circular view path [error]: would dispatch back to the current handler URL [/error] again. Check your ViewResolver setup!
My folder set up is as follows:
Only the images in resources/static/img are getting loaded into jsp and I want the images present on the desktop to be loaded. Please help.
You need to configure little bit more. First resource handler then viewresolver
#Configuration
#EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/test/**")
.addResourceLocations("file:D://tmp2/");
}
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
this is a running example in win10 you need to change the path addResourceLocations accordingly. here you can find the project https://github.com/ozkanpakdil/spring-examples/tree/master/spring-boot-jsp dont forget to check out pom.xml. in order to run jsp in spring boot. Needed some extra provided dependency embeded jasper there.
I found a way to this. This can be done by using a property which goes into the application.properties file
spring.resources.static-locations=file:PATH OF THE FOLDER
For instance if the project folder is located on desktop then it will be something like this
spring.resources.static-locations=file:/Users/sandeepamarnath/Desktop/
In the HTML OR Jsp page, the complete path can be given to the static files like CSS,JS, and Images

Static resources arent loaded in thymeleaf template

I've gone ahead and tried almost any tutorial with the hopes it wouldfix this.
I'm new to spring boot.
So I have a spring boot web application setup, but css, jscript and any other static content won't be loaded in template. It's not a problem with the css or jscript as implementing them directly into the html file will make it work.
This (http://prntscr.com/lk6f6q) is how my project looks like. "test".js just includes a simple alert call.
Html: https://hastebin.com/ixejakiqev.xml
Pom: https://hastebin.com/vakinawuva.xml
What am I doing wrong? I'm trying to solve this since a week and nothing seems to work. Am I maybe missing a library?
Check the exact issue using network tab of the browser.
and also ensure that you have a class something like below to handle static resources.
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(
"/webjars/**",
"/img/**",
"/css/**",
"/js/**")
.addResourceLocations(
"classpath:/META-INF/resources/webjars/",
"classpath:/static/img/",
"classpath:/static/css/",
"classpath:/static/js/");
}
}
The security config did not allow unverified access to the static resources.

Resources