Reputation: 33
Below is my jersey webservice page ( application.java ) which invokes an interceptor
@Context ServletContext context
@Path("/application")
public class application{
@POST
@Path("/getData")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Interceptors(Interceptor.class)
public int metthod(Object input) throws Exception{
// do something
}
}
ServletContext is accessible on appliation.java if i use @Context ServletContext context but I get NullPointerException if I use same inside the Interceptor class.
How do i access ServletContext from an Interceptor class.
Thanks
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>ws</display-name>
<description>Web Services</description>
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.java.files;com.fasterxml.jackson.jaxrs.json</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<listener>
<listener-class>com.java.listener.appServletContextListener</listener-class>
</listener>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
Upvotes: 0
Views: 1032
Reputation: 6456
I will attempt to help you with your query and do this in an answer so that it can be formatted and easier to read. Please comment on it in case there is something I am misunderstanding.
From your question I think you are not using any other frameworks other than Weblogic and Jersey.
I will have to make a few assumptions here:
If you could update your question and add how you create the interceptor?
By the sounds of it, Weblogic offers a container that is running the jax.rs reference implementation for you (jersey). (Correct me if I am wrong).
The essential problem is that Weblogic has no concept of context. If you see your annotation, you can see that the Annotation is a jax-rs annotation:
javax.ws.rs.core.Context
What this means is that you can use this annotation with reference implementations of the jax-rs framework, which would be jersey. Jersey manages beans for you (creation/injection/interception etc) and is request scoped, which is why it can inject all sorts of interesting Attributes for you that have something to do with your Webservice.
This is also why the @Context annotation works in your Resource, because your resource is jersey handled. Your interceptor however seems to be a Weblogic interceptor, that is handled by weblogic. It is not hooked into your jersey logic, hence injection does not work here.
There is ways around this, in form of using a DI framework and scoped beans (e.g. guice can do this for you), however this is not necessary. For your issue, there is a more integrated and smooth way of intercepting resource calls.
A webservice should never be called from within the Application (e.g. it reacts to HTTP requests). That means, you will want to intercept these calls with jersey interceptors, not weblogic interceptors. For this, you can see these two Interfaces:
javax.ws.rs.container.ContainerRequestFilter
javax.ws.rs.container.ContainerResponseFilter
You guessed it right - one of them intercepts Requests before your resource gets them, the other intercepts after your resource has processed the request.
You can read more about this here: https://jersey.java.net/documentation/latest/filters-and-interceptors.html
So in your usecase, you want to intercept the request before handing it off to your resource. In case your ServletContextMap has some value, you'll want to abort the request (return it to the user with some error).
The advantage of this is that Filter are handled by jersey, hence they can be injected by jersey with your context.
Consider this:
public class MyFilter implements ContainerRequestFilter {
@Context
private ServletContext context;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
boolean result = evaluateMyMap();
if(!result) {
// This is the jersey way of not calling proceed. It will return a 400 response
// to the user with the message
requestContext.abortWith(Response.status(Status.BAD_REQUEST)
.entity("The Hashmap in the Context has some wonky value").build());
}
}
private boolean evaluateMyMap() {
// access your context here and do your map evanulation
// return true if you want the request to be processed, false otherwise
return false;
}
}
In the filter class, the injected context is accessible for you and you can access your map as well.
Please note that your filters must be registered with jersey as well. How to do that, I am not sure (because I haven't used weblogic before)
I hope that explains your issue and how to tackle it. Let me know if you need some more advise/help.
Regards, Artur
Upvotes: 1