Published 19 Sep, 2022

Java - How can I get access to the HttpServletRequest object when using Java Web Services

Category Java
Modified : Oct 03, 2022

I'm using Java 6, Tomcat 6, and Metro. I use WebService and WebMethod annotations to expose my web service. I would like to obtain information about the request. I tried the following code, but wsCtxt is always null. What step must I take to not get null for the WebServiceContext.

In other words: how can I execute the following line to get a non-null value for wsCtxt?

MessageContext msgCtxt = wsCtxt.getMessageContext();

public class MyService{

  WebServiceContext wsCtxt;

  public void myWebMethod(){
    MessageContext msgCtxt = wsCtxt.getMessageContext();
    HttpServletRequest req = (HttpServletRequest)msgCtxt.get(MessageContext.SERVLET_REQUEST);
    String clientIP = req.getRemoteAddr();


There are 4 suggested solutions here and each one has been listed below with a detailed description. The following topics have been covered briefly such as Java, Web Services, Annotations, Servlets. These have been categorized in sections for a clear and precise explanation.


I recommend you either rename your variable from wsCtxt to wsContext or assign the name attribute to the @Resource annotation. The J2ee tutorial on @Resource indicates that the name of the variable is used as part of the lookup. I've encountered this same problem using resource injection in Glassfish injecting a different type of resource.

Though your correct name may not be wsContext. I'm following this java tip. If you like the variable name wsCtxt, then use the name attribute in the variable declaration:

@Resource(name="wsContext") WebServiceContext wsCtxt;


Maybe the annotation is for what you are looking for, instead of Resource?


I still have this problem. Here is my work-around was to write a ServletRequestListener that puts the request into a ThreadLocal var. Then the WebService can obtain the request from the ThreadLocal. In other words, I'm reimplementing something that just doesn't work for me.

Here's the Listener:

import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;

public class SDMXRequestListener implements ServletRequestListener {

    public SDMXRequestListener() {

    public void requestDestroyed(ServletRequestEvent event) {

    public void requestInitialized(ServletRequestEvent event) {
        final ServletRequest request = event.getServletRequest();


Here's the ThreadLocal wrapper:

import javax.servlet.ServletRequest;

public class ServletRequestStore {

    private final static ThreadLocal<ServletRequest> servletRequests = new ThreadLocal<ServletRequest>();

    public static void setServletRequest(ServletRequest request) {

    public static ServletRequest getServletRequest() {
        return servletRequests.get();


And the web.xml wiring:


The Web service uses the following code to obtain the request:

final HttpServletRequest request = (HttpServletRequest) ServletRequestStore.getServletRequest();


The following code works for me using Java 5, Tomcat 6 and Metro

Could it possibly be that there is a conflict between the WS support in Java 6 and the version of Metro you are using. Have you tried it on a Java 5 build?

public class Sample {
    public void sample() {
        HttpSession session = findSession();

    private HttpSession findSession() {
        MessageContext mc = wsContext.getMessageContext();
        HttpServletRequest request = (HttpServletRequest)mc.get(MessageContext.SERVLET_REQUEST);
        return request.getSession();
    private WebServiceContext wsContext;