package it.corenet.j2ee.servlet; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Iterator; import java.util.StringTokenizer; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; import javax.servlet.ServletOutputStream; 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.messaging.JAXMServlet; // import javax.xml.messaging.ReqRespListener; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPMessage; import org.apache.log4j.Logger; import it.corenet.j2ee.common.LogUtils; import it.corenet.j2ee.consumer.SOAPConsumer; import it.corenet.j2ee.messages.Message; /** * Servlet che si occupa di ricevere messaggi SOAP, leggerne il body e spedire quest'ultimo ai servizi di back-end * (EJB). Le risposte ricevute dai servizi vengono analogamente reimbustate e spedite al client nel body di un altro * messaggio SOAP. * *

La servlet che deve definire, nel deployment descriptor, i seguenti parametri:
*

* * * * * * * * * * * * * * *
NomeDescrizioneTipoObbligatorio
sessionBeanIDL'identificativo del session bean da utilizzare per le comunicazioni con il servizio . Questo ID server per * fare il lookup sul JNDI context per recuperare la home interface del bean. La home interface deve essere una * {@link it.corenet.j2ee.servizi.ServizioRemoteHome ServizioRemoteHome} o una sottoclasse.StringSi
* * @author Federico Lelli * @cvsauthor $Author: flelli $ * @cvsdate $Date: 2008/03/18 11:20:25 $ * @cvsrevision $Revision: 1.5 $ */ // public class SOAPDispatcherServlet extends JAXMServlet implements ReqRespListener public class SOAPDispatcherServlet extends HttpServlet { /** Il nome del parametro che definisce l'id del session bean da utilizzare come Servizio. */ public static final String PNAME_SESSION_BEAN_ID = "sessionBeanID"; /** L'ID della home interface del bean utilizzato come servizio. */ private String beanID = null; /** Il logger di log4j. */ private Logger logger = null; /** L'istanza della message factory. */ private MessageFactory msgFactory = null; /** * Inizializza il logger. */ public SOAPDispatcherServlet() { super(); logger = Logger.getLogger(this.getClass()); } /** * Interpreta la richiesta http e scrive la risposta. * * @param request la richiesta * @param response la risposta * * @throws ServletException se la configurazione non e' corretta o manca di dati essenziali. * @throws IOException in caso di errori di IO o di comunicazione remota */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // logger.debug("Ricevuto messaggio SOAP"); try { MimeHeaders headers = getHeaders(request); ServletInputStream sis = request.getInputStream(); SOAPMessage soapReq = msgFactory.createMessage(headers, sis); logMessage("Ricevuto il messaggio SOAP di richiesta", soapReq); Message req = SOAPConsumer.fromSOAPMessage(soapReq); Message resp = ServletToolBox.performRequest(req, beanID, "EJB"); SOAPMessage soapResp = SOAPConsumer.toSOAPMessage(resp); logMessage("Istanziato il messaggio SOAP di risposta", soapResp); if (soapResp.saveRequired()) { soapResp.saveChanges(); } response.setStatus(200); putHeaders(soapResp.getMimeHeaders(), response); ServletOutputStream sos = response.getOutputStream(); soapResp.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true"); if (soapResp.countAttachments() > 0) { // Workaround JBWS-1620 (https://issues.jboss.org/browse/JBWS-1620) response.setHeader("Content-Length", Integer.toString(Integer.parseInt(soapResp.getMimeHeaders().getHeader("Content-Length")[0]) + 2)); sos.write(13); sos.write(10); } soapResp.writeTo(sos); sos.flush(); } catch (SOAPException se) { logger.error("ECCEZIONE COMPLETA: " + LogUtils.getCompleteExceptionString(se)); throw new ServletException(se); } } /** * Provvede alla configurazione della servlet. * * @param config la configurazione della servlet * * @throws ServletException se la configurazione non e' corretta o manca di dati essenziali. */ public void init(ServletConfig config) throws ServletException { super.init(config); initEJB(config); try { msgFactory = MessageFactory.newInstance(); } catch (SOAPException se) { throw new ServletException("Unable to create message factory", se); } } /** * Stampa il messaggio di log. * * @param arg0 la stringa da stampare * * @see javax.servlet.GenericServlet#log(String) */ public void log(String arg0) { logger.debug(arg0); } /** * Stampa il messaggio di log. * * @param arg0 la stringa da stampare * @param arg1 l'eccezione o errore da stampare * * @see javax.servlet.GenericServlet#log(String, Throwable) */ public void log(String arg0, Throwable arg1) { logger.debug(arg0, arg1); } /** * Recupera le header MIME dalla richiesta. * * @param request la richiesta http * * @return le header MIME */ private static MimeHeaders getHeaders(HttpServletRequest request) { Enumeration en = request.getHeaderNames(); MimeHeaders headers = new MimeHeaders(); while (en.hasMoreElements()) { String s = (String)en.nextElement(); String s1 = request.getHeader(s); for (StringTokenizer st = new StringTokenizer(s1, ","); st.hasMoreTokens(); headers.addHeader(s, st.nextToken().trim())) { ; } } return headers; } /** * Imposta le header MIME sulla risposta. * * @param headers le headers * @param response la risposta http */ private static void putHeaders(MimeHeaders headers, HttpServletResponse response) { for (Iterator it = headers.getAllHeaders(); it.hasNext();) { MimeHeader header = (MimeHeader)it.next(); String[] as = headers.getHeader(header.getName()); if (as.length == 1) { response.setHeader(header.getName(), header.getValue()); } else { StringBuffer sb = new StringBuffer(); for (int i = 0; i < as.length; i++) { if (i != 0) { sb.append(','); } sb.append(as[i]); } response.setHeader(header.getName(), sb.toString()); } } } /** * Recupera il session bean che rappresenta il servizio . * * @param config la configurazione della servlet * * @throws ServletException se la configurazione non e' corretta o manca di dati essenziali. */ private void initEJB(ServletConfig config) throws ServletException { beanID = config.getInitParameter(PNAME_SESSION_BEAN_ID); logger.debug("Il bean utilizzato e' " + beanID); if ((beanID == null) || ("".equals(beanID))) { throw new ServletException( "Impossibile determinare l'id del session bean dalla configurazione corrente. Definire il parametro '" + PNAME_SESSION_BEAN_ID + "'"); } } /** * Stampa il messaggio SOAP. * * @param commento commento al messaggio da stampare * @param mesg il messaggio da stampare */ private void logMessage(String commento, SOAPMessage mesg) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); mesg.writeTo(baos); logger.debug(commento + ": " + new String(baos.toByteArray())); } catch (IOException ioe) { logger.debug("Si e' verificato un errore di I/O durante il dump del messaggio SOAP", ioe); } catch (SOAPException se) { logger.debug("Si e' verificato un errore SOAP durante il dump del messaggio SOAP", se); } } }