MessageContext in SOAPHandler JAX-WS WebService

11,367

For JAX-WS based webservice, you can access remote host info from javax.xml.ws.spi.http.HttpExchange, that can be accessed based on JAX-WS version,

  • JAX-WS 2.1

    SOAPMessageContext soapContext = (SOAPMessageContext)wsContext.getMessageContext();
    HttpExchange exchange = (HttpExchange)soapContext.get(JAXWSProperties.HTTP_EXCHANGE);
    
  • JAX-WS 2.2

    SOAPMessageContext soapContext = (SOAPMessageContext)wsContext.getMessageContext();
    HttpExchange exchange = (HttpExchange)soapContext.get("com.sun.xml.ws.http.exchange");
    

Note that wsContext.getMessageContext() will return MessageContext. If you want it, don't cast to SOAPMessageContext, like that,

MessageContext msgContext = wsContext.getMessageContext();

Finally you can access remote address info,

InetSocketAddress remoteAddress = exchange.getRemoteAddress();
String remoteHost = remoteAddress.getHostName();
Share:
11,367
hasmet
Author by

hasmet

Updated on June 05, 2022

Comments

  • hasmet
    hasmet almost 2 years

    I have a JAX-WS 2.2 WebService and I must take the IP Address of each client that communicate with it. I write a SOAP protocol handler but I can't see the addresses because the handlers doesn't contain this information and using the mimeheaders I can't also see this information. The code of my handler is the follow:

    public class AddressHandler implements SOAPHandler<SOAPMessageContext> {
    
    private void takeIPAddress(SOAPMessageContext context) {
    
        try {
            SOAPMessage original = context.getMessage();
            MimeHeaders mimeheaders = original.getMimeHeaders();
            MimeHeader mimeheader = null;
    
            Iterator<?> iter = mimeheaders.getAllHeaders();
    
            for (; iter.hasNext();) {
                mimeheader = (MimeHeader) iter.next();
    
                System.out.println("name=" + mimeheader.getName() + ", value="
                        + mimeheader.getValue());
            }
    
    
         } catch (Exception e) {
             e.printStackTrace();
         }
    
    
    }
    
    @Override
    public void close(MessageContext arg0) {
        // TODO Auto-generated method stub
    
    }
    
    @Override
    public boolean handleFault(SOAPMessageContext arg0) {
        // TODO Auto-generated method stub
        return false;
    }
    
    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        takeIPAddress(context);
        return true;
    }
    
    @Override
    public Set<QName> getHeaders() {
        // TODO Auto-generated method stub
        return null;
    }
    }
    

    Now I'm seeing that would be possible to see the addresses using the following code:

    SOAPMessageContext jaxwsContext = (SOAPMessageContext)wsContext.getMessageContext();
    HttpServletRequest request = HttpServletRequest)jaxwsContext.get(SOAPMessageContext.SERVLET_REQUEST);
    String ipAddress = request.getRemoteAddr();
    

    But I can't import correctly the HttpServletRequest class. Do you have any ideas?

    UPDATE

    Thanks to A Nyar Thar, I've seen that exists another method to take address and I've implemented this in my code, that now is:

    private void takeIPAddress(SOAPMessageContext context) {
    
        HttpExchange exchange = (HttpExchange)context.get("com.sun.xml.ws.http.exchange");
        InetSocketAddress remoteAddress = exchange.getRemoteAddress();
        String remoteHost = remoteAddress.getHostName();
    
        System.out.println(remoteHost);     
    
    }
    

    But the code execution create this error (where row 39 is where I do exchange.getRemoteAddress()):

    java.lang.NullPointerException
    at server.AddressHandler.takeIPAddress(AddressHandler.java:39)
    at server.AddressHandler.handleMessage(AddressHandler.java:80)
    at server.AddressHandler.handleMessage(AddressHandler.java:1)
    at com.sun.xml.internal.ws.handler.HandlerProcessor.callHandleMessage(HandlerProcessor.java:282)
    at com.sun.xml.internal.ws.handler.HandlerProcessor.callHandlersRequest(HandlerProcessor.java:125)
    at com.sun.xml.internal.ws.handler.ServerSOAPHandlerTube.callHandlersOnRequest(ServerSOAPHandlerTube.java:123)
    at com.sun.xml.internal.ws.handler.HandlerTube.processRequest(HandlerTube.java:105)
    at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:626)
    at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:585)
    at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:570)
    at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:467)
    at com.sun.xml.internal.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:299)
    at com.sun.xml.internal.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:593)
    at com.sun.xml.internal.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:244)
    at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handleExchange(WSHttpHandler.java:95)
    at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handle(WSHttpHandler.java:80)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77)
    at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:80)
    at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:677)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77)
    at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:649)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)
    

    I think that the real problem is that I don't know how take WebServiceContext from my class AddressHandler. Do you have ideas?

  • Wundwin Born
    Wundwin Born almost 10 years
    @hasmet Hope that is what you want.
  • hasmet
    hasmet almost 10 years
    Thanks A Nyar Thar, but this method didn't work and I have an error :( I've updated my question with the error
  • hasmet
    hasmet almost 10 years
    The realt problem is that I don't know how take WebServiceContext from my class
  • hasmet
    hasmet almost 10 years
    Finally I've implemented this part using your code in another side of server without using the handlers.....Thank you again A Nyar Thar
  • abdelrahman-sinno
    abdelrahman-sinno over 8 years
    I'm running a standalone application with a Jetty embedded server, soapContext.get("com.sun.xml.ws.http.exchange") is returning null; help is highly appreciated.