{section}
{column}
This document is a complement to the documentation of the Petals SE-JSR181 component.
It assumes that you already know how to generate a JSR181 SU using PetalsStudio: most code examples detailed here are embedded in the JSR181 SU main class, pointed as <jsr181:class> in the jbi.xml of the SU.
{column}
{column}
{panel:title=Table of Contents}{toc}{panel}
{column}
{section}
h1. Implementing a web method that deals with complex types and attachments
h2. Text File Extraction
This example receives a text file as an attachment and returns its content to the client.
Attachment's style is MTOM.
{code}
package com.ebmwebsourcing;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.activation.DataHandler;
import javax.jws.WebMethod;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.BindingType;
import javax.xml.ws.soap.SOAPBinding;
/**
* Here is a sample JAX-WS implementation.
*/
@WebService( serviceName="Test", targetNamespace="http://ebmwebsourcing.com", portName="TestPort" )
@BindingType(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
public class Test {
/* (non-Javadoc)
* @see JaxWSInterface#HelloWorld()
*/
@WebMethod( operationName="extractContent" )
@WebResult( name="returnMessage" )
public String extractContent( DataHandler textDocument ) {
String result = "An error occurred.";
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
copyStream( textDocument.getInputStream(), os );
result = os.toString( "UTF-8" );
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* Copies the content from in into os.
* <p>
* Neither <i>in</i> nor <i>os</i> are closed by this method.<br />
* They must be explicitly closed after this method is called.
* </p>
*
* @param in
* @param os
* @throws IOException
*/
public static void copyStream( InputStream in, OutputStream os ) throws IOException {
byte[] buf = new byte[ 1024 ];
int len;
while((len = in.read( buf )) > 0) {
os.write( buf, 0, len );
}
}
}
{code}
h2. Upload method in SU main class (JAX-WS annotated)
This example is an upload method: it receives path + file name information (where to store the file) as a parameter, and a file to upload (as a binary attachment). In this example, we retrieve attachments directly from the Petals exchange.
{code}
@WebMethod( operationName="upload" )
public String upload(@WebParam( name="destination" ) UploadDestination dest) {
// Get the JBI context
JBIContext jbiContext = JBIContextManager.getJBIContext();
Exchange exchange = jbiContext.getExchange();
try {
Set<DataHandler> atts = exchange.getInMessageAttachments();
int n = 0;
for(DataHandler att : atts) {
if(n == 1) { // Ignore 1st attachment (bug workaround... may be useless with latest release ?)
FileOutputStream out = new FileOutputStream(dest.getPath() + File.separator + dest.getName());
InputStream in = att.getInputStream();
byte buf[] = new byte[256];
while(in.read(buf) >= 0) {
out.write(buf);
}
out.close();
}
n++;
}
} catch (Exception e) {
Logger.getLogger( getClass().getName()).severe("Upload error: " + e.getMessage());
}
return "upload destination=" + dest;
}
{code}
h2. Class for complex type parameter
This class is a simple JavaBean (POJO with getter/setter methods for each field: here, fields are "path" and "name", as the class represents an "upload destination" = a file).
{code}
package org.ow2.petals.usecase.jsr181;
public class UploadDestination {
String name_ = "/tmp";
String path_ = "petals-attachment";
public String getName() {
return name_;
}
public void setName(String name) {
this.name_ = name;
}
public String getPath() {
return path_;
}
public void setPath(String path) {
this.path_ = path;
}
public String toString() { return (path_ == null ? "" : path_) + "/" + name_; }
}
{code}
h1. Invoking a Petals service
This class illustrates how a JSR-181 implementation can invoke a Petals service.
The invoked service is here a mailing service.
{code}
package org.ow2.sample;
import java.util.logging.Logger;
import javax.jbi.messaging.MessagingException;
import javax.jws.Oneway;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.namespace.QName;
import org.ow2.petals.component.framework.api.Message.MEPConstants;
import org.ow2.petals.component.framework.api.exception.PEtALSCDKException;
import org.ow2.petals.component.framework.api.message.Exchange;
import org.ow2.petals.jsr181.JBIContext;
import org.ow2.petals.jsr181.JBIContextManager;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.ebmwebsourcing.easycommons.xml.DocumentBuilders;
/**
* Here is a sample JAX-WS implementation.
*/
@WebService( serviceName="MailProxyService", targetNamespace="http://sample.ow2.org", portName="MailProxyServicePort" )
public class MailProxyService {
/* (non-Javadoc)
* @see JaxWSInterface#HelloWorld()
*/
@WebMethod( operationName="helloWorld" )
@WebResult( name="returnMessage" )
public String helloWorld() {
return "Hello World!";
}
/*
* (non-Javadoc)
* @see toto.JaxWSInterface
* #propagateMessage(java.lang.String)
*/
@WebMethod( operationName="listenToTheWorld" )
@Oneway
public void propagateMessage( @WebParam( name="message" ) String message ) {
// We here illustrate a method that does not return anything.
// This method uses a Petals extension to invoke other services in the bus.
// Get the JBI context
JBIContext jbiContext = JBIContextManager.getJBIContext();
// Create the mail content
StringBuilder mailContent = new StringBuilder();
mailContent.append( "Propagating the received message...\n" ).append( message );
// Create a XML document...
final String MAIL_NS = "http://petals.ow2.org/components/mail/version-3";
Document mailDocument = DocumentBuilders.newDocument();
final Element mailElement = mailDocument.createElementNS( MAIL_NS, "mail" );
mailDocument.appendChild( mailElement );
final Element bodyElement = mailDocument.createElementNS( MAIL_NS, "body" );
mailElement.appendChild( bodyElement );
bodyElement.setTextContent( mailContent.toString());
// ... and send it to a mailing service.
try {
final Exchange mailExchange = jbiContext.getMessageSender().createExchange( MEPConstants.IN_ONLY_PATTERN );
mailExchange.setInterfaceName( new QName( "http://petals.ow2.org/components/mail/version-3", "Mail" ));
mailExchange.setService( new QName( "http://petals.ow2.org/components/mail/version-3", "ReportMailService" ));
mailExchange.setOperation(new QName("http://petals.ow2.org/components/mail/version-3", "SendMail"));
mailExchange.setInMessageContent( mailDocument );
// Synchronous invocation
jbiContext.getMessageSender().send( mailExchange );
} catch( MessagingException e ) {
Logger.getLogger( getClass().getName()).severe( "Failed to send a message to the Petals Mail component. Messaging error." );
} catch( PEtALSCDKException e ) {
Logger.getLogger( getClass().getName()).severe( "Failed to send a message to the Petals Mail component. Petals CDK error." );
}
}
}
{code}
{column}
This document is a complement to the documentation of the Petals SE-JSR181 component.
It assumes that you already know how to generate a JSR181 SU using PetalsStudio: most code examples detailed here are embedded in the JSR181 SU main class, pointed as <jsr181:class> in the jbi.xml of the SU.
{column}
{column}
{panel:title=Table of Contents}{toc}{panel}
{column}
{section}
h1. Implementing a web method that deals with complex types and attachments
h2. Text File Extraction
This example receives a text file as an attachment and returns its content to the client.
Attachment's style is MTOM.
{code}
package com.ebmwebsourcing;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.activation.DataHandler;
import javax.jws.WebMethod;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.BindingType;
import javax.xml.ws.soap.SOAPBinding;
/**
* Here is a sample JAX-WS implementation.
*/
@WebService( serviceName="Test", targetNamespace="http://ebmwebsourcing.com", portName="TestPort" )
@BindingType(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
public class Test {
/* (non-Javadoc)
* @see JaxWSInterface#HelloWorld()
*/
@WebMethod( operationName="extractContent" )
@WebResult( name="returnMessage" )
public String extractContent( DataHandler textDocument ) {
String result = "An error occurred.";
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
copyStream( textDocument.getInputStream(), os );
result = os.toString( "UTF-8" );
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* Copies the content from in into os.
* <p>
* Neither <i>in</i> nor <i>os</i> are closed by this method.<br />
* They must be explicitly closed after this method is called.
* </p>
*
* @param in
* @param os
* @throws IOException
*/
public static void copyStream( InputStream in, OutputStream os ) throws IOException {
byte[] buf = new byte[ 1024 ];
int len;
while((len = in.read( buf )) > 0) {
os.write( buf, 0, len );
}
}
}
{code}
h2. Upload method in SU main class (JAX-WS annotated)
This example is an upload method: it receives path + file name information (where to store the file) as a parameter, and a file to upload (as a binary attachment). In this example, we retrieve attachments directly from the Petals exchange.
{code}
@WebMethod( operationName="upload" )
public String upload(@WebParam( name="destination" ) UploadDestination dest) {
// Get the JBI context
JBIContext jbiContext = JBIContextManager.getJBIContext();
Exchange exchange = jbiContext.getExchange();
try {
Set<DataHandler> atts = exchange.getInMessageAttachments();
int n = 0;
for(DataHandler att : atts) {
if(n == 1) { // Ignore 1st attachment (bug workaround... may be useless with latest release ?)
FileOutputStream out = new FileOutputStream(dest.getPath() + File.separator + dest.getName());
InputStream in = att.getInputStream();
byte buf[] = new byte[256];
while(in.read(buf) >= 0) {
out.write(buf);
}
out.close();
}
n++;
}
} catch (Exception e) {
Logger.getLogger( getClass().getName()).severe("Upload error: " + e.getMessage());
}
return "upload destination=" + dest;
}
{code}
h2. Class for complex type parameter
This class is a simple JavaBean (POJO with getter/setter methods for each field: here, fields are "path" and "name", as the class represents an "upload destination" = a file).
{code}
package org.ow2.petals.usecase.jsr181;
public class UploadDestination {
String name_ = "/tmp";
String path_ = "petals-attachment";
public String getName() {
return name_;
}
public void setName(String name) {
this.name_ = name;
}
public String getPath() {
return path_;
}
public void setPath(String path) {
this.path_ = path;
}
public String toString() { return (path_ == null ? "" : path_) + "/" + name_; }
}
{code}
h1. Invoking a Petals service
This class illustrates how a JSR-181 implementation can invoke a Petals service.
The invoked service is here a mailing service.
{code}
package org.ow2.sample;
import java.util.logging.Logger;
import javax.jbi.messaging.MessagingException;
import javax.jws.Oneway;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.namespace.QName;
import org.ow2.petals.component.framework.api.Message.MEPConstants;
import org.ow2.petals.component.framework.api.exception.PEtALSCDKException;
import org.ow2.petals.component.framework.api.message.Exchange;
import org.ow2.petals.jsr181.JBIContext;
import org.ow2.petals.jsr181.JBIContextManager;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.ebmwebsourcing.easycommons.xml.DocumentBuilders;
/**
* Here is a sample JAX-WS implementation.
*/
@WebService( serviceName="MailProxyService", targetNamespace="http://sample.ow2.org", portName="MailProxyServicePort" )
public class MailProxyService {
/* (non-Javadoc)
* @see JaxWSInterface#HelloWorld()
*/
@WebMethod( operationName="helloWorld" )
@WebResult( name="returnMessage" )
public String helloWorld() {
return "Hello World!";
}
/*
* (non-Javadoc)
* @see toto.JaxWSInterface
* #propagateMessage(java.lang.String)
*/
@WebMethod( operationName="listenToTheWorld" )
@Oneway
public void propagateMessage( @WebParam( name="message" ) String message ) {
// We here illustrate a method that does not return anything.
// This method uses a Petals extension to invoke other services in the bus.
// Get the JBI context
JBIContext jbiContext = JBIContextManager.getJBIContext();
// Create the mail content
StringBuilder mailContent = new StringBuilder();
mailContent.append( "Propagating the received message...\n" ).append( message );
// Create a XML document...
final String MAIL_NS = "http://petals.ow2.org/components/mail/version-3";
Document mailDocument = DocumentBuilders.newDocument();
final Element mailElement = mailDocument.createElementNS( MAIL_NS, "mail" );
mailDocument.appendChild( mailElement );
final Element bodyElement = mailDocument.createElementNS( MAIL_NS, "body" );
mailElement.appendChild( bodyElement );
bodyElement.setTextContent( mailContent.toString());
// ... and send it to a mailing service.
try {
final Exchange mailExchange = jbiContext.getMessageSender().createExchange( MEPConstants.IN_ONLY_PATTERN );
mailExchange.setInterfaceName( new QName( "http://petals.ow2.org/components/mail/version-3", "Mail" ));
mailExchange.setService( new QName( "http://petals.ow2.org/components/mail/version-3", "ReportMailService" ));
mailExchange.setOperation(new QName("http://petals.ow2.org/components/mail/version-3", "SendMail"));
mailExchange.setInMessageContent( mailDocument );
// Synchronous invocation
jbiContext.getMessageSender().send( mailExchange );
} catch( MessagingException e ) {
Logger.getLogger( getClass().getName()).severe( "Failed to send a message to the Petals Mail component. Messaging error." );
} catch( PEtALSCDKException e ) {
Logger.getLogger( getClass().getName()).severe( "Failed to send a message to the Petals Mail component. Petals CDK error." );
}
}
}
{code}