Get the Servlet Request object in a POJO class - spring

I need to get the current page URL in a POJO that is being called from an Acegi class (need to add some custom logic for the app I'm working on) and need to retrieve the HttpServletRequest so that I can get the subdomain of the URL (on which the logic is based).
I've tried to add:
#Autowired
private HttpServletRequest request;
...
public void setRequest(HttpServletRequest request) {
this.request = request;
}
public HttpServletRequest getRequest() {
return request;
}
However when I try to use the request object in my code, it is null.
Any idea what I am doing wrong or how I can better go about doing this?

If the bean is request scoped you can autowire the HttpServletRequest like you are doing.
#Component
#Scope("request")
public class Foo {
#Autowired private HttpServletRequest request;
//
}
Otherwise you can get the current request as follows:
ServletRequestAttributes sra = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest req = sra.getRequest();
This uses thread-local under the covers.
If you are using Spring MVC that's all you need. If you are not using Spring MVC then you will need to register a RequestContextListener or RequestContextFilter in your web.xml.

Related

Jersey get Request object programmatically

Is there any way to get the request (HttpServletRequest?) programmatically? I can only find how to do it with an annotation on the endpoint method/class.
Per https://stackoverflow.com/a/5118844/190164 I can add an annotated argument to my endpoint:
#POST
#Path("/test")
#Produces(MediaType.APPLICATION_JSON)
public String showTime(
#Context HttpServletRequest httpRequest
) {
// The method body
}
Or I can injected in the class(https://stackoverflow.com/a/26181971/190164)
public class MyResource {
#Context
private HttpServletRequest httpRequest;
#GET
public Response foo() {
httpRequest.getContentType(); //or whatever else you want to do with it
}
}
however I would like access to the request in another class that isn't directly linked to Jersey. Adding the #Context injection like in the second example above doesn't work, as the class isn't instantiated by Jersey. I'd like to be able to do something like
HttpServletRequest.getCurrentRequest()
but I haven't been able to find any static method somewhere.
If you are looking for some security solutions you can use servlet filters (create class that implements Filter) or you can implement ContainerRequestFilter and by overriding filter you can perform your filtering .Outside filters The context elements are always only accessible in the controller (where you place the path annotations) , there is no way to access this type of content from outside the controller other than passing it to the method or Object desired:
#Context
private HttpServletRequest httpRequest;
#GET
public Response foo() {
someMethod(httpRequest); //or whatever else you want to do with it
}
}
hope this helps.

Spring Data Rest - How to receive Headers in #RepositoryEventHandler

I'm using the latest Spring Data Rest and I'm handling the event "before create". The requirement I have is to capture also the HTTP Headers submitted to the POST endpoint for the model "Client". However, the interface for the RepositoryEventHandler does not expose that.
#Component
#RepositoryEventHandler
public class ClientEventHandler {
#Autowired
private ClientService clientService;
#HandleBeforeCreate
public void handleClientSave(Client client) {
...
...
}
}
How can we handle events and capture the HTTP Headers? I'd like to have access to the parameter like Spring MVC that uses the #RequestHeader HttpHeaders headers.
You can simply autowire the request to a field of your EventHandler
#Component
#RepositoryEventHandler
public class ClientEventHandler {
private HttpServletRequest request;
public ClientEventHandler(HttpServletRequest request) {
this.request = request;
}
#HandleBeforeCreate
public void handleClientSave(Client client) {
System.out.println("handling events like a pro");
Enumeration<String> names = request.getHeaderNames();
while (names.hasMoreElements())
System.out.println(names.nextElement());
}
}
In the code given I used Constructor Injection, which I think is the cleanest, but Field or Setter injection should work just as well.
I actually found the solution on stackoverflow: Spring: how do I inject an HttpServletRequest into a request-scoped bean?
Oh, and I just noticed #Marc proposed this in thecomments ... but I actually tried it :)

Spring RestEasy interceptor

I have a Spring boot application with resteasy-spring-3.0.19 and jboss-jaxrs-api_2.0_spec-1.0.0.
I would like to intercept all the rest calls for authorization.
The interceptor is not getting invoked. Also, How can i get the target method #Path annotation value in the interceptor.
Do I need to register this in the Spring boot app?
#Provider
public class AuthorizationtInterceptor implements ContainerRequestFilter{
/**
*
*/
public AuthorizationtInterceptor() {
// TODO Auto-generated constructor stub
}
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
String method = requestContext.getMethod();
UriInfo uriInfo = requestContext.getUriInfo();
// Need the target method #Path annotation value ....
}
}
Target Rest class,
#Named
#Singleton
#Path(ROOT_PATH)
public class WebController {
#GET
#Path(TEST_PATH)
#Produces(MediaType.APPLICATION_JSON)
public Response getUser(#Context final HttpServletRequest request) {
}
}
In a post-matching filter (a filter without the #PreMatching annotation), you can use ResourceInfo to get the matched resource class and the resource method.
Inject ResourceInfo in your filter using the #Context annotation:
#Context
private ResourceInfo resourceInfo;
Then get the resource class and extract the #Path annotation:
Path path = resourceInfo.getResourceClass().getAnnotation(Path.class);
To get the resource method, use:
Path path = resourceInfo.getResourceMethod().getAnnotation(Path.class);
Depending on what you are trying to achieve, instead of comparing the value of the #Path annotation for authorization purposes, you could consider binding your filter to a set of resource classes or methods. See more details in this answer.
Depending on how you are setting up your application, you may need to register the filter in your Application subclass or in your web.xml deployment descriptor.

Can you use request scoped #Context variables in a singleton ContextResolver in JAX-RS?

I'm using Jersey 1.13 with Spring. I've got a ContextResolver defined like so:
#Provider
public class ThemeSourceContextResolver implements ContextResolver<ThemeSource> {
#Context private HttpServletRequest request;
#Override
public ThemeSource getContext(Class<?> type) {
return new DefaultThemeSource(request);
}
}
<bean id="themeSourceContextResolver" scope="singleton" class="com.example.ThemeSourceContextResolver" />
Is the above valid? Specifically, is it "legal" (or does it make sense) to use the #Context private HttpServletRequest request in a ContextResolver? Since the ContextResolver is a singleton, does Jersey/JAX-RS do some threadlocal proxy magic or something to allow it to have access to the HttpServletRequest of every request?
It's not valid. #Context is injected only into JAX-RS resources. ContextResolver<?> has nothing to do with request context, mostly because it's a singleton, as you said.
To update this answer for Jersey 2.14:
The answer is now "sometimes". Jersey does indeed do proxy magic for specific #Context variables, namely HttpHeaders, Request, UriInfo and SecurityContext. Your specific case, HttpServletRequest, is not supported.
See https://jersey.java.net/documentation/latest/jaxrs-resources.html#d0e2578.

Spring MVC - Response

How can I access the response object from a bean? To get the request object I use the following.
ServletRequestAttributes attr = (ServletRequestAttributes)
RequestContextHolder.currentRequestAttributes();
Is there something similar to the above for response object?
If you are in a web application context (which it looks like you are) you can auto wire in the HttpServletRequest or HttpServletResponse.
The request/response from the current request scope will be injected.
#Component
public class SomeComponentInAWebApplicationContext {
#Autowired
private HttpServletRequest request;
#Autowired
private HttpServletResponse response;
...
}

Resources