向JAX-WS服务响应添加HTTP头

11

我正在开发一个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]", ""));
    }

所以,我真正想做的是将动态SOAP消息与过滤器结合起来。我该如何实现这一点?


“the header is static”是什么意思?静态头部和动态头部有什么区别? - kolossus
"Operation","something"是我定义的静态值。我希望能够为每个请求设置不同的Soap内容。 - Goldbones
我还是不明白:什么是“值静态”和“肥皂内容”?您是否想根据条件设置HTTP标头?还是您想设置SOAP标头?“我希望能够为每个请求设置不同的SOAP内容”真的翻译得不太好。您能发布一张插图或其他东西吗? - kolossus
1个回答

10

虽然我还不完全清楚你想要什么,但是我会描述如何在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;
    }

另一种方法是访问底层的HttpServletResponse,该响应是Web服务响应的基础:

     @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
1
我的错误 @Goldbones;应该是 HTTP_RESPONSE_HEADERS 而不是 HTTP_REQUEST_HEADERS。我也发布了一种替代方法。你已经尝试过的方法应该始终是问题的一部分:这样可以节省每个人的时间,并且问题更好。 - kolossus
太好了!这正是我想要的。我在另一篇帖子中尝试过,但没有人能给出合适的答案。在你提供的代码中,我有了动态内容(通过Soap消息上下文),这非常棒,因为现在我可以为不同的请求提供不同的消息。谢谢! - Goldbones
2
@kolossus 我知道这是一个旧帖子,但是谢谢你,你的后一种变体让我克服了困难,尽管响应布尔值总是返回 null。然而,HttpServ.. 响应从未为 null,因此我不需要进行布尔检查。谢谢! - Alan Smith
在“//如果还没有HTTP头映射,请创建一个新的”上,您不应该将映射放在上下文中吗? - slindenau
@slindenau 没错,你是对的。 - kolossus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接