10

如何访问 Spring-ws 端点中的 HTTP 标头?

我的代码如下所示:

public class MyEndpoint extends AbstractMarshallingPayloadEndpoint {
  protected Object invokeInternal(Object arg) throws Exception {
      MyReq request = (MyReq) arg;
      // need to access some HTTP headers here
      return createMyResp();
  }
}

invokeInternal()仅获取未编组的 JAXB 对象作为参数。如何访问内部请求附带的 HTTP 标头invokeInternal()

一种可能可行的方法是创建一个 Servlet 过滤器,将标头值存储到ThreadLocal变量中,然后在内部访问该变量invokeInternal(),但是否有更好、更像弹簧的方法来做到这一点?

4

3 回答 3

19

您可以添加这些方法。TransportContextHolder它将在线程局部变量中保存一些与传输(在本例中为 HTTP)相关的数据。您可以HttpServletRequestTransportContext.

protected HttpServletRequest getHttpServletRequest() {
    TransportContext ctx = TransportContextHolder.getTransportContext();
    return ( null != ctx ) ? ((HttpServletConnection ) ctx.getConnection()).getHttpServletRequest() : null;
}

protected String getHttpHeaderValue( final String headerName ) {
    HttpServletRequest httpServletRequest = getHttpServletRequest();
    return ( null != httpServletRequest ) ? httpServletRequest.getHeader( headerName ) : null;
}
于 2010-10-26T10:13:26.173 回答
1

您可以通过注入HttpServletRequest来访问 Spring SOAP Endpoint 中的 HTTP 标头。

例如,您需要获取Autorization标头(您使用基本身份验证)。

SOAP 请求:

POST http://localhost:8025/ws HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: ""
Authorization: Basic YWRtaW46YWRtaW4=
Content-Length: 287
Host: localhost:8025
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tok="http://abcdef.com/integration/adapter/services/Token">
   <soapenv:Header/>
   <soapenv:Body>
      <tok:GetTokenRequest>
      </tok:GetTokenRequest>
   </soapenv:Body>
</soapenv:Envelope>

@Endpoint Java 类

@Endpoint
@Slf4j
public class TokenEndpoint {

    public static final String NAMESPACE_URI = "http://abcdef.com/integration/adapter/services/Token";
    private static final String AUTH_HEADER = "Authorization";

    private final HttpServletRequest servletRequest;
    private final TokenService tokenService;

    public TokenEndpoint(HttpServletRequest servletRequest, TokenService tokenService) {
        this.servletRequest = servletRequest;
        this.tokenService = tokenService;
    }

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "GetTokenRequest")
    @ResponsePayload
    public GetTokenResponse getToken(@RequestPayload GetTokenRequest request) {
        String auth = servletRequest.getHeader(AUTH_HEADER);
        log.debug("Authorization header is {}", auth);
        return tokenService.getToken(request);
    }
}
于 2018-08-22T09:03:42.500 回答
0

我遇到了同样的问题(请参阅this other question)。我需要向我的 WS 添加一个 Content-Type 标头。我走了 Servlet Filter 的路。大多数时候,您不需要更改 Web 服务中的 HTTP 标头。但是......有时理论和实践之间存在差异。

于 2010-10-20T08:22:05.497 回答