客户通过 http://localhost:8080/soap/v1/myservice
调用网络服务这很好地映射到我的服务类,我的方法被调用。
在某些情况下,我希望在该方法中访问来自http请求的信息。我无法得到的是路径(或完整网址)。
注入式WebServiceContext中有可用的信息,如下所示:
@WebService @Service
public class MySoapService {
@Resource
private WebServiceContext webServiceContext;
@WebMethod
public String requestInfo() {
MessageContext mc = webServiceContext.getMessageContext();
return makeMsg(mc);
}
private String makeMsg(MessageContext messageContext) {
StringBuilder sb = new StringBuilder();
sb.append("Request method: "+messageContext.get(MessageContext.HTTP_REQUEST_METHOD));
sb.append(", Path: "+messageContext.get(MessageContext.PATH_INFO));
sb.append(", Query string: "+messageContext.get(MessageContext.QUERY_STRING));
sb.append(", User agent: "+((Map)messageContext.get(MessageContext.HTTP_REQUEST_HEADERS)).get("user-agent"));
sb.append(", Content type: "+((Map)messageContext.get(MessageContext.HTTP_REQUEST_HEADERS)).get("content-type"));
sb.append(", Http accept: "+((Map)messageContext.get(MessageContext.HTTP_REQUEST_HEADERS)).get("accept"));
sb.append(", Http host: "+((Map)messageContext.get(MessageContext.HTTP_REQUEST_HEADERS)).get("host"));
sb.append(", Connection: "+((Map)messageContext.get(MessageContext.HTTP_REQUEST_HEADERS)).get("connection"));
System.out.println(messageContext);
return sb.toString();
}
}
但是,messageContext.get(MessageContext.PATH_INFO)请求的路径为空。
示例结果:
请求方法:POST,Path:null,Query string:null,User agent:[JAX-WS RI 2.2.4-b01],Content type:[text / xml; charset = utf-8],Http接受:[text / xml,multipart / related],Http host:[localhost],Connection:[keep-alive]
我也可以获取有关它是否为https的信息,但它需要一个丑陋的演员和字段访问:
((AbstractWebServiceContext) webServiceContext).getRequestPacket().wasTransportSecure
在调试器中,我可以看到网址的路径,但没有反射,我无法找到它。只需要一个干净的方式来获得它,不是吗?
由于SO在不添加点击放大的情况下调整了屏幕截图,因此以下是重要部分:
我的依赖项:
<dependency>
<groupId>org.glassfish.grizzly</groupId>
<artifactId>grizzly-http-server-jaxws</artifactId>
<version>2.3.18</version>
</dependency>
本身使用
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.2.5</version>
</dependency>
在SO上有一些类似的问题,但没有人帮助我。
对于此人wsContext.getMessageContext().get(MessageContext.SERVLET_REQUEST) returns null on Jetty?或此Geting the IP Address Of A client For a webservice或此How can I access the ServletContext from within a JAX-WS web service? , mc.get(MessageContext.SERVLET_REQUEST)
会返回null
要重现,首先运行(调试)Boot类,然后是RequestInfoServiceImplTest,此代码在GitHub https://github.com/optimaize/soapworks上可用。
答案 0 :(得分:0)
这是一种使用反射提取URI的方法。我正在使用它作为临时黑客。
import com.sun.xml.ws.api.server.WebServiceContextDelegate;
import com.sun.xml.ws.server.AbstractWebServiceContext;
import org.jetbrains.annotations.NotNull;
import javax.xml.ws.WebServiceContext;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/**
*/
public class RequestUrlExtractor {
/**
* Best effort. Uses reflection.
* See http://stackoverflow.com/questions/28234303/how-do-i-get-the-full-request-url-in-a-java-jax-ws-webservice-webmethod
* @return starting with a slash, eg "/my/service/url"
* @throws RuntimeException in case of failure (api change)
*/
@NotNull
public String extractUri(@NotNull WebServiceContext webServiceContext) {
WebServiceContextDelegate webServiceContextDelegate = ((AbstractWebServiceContext) webServiceContext).getRequestPacket().webServiceContextDelegate;
Class<?> c = webServiceContextDelegate.getClass();
Field field;
try {
field = c.getDeclaredField("request");
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
field.setAccessible(true);
Object result;
try {
result = field.get(webServiceContextDelegate);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
c = result.getClass();
try {
field = c.getDeclaredField("request");
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
field.setAccessible(true);
Object request;
try {
request = field.get(result);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
java.lang.reflect.Method method;
try {
method = request.getClass().getMethod("getRequestURI");
} catch (SecurityException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
Object uri;
try {
uri = method.invoke(request);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
if (!(uri instanceof String)) {
throw new RuntimeException("Not a string!");
}
return (String)uri;
}
}
答案 1 :(得分:0)
请检查
WebServiceContext.getMessageContext().get( "org.apache.cxf.request.url" ).toString()