So basically question listed in title. Is there a way to populate org.springframework.ui.Model in preHandle method ?
public class SomeInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// need to populate Model here
return true;
}
}
Related
Im using graphql-java-kickstart/graphql-spring-boot and I'd like to create an interceptor to add an HTTP header after processing the request.
When I'm sending a graphql request to the backend the the interceptor is not triggered. But some calls trigger the interceptor. For example when I'm opening /graphiql in my browser I see that the interceptor is triggered but when I send a graphql request from graphiql client it is not. Any idea why? Anybody got experience with this?
My config looks like this:
#Configuration
public class InterceptorConfig implements WebMvcConfigurer {
#Autowired
private TestInterceptor testInterceptor;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(testInterceptor).addPathPatterns("/**");
}
}
Also my Interceptor:
#Slf4j
#Component
public class TestInterceptor extends HandlerInterceptorAdapter {
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
// post processing
log.info("hello there");
}
}
I have following interceptor that successfully works in my project:
My WebConfig:
#Configuration
public class WebConfig implements WebMvcConfigurer {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(requestInterceptor);
}
#Autowired
private ControllerExecInterceptor requestInterceptor;
}
Where ControllerExecInterceptor defined as:
#Component
public class ControllerExecInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws AccessDeniedException, Exception {
// ...
}
#Override
public boolean postHandle(HttpServletRequest request, HttpServletResponse
response, Object handler) throws {
// ...
}
}
I have an reactive spring boot application where I am having different controllers and all the controller having get, post, put, delete methods
GET and DELETE method URI format => /{userName}/{others}
and it's ensured that put and post method must have a field userid in their request body.
Also All the request having an authorization header.
And I already have a method called validate that accepts 2 parameters authorizationHeader and userName and returns true if this mapping exists false if not.
I am trying to write generic filter can filter incoming request and validate before going to controller.
How can I write this generic webfilter especially how to extract body from post request and validate requests.
I tried writing this
#Component
#Slf4j
public class ExampleWebFilter implements WebFilter {
#Override
public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
ObjectMapper mapper = new ObjectMapper();
return serverWebExchange
.getRequest()
.getBody()
.next()
.flatMap(body -> {
try {
return validate(body, serverWebExchange
.geHeaders().get(0))
} catch (IOException e) {
return Mono.error(e);
}
})
.flatMap((boolean s) -> {
return webFilterChain.filter(serverWebExchange);
});
}
Mono<Boolean> validate(DataBuffer body, String Header){
//my logic to validate
}
}
But it seems it's hanging after this filter method executed. so my question is
How can I write webfilter which will read body and validate?
Is there any other generic solution available for this type of problem in spring-boot?
I think you should use Interceptors. You can intercept the http call, and make your validations on the request. You can do this as global or you can do this for specific endpoints/paths. Here is a example for your case.
#Component
public class ProductServiceInterceptor implements HandlerInterceptor {
#Override
public boolean preHandle(
HttpServletRequest request, HttpServletResponse response, Object handler) throws
Exception {
return true;
}
#Override
public void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
//make validations
}
#Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception exception) throws Exception {
//make validations
}
}
After this you need to register your interceptor like below.
#Component
public class ProductServiceInterceptorAppConfig extends WebMvcConfigurerAdapter {
#Autowired
ProductServiceInterceptor productServiceInterceptor;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(productServiceInterceptor);
}
}
For more depth information you can visit the links below.
https://www.youtube.com/watch?v=agBadIAx0Wc
https://www.tutorialspoint.com/spring_boot/spring_boot_interceptor.htm
Based on some business logic i need to add query parameters to the request before it reaches the controller. In order to achieve this i have use the HandlerInterceptorAdapter to intercept the request.
I have a common lib where I have defined an interceptor and the dependent project has the controllers.
The interceptor is getting registered but when i invoke any api call it does not get invoked.
Interceptor in common lib
#Component
public class RequestInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, java.lang.Object handler)
throws ServletException, IOException {
request.setAttribute("id", "123"); // this would be populated based on logic
return true;
}
}
Dependency
#Configuration
public class Resolver implements WebMvcConfigurer {
#Autowired
RequestInterceptor interceptor;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor);
}
}
You don't have to annotate the RequestInterceptor. Please remove the #Component annotation from RequestInterceptor and #Autowired annotation from Resolver class to this dependency.
Instead of injecting, please instantiate it via default constructor.
public class RequestInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, java.lang.Object handler)
throws ServletException, IOException {
request.setAttribute("id", "123"); // this would be populated based on logic
return true;
}
}
#Configuration
#EnableWebMvc
public class Resolver implements WebMvcConfigurer {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new RequestInterceptor());
}
}
Is there any better way in spring boot that I can maintain a persistent counter in a DB(say, Redis or ES) for every kind of REST call with their corresponding timestamp? (WHAT I am not looking for is calling a function from within every REST call). Probably something like if I can do it before the control is passed to the function corresponding to the REST call, a common portion.
you can implement a custom interceptor.
public class MyInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// persist your counter here
return true;
}
#Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
super.afterCompletion(request, response, handler, ex);
// do what you need in the end of the call
}
to make spring-boot invoke your interceptor you should add a configuration class:
#Service
#EnableWebMvc
public class MyConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/*");
}
}
I want to populate a object as model attribute for each new request to my spring container.
I did the following.
-Added a new Interceptor within which am adding the object to request object
-Registered the interceptor
The interceptor is getting executed but the controller is returning a employee object with all values as null. Am i doing something wrong?
public class UserDetailsInterceptor extends AbstractInterceptor {
private static Class<? extends Annotation> annotationName = PopulateUserDetails.class;
public UserDetailsInterceptor() {
super(annotationName);
}
#Override
protected boolean handle(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod)
throws Exception {
log.error("running my interceptor handle now");
Employee empoyee = populateEmployeeDetails();
request.setAttribute("employee",employee");
return true;
}
}
#Slf4j
#RestController
#CrossOrigin
public class TestController {
#RequestMapping(value = "/tst1", method = RequestMethod.GET)
#PopulateEmployee
public Employee getEmployee(#ModelAttribute("employee") Employee employee) {
return employee;
}
}
Instead of using AbstractInterceptor use HandlerInterceptorAdapter
UserDetailsInterceptor will be like this
public class UserDetailsInterceptor extends HandlerInterceptorAdapter
{
Employee empoyee = null;
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
log.error("running my interceptor handle now");
empoyee = populateEmployeeDetails();
return true;
}
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object,
ModelAndView modelAndView) throws Exception {
request.setAttribute("employee",employee");
}
}