【问题标题】:How do I get the full request url in a Java jax-ws @WebService @WebMethod?如何在 Java jax-ws @WebService @WebMethod 中获取完整的请求 URL?
【发布时间】:2015-03-29 20:02:33
【问题描述】:

客户端在 http://localhost:8080/soap/v1/myservice

处调用 Web 服务

这很好地映射到我的服务类,并且我的方法被调用。

在某些情况下,我希望在该方法中访问来自 http 请求的信息。我无法得到的是路径(或完整的 url)。

在可注入的 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,路径:null,查询字符串:null,用户代理:[JAX-WS RI 2.2.4-b01],内容类型:[text/xml; charset=utf-8],Http接受:[text/xml,multipart/related],Http主机:[localhost],连接:[keep-alive]

无论是不是 https,我也能够获取信息,但它需要一个丑陋的演员表和字段访问权限:

((AbstractWebServiceContext) webServiceContext).getRequestPacket().wasTransportSecure

在调试器中,我可以看到 url 的路径,但如果没有反射,我无法找到它。必须有一个干净的方法来获得它,不是吗?

由于在没有添加点击放大的情况下调整了我的屏幕截图大小,因此这里是重要的部分:

我的依赖:

    <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 有一些类似的问题,但没有一个对我有帮助。

mc.get(MessageContext.SERVLET_REQUEST) 返回null 这个人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?

为了重现,此代码在 GitHub https://github.com/optimaize/soapworks 上可用,首先运行(调试)Boot 类,然后是 RequestInfoServiceImplTest。

【问题讨论】:

    标签: java soap jax-ws


    【解决方案1】:

    这是一种使用反射提取 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;
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      请检查 WebServiceContext.getMessageContext().get( "org.apache.cxf.request.url" ).toString()

      【讨论】:

        猜你喜欢
        • 2013-06-08
        • 1970-01-01
        • 2016-08-13
        • 2015-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-09
        相关资源
        最近更新 更多