Spring Boot: Adding static resources from file system breaks existing mappings - spring

I have a Spring Boot MVC application in which I am trying to load resources from an external folder on the file system. I have used the following to configure this:
#Configuration
#EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/where/**")
.addResourceLocations("file:///C:/some/where/");
}
...
}
Once I configure this, I can access my static files by going to http://serverurl/where/somefile
BUT, I am no longer able to access the home page at http://serverurl/
Any idea what I did wrong here?

Related

Component inside auto configuration application not getting registered

I have created a simple spring boot starter configuration.
Along with other files I have Interceptor which should auto-register.
My Configuration is registered in the file is as follow:
/resource/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports=DynamicDataSourceAutoConfiguration
Autoconfiguration kicks in but the components inside this are not initialized.
My default component inside auto configuration is as follow;
#Component
public class AppWebMvcConfigurer implements WebMvcConfigurer {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CommonHeadersInterceptor());
}
}
This starter I am using in multiple micro-service.
Since it is not registered automatically. I have to re-create this AppWebMvcConfigurer file in each of my micro-services.
Please help me if there is some other configuration I need to do for AutoConfiguration to kick in.
FYI: Other files include
Properties
Configuration
DataSources
EDIT:1
I created config file and added the same path in .imports file metioned above. For time being this seems solved.
#Configuration
public class HeaderTenantMvcConfiguration {
#Bean
public AppWebMvcConfigurer webMvcConfigurer() {
return new AppWebMvcConfigurer();
}
}
My org.springframework.boot.autoconfigure.AutoConfiguration.imports now looks something like this:
com.silentsudo.data.DataSourceAutoConfig
com.silentsudo.web.mvc.AppWebMvcConfigurer

How to serve static resources in Spring boot with #EnableWebMvc

