Spring Boot Value annotation inside HandlerInterceptorAdaper - spring

I have a HandlerInterceptorAdapter like
#Component
public class TestInterceptor extends HandlerInterceptorAdapter{
#Value("${thing:defaultValue}")
private String thing;
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
// Do something with thing, but thing is null.
}
}
Is it not possible to get config values injected into this class? What's going on here? I would have expected it to at least have the default value but it has nothing.

You need to make sure that Spring is actually instantiating the Component :)
So, like
#Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
#Autowired
TestInterceptor test;
#Override
public void addInterceptors(InterceptorRegistry registry){
InterceptorRegistration testreg = registry.addInterceptor(test);
// ...
}
}
By Autowiring it in to the Configurer, it makes Spring aware of it.

Related

Custom web filter for specific controllers

Help me please, or show other ways to resolve this problem.
#RestController
#RequestMapping("/users")
public class UserController {
#RequestMapping("/login")
public String logIn() {
return "";
}
#RequestMapping("/getUserData")
#FilterThisRequest
public String getUserData(#PathVariable Long userId) {
return user;
}
}
And I have AuthFilter extends GenericFilterBean which makes a certain logic. How can I make that the filter execute only before methods which have #FilterThisRequest? Or there are better practices to resolve this problem?
Check FilterRegistrationBean reference guide at https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-embedded-container-servlets-filters-listeners-beans.
Make FilterRegistrationBean available to Spring via a #Configuration class, the below example will ensure that authFilter runs only for /getUserData. Note that it is URL (and not method) based filtering.
#Autowired AuthFilter authfilter;
....
....
#Bean
public FilterRegistrationBean authFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean(authfilter);
registration.addUrlPatterns("/web-app-name/getUserData/");
return registration;
}
I would suggest you for the Interceptor.
#Configuration
public class Config extends WebMvcConfigurerAdapter {
#Autowired
RequestInterceptor requestInterceptor;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(requestInterceptor).addPathPatterns("/getUserData","/user");
}
}
Interceptor -
#Component
public class RequestInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object object) throws Exception {
}
You can override Interceptor's prehandle and postHandle according to your need.

SpringMVC Invoking a global method

I am a beginner in springMVC so take it easy on me guys...i am trying to invoke a method every time a user enters my web application regardless of the page/place.
I tried ContextRefreshedEvent but it only works when the application starts.
Is there any way to achieve this ?
Example would be
public class MyInterceptoor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
}
}
It is required to wire interceptor in your config.
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/myproject/**"/>
<bean class="com.mvc.myproject.MyInterceptoor" />
</mvc:interceptor>
</mvc:interceptors>
Spring Documentation HandlerInterceptorAdapter
You can use Spring Interceptor – HandlerInterceptor.
http://www.journaldev.com/2676/spring-mvc-interceptor-example-handlerinterceptor-handlerinterceptoradapter
For SpringBoot you can do this. Make a HandlerInterceptorAdaptor
#Component
public class AccessInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
System.out.println("preHandled for controller = " + handler);
return true;
}
}
Add it to a Spring WebMvcConfiguration class:
#Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
#Autowired
AccessInterceptor accessInterceptor;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(accessInterceptor).addPathPatterns("/**");
}
}
Enjoy ...

Spring requests preprocessing per session

I'd like create Spring request Interceptor which will be able to get some data from session and change some #Autowired components before request.
I can create Interceptor and register it, but it can't get access to session beans:
#Component
#Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class TokenInterceptor extends HandlerInterceptorAdapter {
#Autowired
private MyServicePerSession myServicePerSession;
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println(myServicePerSession.getName()); // NullPointerException!!!
return true;
}
}
Above in the method preHandle(...) per each request I get NullPointerException.
Here is my config:
#Configuration
#EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {
//...
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TokenInterceptor());
}
}
How I said everything work fine except injecting MyServicePerSession.
I will really appreciate if you can give me advice about it, or some other ways to solve that problem.
You are trying to set a new object but you have to set a spring bean.
new TokenInterceptor() // is not spring bean
#Autowired private TokenInterceptor tokenInterceptor;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(tokenInterceptor);
// You have to set bean here
}
If this doesn't work, you can check this http://docs.spring.io/spring-javaconfig/docs/1.0.0.M4/reference/html/ch04s02.html

How can I access Spring ConfigurationProperties inside a custom JsonDeserializer?

I have a custom Json Deserializer that I am trying to Autowire ConfigurationProperties into. However, the property is always null. I tried using the SpringBeanAutowiringSupport but for some reason the CurrentWebApplicationContext is null.
How can I get the #Autowired to work in my custom deserializer?
Update:
I am using #JsonDeserialize(using = Deserializer.class) on my domain class, which is be utilized through a RestTemplate call in a service class.
I am using Spring Boot 1.4.
HealthDeserializer
public class HealthDeserializer extends JsonDeserializer<Health> {
#Autowired
private HealthMappings mappings;
#Override
public Health deserialize(JsonParser jp, DeserializationContext ctx) throws IOException, JsonProcessingException {
mappings.lookup(...);
}
}
HealthMappings
#Component
#ConfigurationProperties(prefix="health_mapping")
public class HealthMappings {
...
}

How do I autowire dependencies into Spring #Configuration instances?

I need to inject an object into my No XML Spring #Configuration object as follows:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "web.client")
public class WebApplicationConfiguration extends WebMvcConfigurerAdapter {
private static final Logger log = LoggerFactory.getLogger(WebApplicationConfiguration.class);
#Inject
private MonitoringExceptionResolver resolver; // always null
#Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
log.debug("configuring exception resolvers");
super.configureHandlerExceptionResolvers(exceptionResolvers);
exceptionResolvers.add(new DefaultHandlerExceptionResolver());
exceptionResolvers.add(new AnnotationMethodHandlerExceptionResolver());
exceptionResolvers.add(new ResponseStatusExceptionResolver());
exceptionResolvers.add(resolver); // passing null ref here
}
}
Where MonitoringExceptionResolver is defined as follows:
#Service
public class MonitoringExceptionResolver implements HandlerExceptionResolver {
private final Counters counters;
#Inject
public MonitoringExceptionResolver(Counters counters) {
super();
this.counters = counters;
}
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
Counter counter = counters.getCounterFor(ex.getClass());
if(counter != null) {
counter.increment();
}
return null;
}
}
However, I get NPE later in the execution chain because the "resolver" field above is null, even if I use #Autowired.
Other classes are being successfully wired in elsewhere using component scanning. Why is it always null in the above? Am I doing something wrong?
#Inject and #Autowired should work very similar in Spring.
Make sure that *BeanPostProcessor in use is aware of MonitoringExceptionResolver: mark it as #Component and make is subject of some #ComponentScan or make a #Bean factory method is some #Configuration class in use.

Resources