Spring 5 add static file directory webapp - java

I have a Spring 5 (not Spring Boot) web application. I have one controller that outputs html. I output a string which is HTML and it works, however the relative paths the JS content do not work. I will layout my structure as follows:
src
main
java
resources
webapp
css
js
img
WEB-INF
index.html
test
java
resources
When I output my html text, all the relative locations cannot be found:
if I call:
http://localhost:8080/myapp/controller?{some parameters}
I would expect
http://localhost:8080/myapp/js/myjsfile.js
would be there. When I build and deploy the WAR, the exploded WAR file has all the right code. So I would expect the file to be there and found. However, I expect from what I've been reading that static files can be served out differently. So, I have two questions:
1) What is the standard way of serving static files from a Spring 5 web application? Do I change the structure this way:
src
main
java
resources
static
css
js
img
webapp
WEB-INF
index.html
test
java
resources
And then I am presuming I have to do the webconfig as such:
#Configuration
#EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/resources/**")
.addResourceLocations("static/js", "static/css", "static/img")
.setCachePeriod(31556926);
}
}
2) OR, can I use the existing structure and then change the WebConfig to add those static locations as follows:
#Configuration
#EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/webapp/**")
.addResourceLocations("/js", "css", "img")
.setCachePeriod(31556926);
}
}
But if putting these files under webapp doesn't work, I can understand moving them to /resources if that is the standard way of doing thing.
So, if I could get any help with this, that will be fine. I am fine with either way as long as it works. Thanks!

Try to use the resources/static folder to provide your view files. And add the following configuration to your WebMvcConfigurer:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
}
It will map all static files requested in the "/" URL to redirect to resources/static folder.

Option 1 is the way to go, place your folder under resources directory (name it as you wish):
src/main/java/resources
myStaticResourcesFolder
css
js
img
Then just do this:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**") // map to whatever url you need
.addResourceLocations("myStaticResourcesFolder/"); //
}

Related

How serve web-folder in Spring Boot out from /resources/

