Sunteți pe pagina 1din 15

Av. Canaval y Moreyra 380, 6to.

Piso, San Isidro


Tel: +51(1) 987500273 www.joedayz.org

SPRING WEB SERVICES


1.5
MTOM

SPRING-WS –Session 4 1
Av. Canaval y Moreyra 380, 6to.Piso, San Isidro
Tel: +51(1) 987500273 www.joedayz.org

Usar MTOM

Publicación del servicio

La idea para este ejemplo es crear un servicio que sea la


interfaz de un repositorio de archivos pdf, por lo tanto,
deberíamos poder pasarle el nombre de un archivo y éste
debería retornar el mismo en caso de encontrarlo. Teniendo en
mente esto, creamos nuestro contrato (contract-first):

De lo anterior, debemos prestar atención a la definición del


archivo, en donde le indicamos que es del tipo "base64Binary".
Una vez resuelto el contrato, debemos decirle a Spring Web
Services que lo publique. Esto lo hacemos a traves de un bean
especifico que a partir de un schema, crea el WSDL:

Configuramos la infraestructura de spring-ws en el web.xml:

SPRING-WS –Session 4 2
Av. Canaval y Moreyra 380, 6to.Piso, San Isidro
Tel: +51(1) 987500273 www.joedayz.org

Creamos el archivo de spring-ws-servlet.xml para definir los beans:

Procesar invocación
Debemos configurar la aplicación, para que pueda procesar pedidos del servicio que

publicamos en el paso anterior.

Primero definimos un bean que busca la anotacion @Endpoint (un endpoint es el

encargado de procesar el pedido):

SPRING-WS –Session 4 3
Av. Canaval y Moreyra 380, 6to.Piso, San Isidro
Tel: +51(1) 987500273 www.joedayz.org

Luego definimos un adaptador, para que procese el pedido de forma que el endpoint lo

pueda entender. Lo mismo hace con la respuesta:

Este adaptador necesita de un serializador. Aca es donde entra


el manejo del archivo binario. Vamos a utilizar JAXB:

El próximo paso es generar a partir del esquema, las clases de


'bindeo' de JAXB.

Cómo hemos configurado el plugin de JAXB en maven.

SPRING-WS –Session 4 4
Av. Canaval y Moreyra 380, 6to.Piso, San Isidro
Tel: +51(1) 987500273 www.joedayz.org

Colocamos una copia del xsd en main/resources

Los archivos generados se ubican en target y aprovechamos


para hacerlo carpeta de código fuente:

SPRING-WS –Session 4 5
Av. Canaval y Moreyra 380, 6to.Piso, San Isidro
Tel: +51(1) 987500273 www.joedayz.org

Una vez configurado JAXB, podemos proceder a implementar el


endpoint:

Debemos prestarle atención a la creación del DataHandler, el


cual se encarga de nuestro archivo binario. Luego es manejo
trivial de Spring Web Services y JAXB.

Cliente

Si bien el cliente podría ser un test del servidor, vamos a crear en este ejemplo otro

modulo web, por un lado para no confundir la configuración entre cliente y servidor y

por el otro para poder visualizar en el browser el pdf.

Básicamente vamos a tener un servlet, que invoca al servicio y luego escribe el pdf a

la pagina.

Configurar cliente

SPRING-WS –Session 4 6
Av. Canaval y Moreyra 380, 6to.Piso, San Isidro
Tel: +51(1) 987500273 www.joedayz.org

Primero definimos un bean, indicando donde está el servicio:

Luego definimos el cliente. Para esta primera versión usaremos


SAAJ:

En el caso de utilizar Saaj, vamos a necesitar indicarle un


serializador, y al igual que en el servidor, vamos a utilizar JAXB:

Implementar el cliente
Para invocar servicios, Spring Web Services provee de una clase utilitaria que facilita

bastante las cosas: WebServiceTemplate. En la configuración que realizamos en el

SPRING-WS –Session 4 7
Av. Canaval y Moreyra 380, 6to.Piso, San Isidro
Tel: +51(1) 987500273 www.joedayz.org

paso anterior nos adelantamos a esto, indicándole a nuestro cliente donde estaba el

servicio.

El WebServiceTemplate lo podemos obtener, heredando


de WebServiceGatewaySupport:

Lo que resta es el método principal que se encargue de enviar


el pedido y procesar la respuesta:

La clase DataHandler nos permite obtener un InputStream para


ir leyendo el pdf.

SPRING-WS –Session 4 8
Av. Canaval y Moreyra 380, 6to.Piso, San Isidro
Tel: +51(1) 987500273 www.joedayz.org

A continuación la implementación del servlet:

package pe.joedayz.clientePdf.mtom.web;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.context.WebApplicationContext;
import
org.springframework.web.context.support.WebApplicationContextUtils;

import pe.joedayz.clientePdf.mtom.ws.SaajMtomClient;

