JBoss – jee6 rest service @ aroundinvoke interceptor is injecting an empty HttpServletRequest object

I have a @ aroundinvoke rest web service interceptor. I want to use it to record common data, such as classes and methods, remote IP address and response time

Using invocationcontext to obtain class and method names is very simple. As long as the intercepted rest service contains @ context HttpServletRequest in its parameter list, you can obtain the remote IP through HttpServletRequest

However, some rest methods do not have HttpServletRequest in their parameters. In these cases, I can't figure out how to get the HttpServletRequest object

For example, the following rest web services do not have the @ context HttpServletRequest parameter

@Inject
@Default
private MemberManager memberManager;

@POST
@Path("/add")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Member add(NewMember member) throws MemberInvalidException {
    return memberManager.add(member);
}

I've tried to inject it directly into my interceptor, but (on JBoss 6.1) it's always empty

public class RestLoggedInterceptorImpl implements Serializable {
    @Context
    HttpServletRequest req;

    @AroundInvoke
    public Object aroundInvoke(InvocationContext ic) throws Exception {

        logger.info(req.getRemoteAddr());  // <- this throws NPE as req is always null
        ...
        return ic.proceed();

I want to suggest a reliable way to access the HttpServletRequest object - even just HTTP headers... Whether the rest service contains parameters or not

Solution

Studying Javadoc http://docs.oracle.com/javaee/6/api/javax/interceptor/package-summary.html After the interceptor life cycle in, I think it is impossible to access any servlet context information other than invocationcontext (defined by parameters in the underlying rest definition) This is because the interceptor instance has the same life cycle as the underlying bean, and the servlet request @ context must be injected into the method instead of the instance However, if there are other contents besides invocationcontext in the method signature, the interceptor containing @ aroundinvoke will not be deployed; It does not accept additional @ context parameters

Therefore, the only answer that allows the interceptor to obtain HttpServletRequest is to modify the underlying rest method definition to include the @ context HttpServletRequest parameter (and httpservletresponse if necessary)

@Inject
@Default
private MemberManager memberManager;

@POST
@Path("/add")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Member add(NewMember member,@Context HttpServletRequest request,@Context HttpServletResponse response) throws MemberInvalidException {
    ...
}

The interceptor can then traverse the parameters in the invocationcontext to get the HttpServletRequest

@AroundInvoke
public Object aroundInvoke(InvocationContext ic) throws Exception {
    HttpServletRequest req = getHttpServletRequest(ic);
    ...
    return ic.proceed();
}

private HttpServletRequest getHttpServletRequest(InvocationContext ic) {
    for (Object parameter : ic.getParameters()) {
        if (parameter instanceof HttpServletRequest) {
            return (HttpServletRequest) parameter;
        }
    }
    // ... handle no HttpRequest object.. e.g. log an error,throw an Exception or whatever
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>