FileDocCategorySizeDatePackage
SAAJServlet.javaAPI DocExample5444Tue Jul 23 23:08:18 BST 2002ora.jwsnut.saaj

SAAJServlet.java

package ora.jwsnut.saaj;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.StringTokenizer;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeader;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;

/**
 * A servlet that can be used to host a SAAJ
 * service within a web container. This is based
 * on ReceivingServlet.java in the JWSDP tutorial
 * examples.
 */
public abstract class SAAJServlet extends HttpServlet {
    
    /**
     * The factory used to build messages
     */
    protected MessageFactory messageFactory;
    
    /**
     * Initialisation - create the MessageFactory
     */
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        try {
            messageFactory = MessageFactory.newInstance();
        } catch (SOAPException ex) {
            throw new ServletException("Failed to create MessageFactory", ex);
        }
    }
    
    /**
     * Handles a POST request from a client. The request is assumed
     * to contain a SOAP message with the HTTP binding.
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response) 
                            throws ServletException, IOException {
                                
        try {                            
            // Get all the HTTP headers and convert them to a MimeHeaders object
            MimeHeaders mimeHeaders = getMIMEHeaders(request);

            // Create a SOAPMessage from the content of the HTTP request
            SOAPMessage message = messageFactory.createMessage(mimeHeaders,
                                                request.getInputStream());
            
            // Let the subclass handle the message
            SOAPMessage reply = onMessage(message);
            
            // If there is a reply, return it to the sender.
            if (reply != null) {
                // Set OK HTTP status, unless there is a fault.
                boolean hasFault = reply.getSOAPPart().getEnvelope().getBody().hasFault();
                response.setStatus(hasFault ? 
                                    HttpServletResponse.SC_INTERNAL_SERVER_ERROR :
                                    HttpServletResponse.SC_OK);
                
                // Force generation of the MIME headers
                if (reply.saveRequired()) {
                    reply.saveChanges();
                }
                
                // Copy the MIME headers to the HTTP response
                setHttpHeaders(reply.getMimeHeaders(), response);
                
                // Send the completed message
                OutputStream os = response.getOutputStream();
                reply.writeTo(os);
                os.flush();
            } else {
                // No reply - set the HTTP status to indicate this
                response.setStatus(HttpServletResponse.SC_NO_CONTENT);
            }               
        } catch (SOAPException ex) {
            throw new ServletException("SOAPException: " + ex);
        }       
    }
    
    /**
     * Method implemented by subclasses to handle a received SOAP message.
     * @param message the received SOAP message.
     * @return the reply message, or <code>null</code> if there is
     * no reply to be sent.
     */
    protected abstract SOAPMessage onMessage(SOAPMessage message) throws SOAPException;
    
    /**
     * Creates a MIMEHeaders object from the HTTP headers
     * received with a SOAP message.
     */
    private MimeHeaders getMIMEHeaders(HttpServletRequest request) {
        MimeHeaders mimeHeaders = new MimeHeaders();
        Enumeration enum = request.getHeaderNames();
        while (enum.hasMoreElements()) {
            String headerName = (String)enum.nextElement();
            String headerValue = request.getHeader(headerName);
            StringTokenizer st = new StringTokenizer(headerValue, ",");
            while (st.hasMoreTokens()) {
                mimeHeaders.addHeader(headerName, st.nextToken().trim());
            }
        }
        return mimeHeaders;
    } 
    
    /**
     * Converts the MIMEHeaders for a SOAP message to 
     * HTTP headers in the response.
     */
    private void setHttpHeaders(MimeHeaders mimeHeaders, HttpServletResponse response) {
        Iterator iter = mimeHeaders.getAllHeaders();
        while (iter.hasNext()) {
            MimeHeader mimeHeader = (MimeHeader)iter.next();
            String headerName = mimeHeader.getName();
            String[] headerValues = mimeHeaders.getHeader(headerName);
            
            int count = headerValues.length;
            StringBuffer buffer = new StringBuffer();
            for (int i = 0; i < count; i++) {
                if (i != 0) {
                    buffer.append(',');
                }
                buffer.append(headerValues[i]);
            }            
            response.setHeader(headerName, buffer.toString());
        }        
    }
}