HttpServletRequest throws error when used within Aspect - spring

I have a method which has an aspect. When I try to #Autowire HttpServletRequest, and use request.getHeader(something), I get this error -
No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
How do I fix this? I tried using RequestContextHolder, but upon debugging I still see null. How do I use the RequestContextListener when my project has no web.xml.

Request Header can be accessed using HttpServletRequest below way.
private static HttpServletRequest getRequest() {
return((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
}
public static String getApiTraceId() {
return getRequest().getHeader(something);
}

Aspect annotations spins a new thread which is different from the one httpservlet is available in. This is why request was not available within the #ASpect. To resolve it, call the request object BEFORE the aspect method, cache it and call the same method as before.

Related

Spring and Netflix DGS: Access SecurityContext from DgsSubscription Method

We have a custom SecurityService class that internally accesses the current SecurityContext and RequestAttributes via SecurityContextHolder and RequestContextHolder for every method call of the service.
Imagine the custom class User returned from securityService.getUser();
Given the following code:
#DgsSubscription
public Publisher<String> test() {
String s = securityService.getUser().getName();
return Flux.interval(Duration.ofSeconds(5)).map(t -> s);
}
That periodically triggers the test subscription and returns the User name.
I get the following error when a client tries to subscribe:
Exception while fetching data (/test) : No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
Apparently the test method is run in a new thread?
How do I make both context available to this thread?
SecurityService is autowired into the Datafetcher.

Is it possible to generate a request scope?

I'm using a request scoped bean in my application:
#Bean
#RequestScope
public BeanA beanA(){
return new BeanA();
}
And, as long as I get web requests it is fine.
Problem is that I'm now supporting also other sources of request (for example Spring data redis listener) but, when I want to populate it with values I get
no thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
Would it possible to create a request scope?

How can I see the json coming from the client when using Spring-MVC?

A client software is trying to access my Spring-MVC rest server, but it's getting a 400 (Bad Request) response every time. I know my server is fine (it's in use by many other clients), but I cannot debug the client application, so I cannot see what it is sending.
Is there a way for me to see what JSON I am receiving before Spring tries to convert it to an entity and fails? It's okay if I can only do this at debug time, I just need to be able to give support to this application's creators.
Just in case, here is the spring-mvc controller method:
#Named
#RequestMapping(value = "/taskmanager/task")
public class TaskManagerTaskRest {
#RequestMapping(value = "", method = RequestMethod.POST)
#ResponseBody
public void createTask(#RequestBody Task task, HttpServletRequest request,
HttpServletResponse response) throws CalabacinException {
// This code never gets executed because the Task json is invalid, but I don't know how I could see it.
...
...
}
}
Try to use Fiddler. It will help you to catch HTTP requests/responses. You will be able to see your JSON.
You can create and use a AbstractRequestLoggingFilter filter implementation and conditionally log the relevant parts of the request. You should use ContentCachingRequestWrapper to wrap the request.

How to get request info on session created in Spring MVC?

I'm hoping to save some client info (IP address, etc) to a database on session created in Spring MVC.
I created a class implementing HttpSessionListener and configured it in web.xml. However, I'm not sure where to go after that.
Would like to be able to inject a bean as well (Spring Data JPA repository).
I've seen How to get the IP address when a session is created? , however if I try to access RequestContextHolder.currentRequestAttributes() I get the following exception:
SEVERE: Session event listener threw exception
java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
You can create a bean this way with Spring java config:
#Bean
#Named ("IP")
#Scope ("session")
public String ip (HttpServletRequest request) {
return request.getRemoteAddr ();
}
If all you want to do is log stuff then you should use the HttpSessionListener, please provide your source and full stack trace. Use pastebin.com if necessary.

Spring MVC, how to have a controller handler handle all the requests before the mapped handlers?

I've wrote a web app with its brave controllers and handler mapping, everything with Spring 3.0 and controller annotations. Now turns out that I need simple and custom autentication. I don't want to use ACEGI for the moment, because I've no time to learn it. I'd like ideally that I could have a routine that gets called before every mapped handler, gets from the HttpSession the userId, checks if he is logged in and the session key and if not redirects to a login page. I've been thinking about an interceptor... the problem is that you have to use HandlerInterceptorAdapter, which has the following method:
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
that won't let me access the HttpSession associated with the request. How do I solve this?
Are you sure? You should be able to obtain the session through request.getSession().

Resources