Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add HTTP Headers to JAX-WS service response

I'm developing a Java Web Service. At this moment I can get Http header requests. But I want to add more header requests.

I'm currently doing this in a servlet filter.

@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);
    }
}

The problem with this strategy is that the added header is static.

With SoapHandler class I can obtain a SOAP message - dynamic:

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]", ""));
    }

So, what I really wanted was to join dynamic soap message with filter. How can I achieve this?

like image 930
Goldbones Avatar asked May 08 '15 17:05

Goldbones


1 Answers

While I'm still not entirely clear on what you really want, I will describe how to add HTTP headers in a SOAP web service response. The cleanest place to do this is in a JAX-WS handler, not unlike what you already have in the form of SoapClass.

To do this in your SOAPHandler, you must first obtain access to the list of headers in the underlying HttpServletResponse. This list is provided by the 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;
    }

An alternative approach is to access the HttpServletResponse that's underlying the web service response:

     @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;
    }
like image 165
kolossus Avatar answered Oct 11 '22 01:10

kolossus