I need help, my Spring Boot 2 Server from a first web generate other web site (folder with html,css ext ext) from a template, but these web sites/html aren't accessible, Spring give me error 404, not found.
I will build the project with Maven in .jar
The gerarchy of the project is this:
---
|_folder (Directory with webapps generated, NOT DELIVERED)
. |_webapp1
. |_webapp2
|_src
. |_main
. . |_java
. . |_resources
. . . |_public (With first web)
. . . |_static (Template used to generate other web site, i simply copy this directoy in other directory, doing templateServices.copyDirectory("target/classes/static/", "folder/webapp1");
---
I tried with this configuration, but dont work.
#Configuration
#EnableWebMvc
public class StaticResourceConfiguration implements WebMvcConfigurer {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/", FileController.uploadingDir};
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
}
}
If the web server is going to generate websites, as you said, then you should save the files outside the Spring Boot scope; just in a folder of your filesystem. An example could be:
#Configuration
#EnableWebMvc
public class AppConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/**")
.addResourceLocations("file:/var/www/websites/");
}
}
If you have dynamic websites (you said it depends on the users) you can inside the method get all users in the system, and add ResourceHandlers for them in specific locations.

Return HTML page from Spring controller

I have a Spring Boot app setup as a REST api. I now also want to be able to serve simple HTML pages to the client, without the use on any template engine like Thymeleaf. I want access to the HTML pages to fall under the same security constraints setup by Spring Security with the use of WebSecurityConfigurerAdapter, already present in my app.
What I've tried is having a Controller:
#Controller
public class HtmlPageController {
#RequestMapping(value = "/some/path/test", method = RequestMethod.GET)
public String getTestPage() {
return "test.html";
}
}
and placing the test.html file in /resources/test.html or /webapp/WEB-INF/test.html.
Every time I try to access the page at localhost:8080/some/path/test a 404 is returned.
How do I make this work?
Okey so apparently Spring Boot supports this without any additional configuration or controllers.
All I had to do was to place the HTML file in the correct directory /resources/static/some/path/test.html and it can be reached at localhost:8080/some/path/test.html.
In my attempts to change the directory from which the file is served I was unsuccessful. It seems that providing a separate #EnableWebMvc (needed for configuring the resource handlers) breaks the Spring Boot configuration. But I can live with using the default /static directory.
There is a Spring MVC mecanism that exists to provide static resources.
In the config class, overide this method :
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("some/path/*.html")
.addResourceLocations("/static/");
}
And place your html files in the src/main/webapp/static/ folder.
If you request some/path/test.html (note the .html), it will return the test.html file located in static folder.
You can obviously use a different folder or a more sofiticated directory structure.
This way you don't have to create a controller. Note that your config class should implements WebMvcConfigurer.
Your html, js and css files should be under the src/main/resources/static directory. and your return statement you can try removing .html.
#RestController
public class HtmlPageController {
#GetMapping("/some/path/test")
public String getTestPage() {
return "test";
}
}
See tutotrial example how to define html view in Spring MVC configuration
#Bean
public InternalResourceViewResolver htmlViewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setPrefix("/WEB-INF/html/");
bean.setSuffix(".html");
bean.setOrder(2);
return bean;
}
setOrder is set to 2 because it include also JSP support in example
Also you need to change to return without .html suffix
return "test.html";

Spring Boot static resources are not available

Files in resources/static are not available. How I can fix it?
Hierarchy:
resources/
db/
static/
image.png
templates/
application.properties
But if I open localhost:8081/image.png I get error.
My WebConfig:
#Configuration
#EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("/webjars/");
}
}
You should add below line to your existing resource mapping:
registry.addResourceHandler("/**")
.addResourceLocations("resources/static/");
You have configured the webjars resourceHandler to serve client side script or stylesheet dependencies. but custom handler is not added to serve your image file.
Since you are overriding the addResourceHandlers (ResourceHandlerRegistry registry) method, you should provide all the resourceLocation and handler mapping in your implementation.
Please check serving-static-web-content-with-spring-boot article to have more clear idea.
Note:
If you are using spring-boot you shouldn't be overriding the above method untill explicitly required as its already taken care in WebMvcAutoConfiguration.java.
Please check below default implementation:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache()
.getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry
.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod))
.setCacheControl(cacheControl));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(
registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(
this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod))
.setCacheControl(cacheControl));
}
}
Here give path of your image:
registry.addResourceHandler("/**").addResourceLocations("file:/path/to/your/image/");
If you would prefer to serve static content (including web pages, js, pdf, css, pdf, doc etc.) from outside of the WAR, may be that is usefull. if you wanna changed any that static contents, just you can put changed file to your content path on application server easly and serving that without deploying or restarting you application server. If you prefer this way, you can do it with a small configuration on your application server.

Spring (with Jade) Resources

The Problem
My spring-boot application recently changed routing from host/endpoint to host/middle/endpoint. Since the change, I am running into an issue where the resources are not being found relative to the new url structure. Before, I could reference resources like css stylesheets like link(rel='stylesheet', href='css/style.css'), but now the logger shows an error saying it can't find the resource at /middleman/css/style.css.
From my research, I have found that what I need to do is use a resource handler registry. I have created one (as shown below) but it doesn't seem to be working. I think the problem is that even though I now have the resource registry, I am not referencing resources in the registry. What is the proper way to solve this problem and have all resources point load from the same place regardless of the endpoint? I very well may be missing some obvious piece of SOP
Note: This is all a dumbed down representation of my project in order to give the idea of what is going on without giving unnecessary information.
Project Structure
src
main
java
com.mystuff.cool
configurations
ResourceConfiguration.java
controllers
RoutingController.java
application
Application.java
resources
static
css
footer.css
style.css
images
place1.png
location1.png
spot1.png
favicon.ico
javascripts
layout.js
templates
home.jade
Application Class
#ComponentScan(basePackages = {"my.packages"})
#EnableAutoConfiguration
#EnableSAMLSSO
#Configuration
public class Application
{
public static void main(String[] args)
{
SpringApplication.run(new Object[]{ Application.class, ServiceConfig.class, ResourceConfiguration.class}, args);
}
}
Resource Configuration
#EnableWebMvc
#Configuration
public class ResourceConfiguration extends WebMvcConfigurerAdapter
{
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/css/**").addResourceLocations("/css/").setCachePeriod(31556926);
registry.addResourceHandler("/img/**").addResourceLocations("/img/").setCachePeriod(31556926);
registry.addResourceHandler("/js/**").addResourceLocations("/js/").setCachePeriod(31556926);
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
{
configurer.enable();
}
}
Controller
#Controller
public class RoutingController
{
#RequestMapping("/house/home")
public String home(Model model)
{
model.addAttribute("title", "Home is where the heart is");
commonModelTribs(model);
return "home";
}
}
Home Page
doctype html
html
title Place-spedia #{title}
link(rel='icon', href='images/favicon.ico')
link(rel='stylesheet', href='css/style.css')
script(src='javascripts/layout.js')
link(rel='stylesheet', href='css/footer.css')
body
div#footer-icons
a(href='place1')
img#place1(src="images/place1.png")
a(href='location1')
img#location1(src="images/location1.png")
a(href='spot1')
img#spot1(src='images/spot1.png')
If you are using spring boot, you don't need to worry about the resource configuration since you are already configuring the resource directory through the auto configuration. The default behavior for the autoconfiguration is to look within resources/static.
Your issue is with your href values, try inserting a leading forward slash:
link(rel='icon', href='/images/favicon.ico')
link(rel='stylesheet', href='/css/style.css')
script(src='javascripts/layout.js')
link(rel='stylesheet', href='/css/footer.css')
Spring is routing your application to a new relative path, so by putting the leading / in your href attributes, you are telling the router to look absolutely within the static directory instead of relatively from the middle directory.

SpringBoot not automatically serving static files

I have SpringBoot 1.3.3 and a working Java API exposed on port 8080. However, along with this API I would like to expose an index.html file located directly under {projectName}/src/main/resources/, according to the Springboot documentation this should be served up automatically but when I navigate to http://localhost:8080/index.html I get a 404. I am not using #EnableWebMVC anywhere and have tried adding my own configuration file like below, however nothing has worked so I'm kind of at a loss. Any help would be much appreciated!
#Configuration
#EnableWebMvc
#ComponentScan
public class ServerConfiguration extends WebMvcAutoConfiguration {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/" };
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
}
}
Put the files in /src/main/resources/public/

Categories