/**
* Servlet de ejemplo que imprime en la pagina el pdf, para poder
visualizarlo.
*
* @author JoeDayz
*/
public class ExportarPdfServlet extends HttpServlet {

/**
* Processes requests for both HTTP <code>GET</code> and
<code>POST</code> methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request,

SPRING-WS –Session 4 9
Av. Canaval y Moreyra 380, 6to.Piso, San Isidro
Tel: +51(1) 987500273 www.joedayz.org

HttpServletResponse response) throws ServletException,


IOException {
response.setContentType("application/pdf");
OutputStream out = response.getOutputStream();
try {
WebApplicationContext webApplicationContext =
WebApplicationContextUtils.
getWebApplicationContext(request.getSession().
getServletContext());
//Elegir el cliente de acuerdo a cual se implementó.
//AxiomMtomClient axiomClient = (AxiomMtomClient)
webApplicationContext.getBean("axiomClient");
SaajMtomClient saajClient = (SaajMtomClient)
webApplicationContext.getBean("saajClient");
InputStream inputStream =
saajClient.loadPdf("mtom.pdf").
getInputStream();
//hay varias formas de escribirlo al outputstream, aca
una sencilla para el ejemplo.
int cantidadLeida = 0;
byte buffer[] = new byte[256];
while ((cantidadLeida = inputStream.read(buffer))!= -1)
{
out.write(buffer, 0, cantidadLeida);
}
} finally {
out.close();
}
}

// <editor-fold defaultstate="collapsed" desc="HttpServlet


methods. Click on the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

SPRING-WS –Session 4 10
Av. Canaval y Moreyra 380, 6to.Piso, San Isidro
Tel: +51(1) 987500273 www.joedayz.org

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Returns a short description of the servlet.
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>

Solo resta configurar el modulo para que levante la


configuración de Spring Web Services. En el web.xml definimos
un listener y le indicamos donde está el archivo con la
configuración:

SPRING-WS –Session 4 11
Av. Canaval y Moreyra 380, 6to.Piso, San Isidro
Tel: +51(1) 987500273 www.joedayz.org

PRUEBAS

1.- WSDL

http://localhost:28080/servidorPdf/ws/pdf/mtom.wsdl

2.- http://localhost:28080/clientePdf/ExportarPdf

3.- Si queremos usar un cliente con AXIOM

Añadimos al POM.xml

SPRING-WS –Session 4 12
Av. Canaval y Moreyra 380, 6to.Piso, San Isidro
Tel: +51(1) 987500273 www.joedayz.org

Luego creamos la clase:

package pe.joedayz.clientePdf.mtom.ws;

import java.io.IOException;
import java.util.Iterator;
import javax.activation.DataHandler;
import javax.xml.transform.TransformerException;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.OMText;
import org.apache.axiom.soap.SOAPMessage;
import org.apache.axiom.soap.SOAPBody;
import org.apache.axiom.soap.SOAPFactory;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.client.core.WebServiceMessageCallback;
import org.springframework.ws.client.core.WebServiceMessageExtractor;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import org.springframework.ws.soap.axiom.AxiomSoapMessage;
import org.springframework.ws.soap.axiom.AxiomSoapMessageFactory;

/**
* Cliente que invoca a un servicio que retorna como respuesta un pdf, utilizando MTOM
y AXIOM.
*
* @author dosideas
*/
public class AxiomMtomClient extends WebServiceGatewaySupport {

/**
* Construye el cliente a traves de la message factory.
* @param messageFactory message factory que utiliza AXIOM.
*/
public AxiomMtomClient(AxiomSoapMessageFactory messageFactory) {
super(messageFactory);
}

/**
* Carga un pdf en un DataHandler para luego poder leerlo.
* @param path donde se encuentra el pdf.
* @return un DataHandler que contiene el pdf.
*/
public DataHandler loadPdf(final String path){
final StringBuilder name = new StringBuilder();
DataHandler dataHandler = (DataHandler)
getWebServiceTemplate().sendAndReceive(new WebServiceMessageCallback() {
/**
* Le agrega al mensaje, el request con la operacion que se quiere ejecutar
del web service. Es necesario
* conocer el schema del servicio.
*/
public void doWithMessage(WebServiceMessage message) throws IOException,
TransformerException {
SOAPMessage axiomMessage = ((AxiomSoapMessage)
message).getAxiomMessage();
SOAPFactory factory = (SOAPFactory) axiomMessage.getOMFactory();
SOAPBody body = axiomMessage.getSOAPEnvelope().getBody();

SPRING-WS –Session 4 13
Av. Canaval y Moreyra 380, 6to.Piso, San Isidro
Tel: +51(1) 987500273 www.joedayz.org

OMNamespace ns =
factory.createOMNamespace("http://www.joedayz.pe/spring-ws/ejemplos/mtom", "tns");

OMElement loadPdfRequestElement =
factory.createOMElement("LoadPdfRequest", ns);
loadPdfRequestElement.setText(StringUtils.getFilename(path));
body.addChild(loadPdfRequestElement);
}
}, new WebServiceMessageExtractor() {
/**
* Obtiene de la respuesta, el DataHandler que tiene adentro el pdf. Es
necesario
* conocer el schema del servicio.
*/
public Object extractData(WebServiceMessage message) throws IOException,
TransformerException {
SOAPMessage axiomMessage = ((AxiomSoapMessage)
message).getAxiomMessage();
SOAPBody body = axiomMessage.getSOAPEnvelope().getBody();
OMElement loadPdfResponseElement = (OMElement)
body.getChildElements().next();

Assert.isTrue("LoadPdfResponse".equals(loadPdfResponseElement.getLocalName()));
Iterator childElements = loadPdfResponseElement.getChildElements();
OMElement nameElement = (OMElement) childElements.next();
Assert.isTrue("name".equals(nameElement.getLocalName()));
name.append(nameElement.getText());
OMElement fileElement = (OMElement) childElements.next();
Assert.isTrue("file".equals(fileElement.getLocalName()));
OMText text = (OMText) fileElement.getFirstOMChild();
text.setBinary(true);
text.setContentID("pdf");

return (DataHandler) text.getDataHandler();


}
});

return dataHandler;
}

Definimos en cliente-springws.xml

Y cambiamos en el servlet para que use axiom.

SPRING-WS –Session 4 14
Av. Canaval y Moreyra 380, 6to.Piso, San Isidro
Tel: +51(1) 987500273 www.joedayz.org

SPRING-WS –Session 4 15

S-ar putea să vă placă și