Thymeleaf: can't load js and css when direct access the page - spring-boot

Updated: to describe the question more clearly
I create a web applicaiton with spring boot and thymeleaf, everything works fine if I open the login page, then login, then head for the management module or reports module sequently.
The proleam occurs when I type the url locahost:8080/send/kf/index(needs to authenticate, but I have open access to all in customized filter) in the browser, the page loads without js and css. In debug mode, I saw /send/kf was unexpectly put into the path like the following. I can get the resource if I access localhost:8080/assets/avatars/avatar.png.
The following is the folder structure I put my static resources. How could /send/kf automatically added into the url, please help me solve this problem. Thanks!

you can use spring.resources.static-locations in your application.properties file
spring.resources.static-locations=classpath:/resources/css/
spring.mvc.static-path-pattern=/resources/**
this is taken form documentation
Note:Static resources, like JavaScript or CSS, can easily be served from your Spring Boot application just be dropping them into the right place in the source code. By default Spring Boot serves static content from resources in the classpath at "/static" (or "/public")

Using /assets/ instead of assets/ fixes the issue, as otherwise it's a relative url that's supposed to get added to the end of existing url.

I find a solution for this question. I don't know how /send/kf is put into the url for the static resources, but I think if I put the controller mapping under the root path, this problem should avoid. As I think, the url is correct and resources can load successfully.
#Controller
public class ManualMessageController {
#Autowired
private MsgTemplateRepository msgTemplateRepository;
#RequestMapping("/manualMsg")
public String manualMsg(Model model){
model.addAttribute("msgTemplateList", msgTemplateRepository.findByStatus(1));
return "manualMessage";
}
}
updated:
The right solution is to use absolute path rather than relative path in the project. So change assets/css to /assets/css works.

Related

Spring Boot - How to add custom controller logic before user accesses static files

I'm working on a Spring Boot project, where some static contents are served from the src/main/resources/static directory.
My goal is that whenever a user tries to access static contents that end with a certain suffix (e.g. ".xlsx"), the request is intercepted and I check to see if the user has the right permission using Spring AOP, and reject the request if necessary. I've got the AOP part working in other scenarios, but not in this scenario yet.
Currently I've tried something like the following, but the method isn't being invoked upon accessing a file of ".xlsx" suffix:
#RequestMapping("/*.xlsx")
public void checkPermission() {
}
Can this be done without using Spring Security? Thanks in advance.
Have you tried Filter interface? much more available.
LINK: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/filter/OncePerRequestFilter.html
Using this you can easily parse the request before even it reaches the controller and add you business logic/validation to it.

How does spring resolve .jsp page without controller mapping

I'm trying to understand the following issue. When I type url http://localhost:8076/demoproject_war/test.jsp spring is able to load test.jsp page. Here is the pic of my directory structure.
My question is how spring loads ./test.jsp even though I don't have any mappings in my controller class for ./test.jsp . Does not this request go to controller to check the mappings?
Spring does not load this JSP when you go to that URL. You're navigating directly to the JSP. It is considered a bad practice as you're not controlling the execution in this case. You should put the JSPs inside a webapp/WEB-INF directory. Then, the won't be accessible directly.

Thymeleaf +Spring Boot can't find files (FileNotFoundException)

This is a bit of a silly and frustrating one:
The #Configuration is taken from a tutorial website or forum and in it a
ServletContextTemplateResolver thymeleafTemplateResolver
is created using the ServletContext provided by spring boot.
When requested, a FileNotFoundException is thrown, despite the file being in the configured resources folder.
How do I get it to find the file / load it from the resources?
For thymeleaf to resolve the classpath resources, you need to configure a ClassLoaderTemplateResolver. (You were using a ServletContextTemplateResolver)
Also check that setPrefix is set to the correct folder, eg. "/thymeleaf/" if your documents are in resources/thymeleaf/ and that setSuffix is set to ".html" (or whatever your preferred file suffix is)
To also serve static content, you can extend WebMvcConfigurer and override addResourceHandlers, to then do e.g.
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
assuming a static folder in your resources.
(Spring controllers take precedence here)

Spring Web Flux cannot resolve path to static content

I am using Spring Boot 2.0.0 M1 with WebFlux to build my sample web application. After succeeding with REST endpoints I've decided to add some views to my application. I've decided to use Thymeleaf 3.x version. I know that Spring serves static content from 4 default location:
/META-INF/resources/
/resources/
/static/
/public/
I've decided to go with second example so my css file is in /resources/static/css/. However after loading my page .css file was not found.
This is a screenshot from my IDE:
I am not providing my own configuration for static directory I just want to use default one. What might be important is the fact that templates are loading just fine from the /resources/templates/ directory.
Css file is loaded like this:
<link data-th-href="#{css/bootstrap.min.css}" rel="stylesheet">
App is not using normal Controller class instead I've provided function as a Bean to define my router:
#Bean
RouterFunction<?> router(final GeneratorHandler generatorHandler) {
return route(GET("/generate"), handler::render);
}
Any ideas what's wrong here?
I've found the right solution. In your RouterFunction you need to use:
return resources("/**", new ClassPathResource("/static/"))
This will set your static directory to:
:classpath/static

How to serve an html file with .html url extension using Spring

I'm trying to use the Application Security on Cloud provided by Bluemix for a Spring application.
I'm relatively new to Spring and I'm having difficulty serving the requested verification file with the requested url. Bluemix wants the html file to be available at /IBMDomainVerification.html
However, I can't figure out how to serve the html file given that exact url using Spring. I can serve it without the .html at the end of the url but that's not what it needs.
If anyone can let me know how I can serve the html file given the specified url with the .html extension on the end that'd be great!
Thanks!
Spring 4.1 introduced the ResourceResolvers, that can resolve resources, given their URL path. In particular you could use the simplest: PathResourceResolver. This is the simplest resolver and its purpose is to find a resource given a public URL pattern. In fact, if no ResourceResolver is added to the ResourceChainRegistration, this is the default resolver.
Consider the following example:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("/resources/","/other-resources/")
.setCachePeriod(3600)
.resourceChain(true)
.addResolver(new PathResourceResolver());
}
The above code serves anything in either the webapp/resources of the webapp/other-resources folder, required with URLs /resources/** (e.g. /resources/foo.js). Note the two asterisks, it means that it will match everything after resources/, even '/'.
In your case using /IBMDomainVerification.html (/**) it should work.
An alternative way could be using *<mvc:resources/>* (Spring 3) which can be used to serve static resources while still using the DispatchServlet on root. Please refer to this SO answer.

Resources