Get HttpServletRequest in Jax Rs / Appfuse application?
Asked Answered
I

2

31

I created a basic application shell with AppFuse, and followed the AppFuse tutorial to create a a simple RESTful service with Jax-RS. That works just fine. A call to http://localhost:8080/services/api/persons returns a collection of Person objects as a Json formatted string with the right data.

I now would like to access the ServletRequest and ServletResponse objects from within a RESTful service exposed by Appfuse (to use another library that requires these objects).

I think that should be doable by adding an @Context annotation, e.g. following this StackOverflow post and this forum post.

But if I add the @Context tag (see below), it compiles fine but throws an Exception when the server is restarted (attached at bottom).

Here's the declaration of the @WebService:

@WebService
@Path("/persons")
public interface PersonManager extends GenericManager<Person, Long> {
    @Path("/")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    List<Person> read();
    ...
}

And here's the implementation class where I think I would call the @Context annotation:

@Service("personManager") 
public class PersonManagerImpl extends GenericManagerImpl<Person, Long> implements PersonManager { 
    PersonDao personDao; 
    @Context ServletRequest request; // Exception thrown on launch if this is present 
    @Context ServletContext context;  // Exception thrown on launch of this is present 
    ... 
    } 

Hopefully I'm missing something simple, either something to include to make it work, or to realize that getting the ServletRequest isn't supposed to be possible because.... Any clues would be welcome.

Am running this on Tomcat in IntelliJ.

=== EXCEPTION STACK TRACE (Truncated) ===

Caused by: org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are: 
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'serviceBeans' threw exception; nested exception is java.lang.RuntimeException: java.lang.NullPointerException 
        at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:102) 
        at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:58) 
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1358) 
        ... 37 more 
Interlanguage answered 8/3, 2012 at 2:38 Comment(0)
H
47

Try injecting the HttpServletRequest and HttpServletContext directly:

@Context private HttpServletRequest servletRequest;
@Context private HttpServletContext servletContext;
Homogeny answered 8/3, 2012 at 4:3 Comment(4)
Thanks so much! Although this didn't work exactly as written, it gave a different Exception, and that plus the idea of referencing HttpServletRequest rather than just ServletRequest was the perfect clue to figure out how to properly include it. Is a +1 rather than check appropriate?Interlanguage
Hmmm thats odd. I actually pasted the code directly from a functioning program. Feel free to post your solution as an answer so that it can benefit others.Homogeny
Then there must another item I need to add to my list of things to learn about how restful services work. Knowing that is also helpful. Thanks again!Interlanguage
This option forces you to use instance variable, you may want to use it as method parameter to inject the request, response variablesSebastien
I
30

Adding it to the method signature worked. I imagine it's because the request and response objects don't yet exist when the class is instantiated, but does when called by the brower.

@Path("/")
@GET
@Produces(MediaType.APPLICATION_JSON)
List<Person> read( @Context HttpServletRequest httpServletRequest, @Context HttpServletResponse httpServletResponse) { }
Interlanguage answered 9/3, 2012 at 1:38 Comment(1)
Surprisingly this works even without Spring or another CDI framework in use.Sidneysidoma

© 2022 - 2024 — McMap. All rights reserved.