如何在Java jax-ws @WebService @WebMethod中获取完整的请求URL?

时间:2015-01-30 10:54:07

标签: java soap jax-ws

客户通过 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

在调试器中,我可以看到网址的路径,但没有反射,我无法找到它。只需要一个干净的方式来获得它,不是吗?

intellij debugger shows url

由于SO在不添加点击放大的情况下调整了屏幕截图,因此以下是重要部分:enter image description here

我的依赖项:

    <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上可用。

2 个答案:

答案 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()

相关问题