Cracking head over this. The documentation says:
By default Spring Boot will serve static content from a directory called /static (or /public or /resources or /META-INF/resources) in the classpath or from the root of the ServletContext.
Minimal example:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#SpringBootApplication
#EnableWebMvc
public class Main {
public static void main(final String[] args) {
SpringApplication.run(Main.class, args);
}
}
And create one directory /src/main/resources/public placing static resources there. When I run the application I only get 404. When I remove #EnableWebMvc resources are served as expected.
Attempted (and failed) remedies
/**
* #see org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter#addResourceHandlers(org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry)
*/
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/public/**").addResourceLocations("/public/");
}
In the application.properties added:
spring.mvc.static-path-pattern=/**
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
The question
So my question: What do I need to configure to serve static resource when I want to use the #EnableWebMvc annotation?
In the documentation you mentionned, it says :
If you want to take complete control of Spring MVC, you can add your
own #Configuration annotated with #EnableWebMvc.
You should try to use #EnableWebMvc with your configuration instead of your Spring boot application.
There's an example of this in this documentation.
Enabling the MVC Java Config or the MVC XML Namespace
To enable MVC Java config add the annotation #EnableWebMvc to one of
your #Configuration classes:
#Configuration
#EnableWebMvc
public class WebConfig {
}
Also in these examples :
Customizing the Provided Configuration
Conversion and Formatting
I hope this will help you.
You should configure a ViewResolver something like below along with your ResourceHandlers. Check this
#Bean
public InternalResourceViewResolver defaultViewResolver() {
return new InternalResourceViewResolver();
}

Spring Boot with Custom Converters breaks Swagger & how to move it

I have a very simple Spring Boot application. I launch this through the basic SpringApplication.run(Startup.class, args); and have a custom #Configuration class in there that overrides the default converters. I decided to add Swagger to the mix of things so that I can generate better documentation for our internal user base as there are gads of endpoints.
When I started things up, Swagger simply wouldn't work.
I decided to start a front-scratch Spring Boot with just one endpoint to document to see what went wrong. Out-of-the box this worked perfectly fine and I was able to get Swagger running via just hitting the http://localhost:8080/swagger-ui.html base URL.
When I implemented my custom #Configuration class that extended WebMvcConfigurationSupport, Swagger no longer worked.
My configuration overrode a single method:
#Configuration
public class StartupConfiguration extends WebMvcConfigurationSupport {
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(getJsonConverter());
}
}
That's it. I decided to add the default converters as well without any luck. Then I just emptied the class and left it as:
#Configuration
public class StartupConfiguration extends WebMvcConfigurationSupport {
}
Swagger is still broken - if I remove the class completely, then it works.
What can I do to keep my custom configuration data and run Swagger? I would also love to move it to something like http://localhost:8080/swagger/ rather than the default file it uses, but that is a completely separate issue for now.
My launch of Swagger looks like this:
#Configuration
#EnableSwagger2
public class SwaggerConfiguration {
#Bean
public Docket getDocket() {
// ...
return new Docket(DocumentationType.SWAGGER_2)
.groupName("Core API")
.apiInfo(infoBuilder.build())
.select().paths(PathSelectors.regex("/*"))
.build();
}
}
Overriding the default resource handler worked for me. I added the following to the configuration class extending WebMvcConfigurationSupport:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}

META-INF/resources not works properly with #EnableWebMVC in Spring Boot

1.
I'm working with Spring Boot. My Main class very simple
#ComponentScan
#EnableAutoConfiguration
#Configuration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
#2. Now I would like to make my static content externalised into a jar file. So, below is the jar project
/pom.xml
/src/main/resources/META-INF/resources/hello.json // here is my resource
I do maven install and put the dependency into the main app, run the app normally. Now I can invoke http://localhost:8080/hello.json to get my hello.json file
#3. Then, the next step is using the Apache Tiles for my main web project, so I create a #EnableWebMvc class to configure the tilesViewResolver
#Configuration
#EnableWebMvc
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
public #Bean TilesViewResolver tilesViewResolver() {
return new TilesViewResolver();
}
public #Bean TilesConfigurer tilesConfigurer() {
TilesConfigurer ret = new TilesConfigurer();
ret.setDefinitions(new String[] { "classpath:tiles.xml" });
return ret;
}
}
Then I started again the application and try the hello.json to ensure everything still works properly. But, the 404 page appear. Delete the WebMvcConfiguration give back my hello.json.
What configuration I should do to resolve this issue?
Thanks a lot.
In Spring MVC, using XML configuration, you have to have a tag like the following to service static content:
<mvc:resources mapping="/js/**" location="/js/"/>
This insinuates that Spring Boot is doing something to automatically guess that you have static content and properly setup the above example in META-INF/resources. It's not really "magic", but rather that they have a default Java Configuration using #EnableWebMvc that has some pretty reliable default values.
When you provide your own #EnableWebMvc, my guess is you are over-writting their "default" one. In order to add back a resource handler, you would do something like this:
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/js/**").addResourceLocations("/js/").setCachePeriod(31556926);
}
This is equivalent to the XML above.

Spring boot for Spring mvc and Angular JS not refreshing static resources

I am running Spring boot in IntelliJ idea and have found that spring boot is no longer refreshing my changes to the resources which is where i have the html and js files. It was working fine but now only seems to detect changes on system reboot.
Is there a way to prevent caching of files ?
let assume you cached the required files like below code :
#SpringBootApplication
public class App extends SpringBootServletInitializer {
#Bean
public WebMvcConfigurerAdapter webConfigurer () {
return new WebMvcConfigurerAdapter() {
#Override
public void addResourceHandlers (ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/js/**")
.addResourceLocations("/static/js/")
.setCacheControl(CacheControl.maxAge(300, TimeUnit.DAYS));
registry.addResourceHandler("/static/images/**")
.addResourceLocations("/static/images/")
.setCacheControl(CacheControl.maxAge(7, TimeUnit.DAYS));
registry.addResourceHandler("/static/css/**")
.addResourceLocations("/static/css/")
.setCacheControl(CacheControl.maxAge(300, TimeUnit.DAYS));
}
};
}
}
add new folder like "nonCached" folder and include your non Cached files like below :

Resources