添加 HTTP Headers 到 JAX-WS 服务响应

Add HTTP Headers to JAX-WS service response

我正在开发 Java Web 服务。此时我可以得到 Http header 请求。但我想添加更多 header 请求。

我目前正在 servlet 过滤器中执行此操作。

@WebFilter(urlPatterns = {"/*"})
public class AddHeader implements Filter {

    @Resource
    private WebServiceContext context;

    public AddHeader() {
    }

    @Override
    public void init(FilterConfig fConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(
            ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        if (request.getContentLength() != -1 && context != null) {
            MessageContext mc = context.getMessageContext();
            ((HttpServletResponse) response).addHeader(
                    "Operation", "something"
            );
        }

        chain.doFilter(request, response);
    }
}

这个策略的问题是添加的 header 是静态的。

使用 SoapHandler class 我可以获得 SOAP 消息 - 动态:

public class SoapClass implements SOAPHandler<SOAPMessageContext> {


    @Override
    public boolean handleMessage(SOAPMessageContext messageContext) {
        log(messageContext);
        return true;
    }

    @Override
    public Set<QName> getHeaders() {
        Set<QName> qNames = Collections.EMPTY_SET;
        return qNames;
    }

    @Override
    public boolean handleFault(SOAPMessageContext messageContext) {
        log(messageContext);
        return true;
    }

    @Override
    public void close(MessageContext context) {
    }


    public static String getMsgAsString(SOAPMessage message) {
        String msg = null;
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            message.writeTo(baos);
            msg = baos.toString();
        } catch (SOAPException | IOException soape) {
        }
        return msg;
    }


    private String soapToString(SOAPMessage message, boolean indent) {
        final StringWriter sw = new StringWriter();

        try {
            TransformerFactory.newInstance().newTransformer().transform(
                    new DOMSource(message.getSOAPPart()),
                    new StreamResult(sw));
        } catch (TransformerException e) {
            throw new RuntimeException(e);
        }

        return (indent ? sw.toString() : sw.toString().replaceAll("[\r\n]", ""));
    }

所以,我真正想要的是将动态肥皂消息加入过滤器。我怎样才能做到这一点?

虽然我仍然不完全清楚您真正想要什么,但我将描述如何在 SOAP Web 服务响应中添加 HTTP headers。执行此操作最干净的地方是在 JAX-WS 处理程序中,这与您已经拥有的 SoapClass.

形式没有什么不同

要在您的 SOAPHandler 中执行此操作,您必须首先获得对底层 HttpServletResponse 中 headers 列表的访问权限。此列表由 SOAPMessageContext:

提供
    @Override
    public boolean handleMessage(SOAPMessageContext context) {
      //This property checks whether the handler is being invoked for a service response
      boolean response= ((Boolean) context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue(); 

      if (response) {
          //this is a JAX-WS-provided map of HTTP headers
          Map<String, List<String>> headers = (Map<String, List<String>>) context.get(MessageContext.HTTP_RESPONSE_HEADERS);
          if (null == headers) {
              //create a new map of HTTP headers if there isn't already one
              headers = new HashMap<String, List<String>>();
          }
          //add your desired header
          headers.put("Operation",Collections.singletonList("something");
        }
      return true;
    }

另一种方法是访问作为网络服务响应基础的 HttpServletResponse

     @Override
    public boolean handleMessage(SOAPMessageContext context) {
      //This property checks whether the handler is being invoked for a service response
      boolean response= ((Boolean) context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY)).booleanValue(); 

      if (response) {
          //this is underlying http response object
          HttpServletResponse response = (HttpServletResponse) context.get(MessageContext.SERVLET_RESPONSE);

          //add your desired header
          response.addHeader("Operation", "something");
          }
      return true;
    }