Spring 4 Annotation based equivalent of static resource mapping - spring

I just converted an XML configured Spring MVC project to being annotation based but I cannot seem to figure out what annotation to use (and where to place it) for static resource mappings. The mappings in my project's older XML based configuration were:
<mvc:resources mapping = "/css/**" location = "/css/"/>
<mvc:resources mapping = "/images/**" location = "/images/"/>
<mvc:resources mapping = "/*.html" location = "/"/>
Any help appreciated.

#Configuration
#EnableWebMvc
public class WebAppConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
}
}

Related

Does a Spring Boot Project that runs as a Jar needs a web.xml file?

As the title states.
I am migrating a Spring-MVC application that uses XML based Configuration.
I don't know where to move the filters located in the web.xml file to the new Spring Boot Project.
You can make use of the annotation : #ImportResource for this
Find more details here
You can define your filters using Java Configurations when using Spring Boot.
As mentioned in the documentation, you only need to declare that filter as a Bean in a configuration class.
#Configuration
public class WebConfig {
#Bean
public Filter someFilter() {
return new someFilter();
}
}
If for some reason "SomeFilter" is not a spring managed bean, or if you need to customize the filter behaviour, then you can register the filter using FilterRegistrationBean as follows
#Configuration
public class WebConfig {
#Bean
public Filter someFilter() {
return new someFilter();
}
#Bean
public FilterRegistrationBean someFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(someFilter());
return registration;
}
}
In case of multiple Filters you can specify the order using FilterRegistrationBean.setOrder() as mentioned in the doc
Finally I registered my Interceptors using Java Configuration (no xml) this way.
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
#Autowired
ControllerInterceptor controllerInterceptor;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(this.controllerInterceptor).addPathPatterns(this.buildPaths());
}
private String[] buildPaths() {
String paths[] = { "/api/example1/**", "/api/example2/**" };
return paths;
}
}

How to Configure Servlet Mapping and Resource Handler in Spring MVC

I have created sample Spring MVC REST Maven project with following folder structure
ResourceHandlerRegistry configuration as follows
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.raju.spring_app")
public class RootConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static_res/*").addResourceLocations("/WEB-INF/html/static_res/");
}
//Other methods
}
Servlet mapping as follows
public class HelloWorldInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected String[] getServletMappings() {
return new String[] { "/", "/static_res/*" };
}
//Other Methods
}
The problem is whenever I tried to access resource
http://localhost:8080/spring4_rest_angular_demo/static/css/app.css
I got 404 error.
I want to keep this folder structure to get css IntelliSense suggestions
in index.jsp file.
<link href="static_res/css/app.css" rel="stylesheet"></link>
Few corrections :
Replace
return new String[] { "/", "/static_res/*" };
with
return new String[] { "/" };
and
registry.addResourceHandler("/static_res/*")
with
registry.addResourceHandler("/static_res/**")
Also, the right path is
http://localhost:8080/spring4_rest_angular_demo/static_res/css/app.css
and not
http://localhost:8080/spring4_rest_angular_demo/static/css/app.css
With Spring 3.0.4.RELEASE and higher you can use
<mvc:resources mapping="/resources/**" location="/public-resources/"/>
As seen in http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-static-resources
Also, you should avoid putting pages in WEB-INF. Put the folder with html/css/js higher in hierarchy, under the web app folder. Generally, in WEB-INF there should be only configuration xml files.

Spring MVC HandlerInterceptor ignored in Java config

I'm trying to convert a Spring project from XML to Java config and have run into the following issue with HandlerInterceptors:
XML Config (works):
<mvc:annotation-driven />
<mvc:interceptors>
<bean class="com.mycompany.MyHandlerInterceptor" />
</mvc:interceptors>
Java Config (interceptor is never called)
#Configuration
public class MvcConfig extends WebMvcConfigurationSupport {
#Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyHandlerInterceptor());
}
// ...
}
According to the documentation, these two configurations should be equivalent, however in the Java config example the neither the pre or post handle methods are ever called?
What am I missing?
Thanks.
This was my own fault. I had overridden requestMappingHandlerMapping() in my MVC Java config and did not set the interceptors property on the custom HandlerMapping class.
#Bean
#Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
CustomRequestHandlerMapping handlerMapping = new CustomRequestHandlerMapping();
handlerMapping.setOrder(0);
handlerMapping.setInterceptors(getInterceptors()); // <-- This was missing
return handlerMapping;
}

How to add implemetation of RequestDataValueProcessor using code and not as xml configuration

I have a bean like follows
<bean name="requestDataValueProcessor" class="com.bom.DOMRequestDataValueProcessor"/>
DOMRequestDataValueProcessor implements the RequestDataValueProcessor.
I am doing my mvc configuration using the following class and not by xml configuration file.
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
}
How can i add the above bean in the configuration ?
From Pro Spring Mvc book:
To config a RequestDataValueProcessor, we need to add it to the
application context and then register it with the name,
requestDataValueProcessor. This is the name the framework uses to
detect the registered instance.
So you probably need to do something like:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"com.bom"})
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public RequestDataValueProcessor
requestDataValueProcessor() {
return new DOMRequestDataValueProcessor();
}
}
you should enable the components scanning. See Spring doc : http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-java
<beans>
<context:component-scan base-package="com.acme"/>
</beans>
#Bean(name = { "requestDataValueProcessor" })
public DOMRequestDataValueProcessor getRequestDataValueProcessor() {
final DOMRequestDataValueProcessor domRequestDataValueProcessor = new DOMRequestDataValueProcessor();
return domRequestDataValueProcessor;
}

How to override ResourceHttpRequestHandler to implement a customized resource handler?

When I use spring mvc, I use <mvc:resources /> to map the location of the static resources to handler, and now I want to add some new functions to handler resource, is there anyone who can tell me how to override the ResourceHttpRequestHandler?
(Based on the following doc, the <mvc:resources /> use ResourceHttpRequestHandler to handle resources.)
Thanks in advance!
I haven't tried this but you could try extending the ResourceHttpRequestHandler and use a BeanFactoryPostProcessor to replace ResourceHttpRequestHandler class with your custom class . A similar solution is given here
Sample...
public class ResourceHttpRequestHandlerReplacer implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory factory)
throws BeansException {
String[] names = factory.getBeanNamesForType(ResourceHttpRequestHandler.class);
for (String name: names) {
BeanDefinition bd = factory.getBeanDefinition(name);
bd.setBeanClassName("org.myProject.CustomResourceHttpRequestHandler");
}
}
}

Resources