jax ws getting client ip
Asked Answered
V

4

12

I'm trying to retrieve the client IP with JAX-WS, I used:

@Resource
WebServiceContext wsContext; 

MessageContext mc = wsContext.getMessageContext();
HttpServletRequest req = (HttpServletRequest)mc.get(MessageContext.SERVLET_REQUEST); 

log.info("["+req.getRemoteAddr()+"])

I get a NullPointerException in req, mc is not null.

My question is which JAR to use for HttpServletRequest because I'm using a Java stand-alone application?

Thanks

Valeda answered 4/10, 2012 at 13:8 Comment(0)
G
19

How to get the webservice client address for a jax-ws service depends on whether you are:

  • Running your webservice as a servlet (in a Java EE container), or
  • Running your webservice as a stand-alone application (Java SE 6 or 7).

Servlet Webservices If your webservice is a servlet then use the solution of the first post that contains the following:

HttpServletRequest req = (HttpServletRequest)mc.get(MessageContext.SERVLET_REQUEST);

Application Webservices : JAX-WS 2.1 If you are using a Java application (Java SE) you have no servlet context, so the HttpServletRequest will be null. You need to use the method of the later post, the one that has the following line:

HttpExchange exchange = (HttpExchange)msgx.get(JAXWSProperties.HTTP_EXCHANGE);

Note: this only works with the JAX-WS 2.1 stack/reference implementation.

Application Webservices : JAX-WS 2.2

In JAX-WS 2.2 the value of JAXWSProperties.HTTP_EXCHANGE has changed from "com.sun.xml.ws.http.exchange" (the value it was in JAX-WS 2.1) to "com.sun.xml.internal.ws.http.exchange". That means that a call to

HttpExchange exchange = (HttpExchange)msgx.get(JAXWSProperties.HTTP_EXCHANGE);
InetSocketAddress remoteAddress = exchange.getRemoteAddress();
String remoteHost = remoteAddress.getHostName();

will return null in JAX-WS 2.2 and you'll get a NullPointerException on the second line, and more importantly, cannot get the remote address of the client.

If you use the following call instead (using the literal value, ugh!):

HttpExchange exchange = (HttpExchange)msgx.get("com.sun.xml.ws.http.exchange");
InetSocketAddress remoteAddress = exchange.getRemoteAddress();
String remoteHost = remoteAddress.getHostName();

you will get a non-null value and will be able to obtain the client address.

So, how you get the remote address of the client depends on how you deploy your code (servlet or application) and which version of JAX-WS you are using (JAX-WS 2.1 or 2.2).

Recommendations

  • Servlets: If you are deploying your JAX-WS webservice in a servlet you can always use the call to get the property MessageContext.SERVLET_REQUEST no matter what version of JAX-WS 2 you are using.

  • Applications: If you are deploying your JAX-WS webservice in an application you can always use the call HttpExchange exchange = (HttpExchange)msgx.get("com.sun.xml.ws.http.exchange"); no matter whether you are using JAX-WS 2.1 or 2.2, therefore it is probably better to use the string literal in your code rather than the symbolic JAXWSProperties.HTTP_EXCHANGE.

As distasteful as using the literal is, it is better to have more robust code that works across JAX-WS versions rather than prettier code that doesn't.

I hope the JAX-WS team correct the issue sometime and restore the value of JAXWSProperties.HTTP_EXCHANGE to the useful value again.

Many thanks to the earlier posters that showed the various ways of finding the remote address of JAX-WS clients. The information was very useful :)

Gorgoneion answered 3/12, 2012 at 22:37 Comment(2)
It may be noteworthy that with an HTTPS connection there is no value associated with the key "com.sun.xml.ws.http.exchange". But with the string literal "com.sun.xml.internal.ws.http.exchange" you can get an object and cast it to HttpsExchange. Tested with (official) Java 7 with JAX-WS 2.2.Alviani
If you're using Apache AXIS: MessageContext context = MessageContext.getCurrentContext(); HttpServletRequest req = (HttpServletRequest) context.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST); String IP = req.getRemoteAddr(); OR String IP = MessageContext.getCurrentContext().getProperty("remoteaddr"); SourceChintz
V
9

if we use an embedded Http server , we can get the client IP like this:

@Resource
WebServiceContext wsContext;

Then in the web method :

@WebMethod
MessageContext msgx = wsContext.getMessageContext();
HttpExchange exchange = (HttpExchange)msgx.get(JAXWSProperties.HTTP_EXCHANGE);
log.info("[" + exchange.getRemoteAddress().getAddress() + "]");

Hope it helps someone else

Valeda answered 10/10, 2012 at 9:34 Comment(0)
P
1

Here is an answer, I think you should initialize mc and req in WebMethod annotated method. Geting the IP Address Of A client For a webservice

Plumy answered 4/10, 2012 at 13:20 Comment(1)
that's what i did , the problem is im using embedded HTTP server , so : HttpServletRequest req = (HttpServletRequest)mc.get(MessageContext.SERVLET_REQUEST); is incorrect , that's what im looking for. Thanks anywayValeda
B
-1

The following code might work:

HttpServletRequest request = (HttpServletRequest) messageContext.get("transport.http.servletRequest");
String hostIp = request.getRemoteAddr();
Breechblock answered 21/5, 2015 at 8:43 Comment(1)
If you want to get an instance of HttpServletRequest, use MessageContext.SERVLET_REQUEST as a key insteadPhilter

© 2022 - 2024 — McMap. All rights reserved.