【问题标题】:Add HTTP Headers to JAX-WS service response将 HTTP 标头添加到 JAX-WS 服务响应
【发布时间】:2015-07-19 17:22:06
【问题描述】:

我正在开发 Java Web 服务。此时我可以获取 Http 标头请求。但我想添加更多标头请求。

我目前正在 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);
    }
}

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

使用 SoapHandler 类,我可以获得 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]", ""));
    }

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

【问题讨论】:

  • “标题是静态的”是什么意思?什么是静态标头与动态标头?
  • "Operation", "something" 是我定义的静态值。我希望能够为每个请求提供不同的肥皂内容
  • 我还是不明白:什么是“价值静态”与“肥皂内容”?您是否希望根据条件设置 HTTP 标头?或者您要设置 SOAP 标头? 我希望能够为每个请求提供不同的 Soap 内容 确实翻译得不是很好。能发个插图什么的吗?

标签: java servlets soap jax-ws


【解决方案1】:

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

要在您的 SOAPHandler 中执行此操作,您必须首先获得对底层 HttpServletResponse 中标头列表的访问权限。此列表由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;
    }

另一种方法是访问作为 Web 服务响应基础的 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;
    }

【讨论】:

  • 我之前尝试过这种方法。我收到一个异常 - request.headers 是一个只读属性。
  • 我的错误@Goldbones;它应该是HTTP_RESPONSE_HEADERS 而不是HTTP_REQUEST_HEADERS。我也发布了另一种方法。您已经尝试过的方法应该始终成为您问题的一部分:节省每个人的时间并提出更好的问题。
  • 完美!这正是我想要的。我在另一篇文章中这样做了,但没有人能给出适当的答案。在您提供的代码中,而不是静态内容(“某事”在不同的请求中总是相同的答案)我有动态内容(通过 Soap 消息上下文),这很好,因为现在我有不同的消息用于不同的请求。谢谢!
  • @kolossus 我知道这是一篇旧帖子,但谢谢,你的后一种变化让我克服了困难,尽管响应布尔值总是返回 null。然而,HttpServ.. 响应永远不会为空,所以我不需要布尔检查。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-25
  • 2016-02-10
相关资源
最近更新 更多