#Service
#GetMapping
public Foo findByFooId(#RequestParam(name = "fid") String fooId) {
return fooService.findByFooId(fooId);
}
I would like to trigger and save who viewed Foo, using a different method in FooService.
Its like a PostConstruct callback for a successful response of findByFooId. How can this be achieved
One way is going to a custom HandlerInterceptor implementation.
Definition of the interceptor
public class FooViewerInterceptor extends HandlerInterceptorAdapter {
#Autowired
FooService fooService;
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
// if response succeeded ? http response code = 200 ?
// extract the "who" logic
// extract the fooId from request path
fooService.viewedBy(fooId, userId); // example...
}
}
Register the interceptor. Note the path pattern specified with the custom interceptor instance.. just an example.
#Configuration
public class AppConfig implements WebMvcConfigurer {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new FooViewerInterceptor()).addPathPatterns("/foo/**");
}
}
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 {
// ...
}
}
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());
}
}
I have a Spring boot application and I am implementing and interceptor in order to log some data.
The problem is that is not getting called, I have tried:
#Interceptor
public class LoggerInterceptor{
#AroundInvoke
public Object collectBasicLoggingInformation(InvocationContext context) throws Exception {
Logger logger = LoggerFactory.getLogger(context.getClass());
logger.info("Method Called: " + context.getMethod()
.getName());
logger.info("Parameters: " + Arrays.toString(context.getParameters()));
return context.proceed();
}
}
And then I've applied to methods or classes and in both of them doesn't work:
#GetMapping
#Interceptors(LoggerInterceptor.class)
public List getAllFilingNumber(){
logger.info("This is a test");
return filingNumberService.findAll();
}
Or
#RestController
#RequestMapping(FilingNumberController.BASE_URL)
#Interceptors(LoggerInterceptor.class)
public class FilingNumberController{
#GetMapping
public List getAllFilingNumber(){
logger.info("This is a test");
return filingNumberService.findAll();
}
}
Does someone knows what I am doing wrong?
Thanks
If you are having a springboot application in order to intercept the request to a controller , you have to take a different approach altogethor.
Interceptors are used in conjunction with Java EE managed classes to
allow developers to invoke interceptor methods on an associated target
class, in conjunction with method invocations or lifecycle events.
Common uses of interceptors are logging, auditing, and profiling.
Reference Doc
You are trying to use Java EE annotation with spring , which won't work.In spring-boot you will have to register the interceptors like :
#Configuration
public class WebConfig implements WebMvcConfigurer {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleChangeInterceptor());
registry.addInterceptor(new ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*");
}
}
The interceptor itself have to be a class which extends the HandlerInterceptorAdapter and implements the methods as follows.
From Spring DOCS :
All HandlerMapping implementations support handler interceptors that
are useful when you want to apply specific functionality to certain
requests — for example, checking for a principal. Interceptors must
implement HandlerInterceptor from the org.springframework.web.servlet
package with three methods that should provide enough flexibility to
do all kinds of pre-processing and post-processing:
preHandle(..): Before the actual handler is executed
postHandle(..): After the handler is executed
afterCompletion(..): After the complete request has finished
#Component
public class RequestInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object object) throws Exception {
System.out.println("we are Intercepting the Request");
return true;
}
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object object, ModelAndView model)
throws Exception {
System.out.println("request processing "
+ "completed by #RestController");
}
#Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object object, Exception arg3)
throws Exception {
System.out.println("afterCompletion Request Completed");
}
}
I've created following component to add X-Frame-Options into each response:
#Component
public class SecurityInterceptor extends HandlerInterceptorAdapter {
#PostConstruct
public void init(){
System.out.println("init");
}
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
response.addHeader("X-Frame-Options", "DENY");
}
}
method init executes on startup thus spring knows about this.
Also I have following rest service:
#PostMapping("/rest_upload")
public DeferredResult<ResponseEntity> upload(#RequestParam("file") MultipartFile multipartFile, HttpServletRequest request) throws IOException {
final DeferredResult<ResponseEntity> deferredResult = new DeferredResult<>();
...
return deferredResult;
}
Unfortunately postHandle method is not invoking.
How can I correct it?
Spring knows about your Interceptor as just a bean and nothing more. You need to register it with InterceptorRegistry so that it is called as part of interceptors.
#Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
#Autowired
SecurityInterceptor securityInterceptor;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(securityInterceptor);
}
}
You need a configuration class that extends WebMvcConfigurerAdapter and overrides the addInterceptor method:
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SecurityInterceptor());
}
You also need to make sure you have enabled WebMvc in Spring.
I have an interceptor that is supposed to intercept urls with different patterns like:
myapp/something/add/whatever
myapp/something/add
myapp/something/addWhatever
myapp/something/somethingelse/add
etc...
I have to intercept all urls which contain "add". There are a lot of somethings and somethingelses...
I have tried different patterns but it seems that they are all wrong:
**/add/*
**/add*
**/add/ ** (I added a blank space before the last ** so it doesn't format it to bold)
The interceptor is something like
public class MyInterceptor implements HandlerInterceptor {
}
I configure it in
#Configuration
#EnableSpringDataWebSupport
#EnableWebMvc
class MvcConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addInterceptors(final InterceptorRegistry registry) {
registry.addInterceptor(getMyInterceptor()).addPathPatterns("**/add/*", "**/add/**", "**/add*");
}
#Bean
public MyInterceptor getMyInterceptor() {
return new MyInterceptor();
}
}
If I try to access
http://localhost:8080/myapp/something/add/somethingelse
my interceptor doesn't intercept it...
I had a similar issue. Here are my suggestions.
First use global interceptor and check the request uri:
public class MyInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String uri = request.getRequestURI();
if(uri.contains("/add")){
// do your job
}
return super.preHandle(request, response, handler);
}
}
In my case, alls add- methods are PUT, or POST requests. So I'm checking this in my global interceptor:
public class MyInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String method = request.getMethod();
if("PUT".equals(method) || "POST".equals(method)){
// do your job
}
return super.preHandle(request, response, handler);
}
}
configure it without addPathPatterns:
#Configuration
#EnableSpringDataWebSupport
#EnableWebMvc
class MvcConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addInterceptors(final InterceptorRegistry registry) {
registry.addInterceptor(getMyInterceptor());
}
#Bean
public MyInterceptor getMyInterceptor() {
return new MyInterceptor();
}
}
Apparently this can be fixed by Change the bean type to "Mapped Interceptor" and wrapping it; though people don't seem to know why its an issue in the first place.
Based on this solution: https://stackoverflow.com/a/35948730/857994