The following code posted by Michael Binz could help you.
---------------------- START--------------------------------------
package .util;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.ByteArrayInputStream;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Properties;
import java.util.StringTokenizer;
import javax.xml.namespace.QName;
import javax.xml.rpc.encoding.TypeMapping;
import net.guardean.agw.*;
import net.guardean.agw.server.AgTransformer;
import net.guardean.agw.ws.schema.*;
import org.apache.axis.MessageContext;
import org.apache.axis.client.AxisClient;
import org.apache.axis.client.Call;
import org.apache.axis.description.TypeDesc;
import org.apache.axis.encoding.DeserializationContextImpl;
import org.apache.axis.encoding.SerializationContextImpl;
import org.apache.axis.message.RPCElement;
import org.apache.axis.message.SOAPEnvelope;
import org.apache.axis.message.SOAPBodyElement;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.AttributesImpl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.axis.encoding.ser.BaseDeserializerFactory;
import org.apache.axis.encoding.ser.BaseSerializerFactory;
import org.apache.axis.encoding.ser.BeanSerializerFactory;
import org.apache.axis.encoding.ser.BeanDeserializerFactory;
import org.apache.axis.encoding.ser.EnumDeserializerFactory;
import org.apache.axis.encoding.ser.EnumSerializerFactory;
/**
* Holds AG support functionality.
*
* @version $Revision: #4 $
* @author Michael Binz
*/
public class AgSupportLib
{
/**
* Logger used by this class
*/
private static final Log _logger =
LogFactory.getLog( AgSupportLib.class );
/**
* Generated classes from Axis. This table is only necessary on
Axis 1.1.
* Note that the classes commented with // enum ... require a special
* handling performed in registerAxisClassesInContext. Keep them as
* as comments here so that they arent forgotten.
*
* TODO Remove as soon as Axis 1.2 is used.
*/
private static Class generatedAxisClasses[]={
AddressType.class,
AgencyInformationType.class,
CompanyType.class,
ErrorMessageType.class,
FunctionType.class,
// enum GenderType.class,
LegalEventType.class,
MoneyType.class,
OptionalEntry.class,
PartyListType.class,
PartyMatrixType.class,
PartyType.class,
PersonType.class,
RatingType.class,
RequestType.class,
ResponseType.class,
ScoreType.class
};
private final static QName GenderTypeName =
new javax.xml.namespace.QName(
"http://ws.agw.guardean.net/schema",
getPlainClassName( GenderType.class ) );
/**
* Register a set of generated classes from Axis in a Message
Context
*
[EMAIL PROTECTED] pContext MessageContext where all the classes will be
registered
[EMAIL PROTECTED] pClassArray generated classes by Axis that will be register
in the
* context given as parameter
*/
private static void registerAxisClassesInContext(MessageContext
pContext, Class pClassArray[]){
Class currentClass = null;
//TODO Is there a way to check dynamically the classes
generated by Axis
//under the schema package??
//TODO Operation is not longer necessary on Axis 1.2. No need to
invest
// the time to make that finally cool on Axis 1.1 -- would be
expensive.
if (pContext == null)
return;
if (pClassArray == null){
_logger.warn("No generated classes from Axis in
system!.");
return;
}
TypeMapping typeMapping = pContext.getTypeMapping();
for(int i=0; i < pClassArray.length; i++){
try{
currentClass = pClassArray[i];
// get TypeDesc from class
Method gtd = currentClass.getMethod( "getTypeDesc",
null );
TypeDesc td = (TypeDesc)gtd.invoke( null, null );
// register serializer and deserializer for this
class
typeMapping.register(
currentClass,
td.getXmlType(),
BaseSerializerFactory.createFactory(BeanSerializerFactory.class,currentClass
,td.getXmlType()),
BaseDeserializerFactory.createFactory(BeanDeserializerFactory.class,currentC
lass,td.getXmlType())
);
}catch(Exception e){
_logger.error("No Axis generated class ("+
currentClass.getName()+")",e);
throw new IllegalArgumentException(
"No Axis generated class: " + currentClass.getName()
);
}
}
// Special handling for enumeration simple types.
// genderType
{
typeMapping.register(
GenderType.class,
GenderTypeName,
EnumSerializerFactory.createFactory(
EnumSerializerFactory.class,
GenderType.class,
GenderTypeName ),
EnumDeserializerFactory.createFactory(
EnumDeserializerFactory.class,
GenderType.class,
GenderTypeName ) );
}
}
/**
* <p>Transforms an instance of a type generated by Axis
* <code>WSDL2Java</code> into an XML representation, using only Axis
APIs.
* <p>Note that this implementation only works on Axis data types since
* only these are registered against the Axis runtime,</p>
*
* @param pO The object to be transformed.
* @param pQname The qualified name of the passed object. Note that
* passing the wrong value here does not result in an error, but
in
* the generation of a wrong XML structure. This can be accessed
* for a given type <i>Type</i> by the code
* <code><i>Type</i>.getTypeDesc().getXmlType()</code>.
* @return An XML-stringified representation of the input object.
* @deprecated Use the single parameter version of this operation.
QName
* autodetection is save and simple.
*/
private static String transformWsInstanceToXml( Object pO, QName pQname
)
{
// Since we are not in a message call context, we have to create a
// message context ourselves.
MessageContext mc = new MessageContext( new AxisClient() );
registerAxisClassesInContext( mc, generatedAxisClasses );
// This means that the XSI type attributes are not generated.
mc.setProperty( Call.SEND_TYPE_ATTR, "false" );
// This writer will ultimately receive the generated XML...
StringWriter result = new StringWriter();
// ...and is connected to the serialisation context.
SerializationContextImpl sci = new SerializationContextImpl(
result,
mc );
// Pretty print the result for convenience.
sci.setPretty( true );
// MultiRef'ing means that when object graphs are serialized, the
// identity of objects is kept, i.e. first the first level objects
are
// serialized with hrefs to the nested objects. After that the
nested
// objects are serialised and so on.
// This is not what we want. We want instead an in-place expansion
of
// nested objects without the hassle of object decomposition, we
have
// only plain vanilla data structures in the end.
sci.setDoMultiRefs( false );
try
{
// ...and perform the serialization.
sci.serialize(
pQname,
new AttributesImpl(),
pO );
}
catch ( IOException e )
{
// This exception is triggered by the java.io.Writer in the
// SerialisationContext. Since we use a StringWriter, we can
// guarantee that no IOExceptions will be thrown and safely
// ignore these.
_logger.warn( "java.io.StringWriter threw IOException.", e );
}
return result.toString();
}
/**
* Transforms the passed type into its XML representation. The passed
* object must represent a type generated by the Axis WSDL compiler.
*
* @param pO The object to be transformed.
* @return The passed object's XML representation in string format.
* @throws IllegalArgumentException If the passed object is not an
instance
* of an Axis-generated type.
*/
public static String axisToXml( Object pO )
{
Class oClass = pO.getClass();
try
{
// Get the type description via the static method.
Method gtd = oClass.getMethod( "getTypeDesc", null );
TypeDesc td = (TypeDesc)gtd.invoke( null, null );
// From the type description get the QName.
return transformWsInstanceToXml( pO, td.getXmlType() );
}
catch ( Exception e )
{
// Check whether this is one of the non-complex types in the
// package. In this case we synthesize a QName. Holy cow,
looking
// forward to Axis 1.2
return transformWsInstanceToXml(
pO,
new javax.xml.namespace.QName(
"http://ws.agw.guardean.net/schema",
getPlainClassName( pO.getClass() ) ) );
}
}
/**
* Transforms the passed type into its XML representation. The passed
* object must represent a type generated by the Axis WSDL compiler.
*
* @param pO The object to be transformed.
* @return The passed object's XML representation in string format.
* @deprecated Use axisToXml() instead.
* @throws IllegalArgumentException If the passed object is not an
instance
* of an Axis-generated type.
*/
public static String transformWsInstanceToXml( Object pO )
{
return axisToXml( pO );
}
/**
* Convert an XML structure created from an Axis-generated class back
into
* an object representation.
*
* @param xml The XML structure. Generated by
* <code>axisToXml( Object )</code>.
* @param pQname The qualified name of the target type.
* @return An instance of the Axis generated class.
* @see AgSupportLib#axisToXml(Object)
*/
public static Object xmlToAxis( String xml, QName pQname )
{
// TODO would be cool to dynamically detect the target qname. This
// could be done by looking at the first element's name in the
inbound
// XML data.
try
{
// Wrap the InputStream up into a SOAP Body and Envelope
since the parser
// expects a SOAP Envelope
SOAPEnvelope env1 = new SOAPEnvelope();
env1.addBodyElement(
new SOAPBodyElement(
new ByteArrayInputStream(xml.getBytes())));
// Since we are not in a message call context, we have to create
a
// message context ourselves.
MessageContext mc = new MessageContext( new AxisClient() );
// TODO: This following line manually registers the generated
type
// mappings. This has to be removed as soon as Axis 1.2 is
used.
registerAxisClassesInContext(mc,generatedAxisClasses);
InputSource is =
new InputSource( new StringReader( env1.toString() ) );
// ...and is connected to the serialisation context.
DeserializationContextImpl sci = new DeserializationContextImpl(
is, mc, org.apache.axis.Message.REQUEST );
sci.parse();
SOAPEnvelope env2 = sci.getEnvelope();
RPCElement rpcElem = (RPCElement) env2.getFirstBody();
// On Axis 1.2 use the getValueAsType( qname, class ) in the
next
// line and not the single arg version.
//return rpcElem.getValueAsType(qname, clazz);
return rpcElem.getValueAsType( pQname ); // Axis 1.1 code.
}
catch ( Exception e )
{
_logger.debug( "deserialisation problem.", e );
throw new IllegalArgumentException(
e.getMessage() );
}
}
/**
*
* @param pclass
* @return
*/
public static String getPlainClassName( Class pclass )
{
String fullyQualified = pclass.getName();
int lastDot = fullyQualified.lastIndexOf( '.' );
if ( lastDot == -1 )
return fullyQualified;
return fullyQualified.substring( lastDot+1 );
}
/**
* Test code.
*
* @param argv
*/
public static void main( String[] argv )
{
LegalEventType o = new LegalEventType();
o.setDate( new Date() );
o.setDescription( "This is a test for legal event serialisation." );
o.setHasExpired( Boolean.TRUE );
System.out.println( "Serialized Object. Description: " +
o.getDescription() );
System.out.println( "Serialized Object. hasExpired: " +
o.getHasExpired() );
System.out.println( "Serialized Object: Date: " +
o.getDate() );
String intermediateString = transformWsInstanceToXml( o );
Object deserialised = xmlToAxis(
intermediateString,
LegalEventType.getTypeDesc().getXmlType() );
LegalEventType t = (LegalEventType) deserialised;
System.out.println( "Deserialized Object. Description: " +
o.getDescription() );
System.out.println( "Deserialized Object. hasExpired: " +
o.getHasExpired() );
System.out.println( "Deserialized Object: Date: " +
o.getDate() );
//System.err.println( "" + deserialised );
GenderType gender = GenderType.FEMALE;
intermediateString = transformWsInstanceToXml( gender );
System.err.println( intermediateString );
deserialised = xmlToAxis( intermediateString, GenderTypeName );
System.err.println( deserialised.toString() );
Gender g = AgTransformer.transform( (GenderType)deserialised );
System.err.println( "Gender is: " + g );
}
}
-----------------------------------------------------------------------------
Regards,
- kiru
Laurent CORNELIS <[EMAIL PROTECTED]>
10/18/2004 06:37 AM
|
|
Hi,
Can someone tell me how to use BeanSerializer / Deserializer out of the context of a message ? (ie to encode an object to XML and to parse XML for an object).
For the serialization I do :
-------------------------------------------------------------------
MyObject obj = new MyObject();
FileWriter fout = new FileWriter("c:\\test.xml");
AxisClient client = new AxisClient();
MessageContext msgContext = new MessageContext(client);
SerializationContextImpl context = new SerializationContextImpl(
fout, msgContext);
context.setPretty(true);
context.setDoMultiRefs(false);
context.setSendDecl(true);
BeanSerializer s = (BeanSerializer) MyObject
.getSerializer(Constants.AXIS_SAX, MyObject.class,
MyObject.getTypeDesc().getXmlType());
s.serialize(MyObject.getTypeDesc().getXmlType(),
null, obj, context);
fout.flush();
fout.close();
-------------------------------------------------------------------
And it is working.
Now I don't know how to deserialize ... I tried this but it don't work :
-------------------------------------------------------------------
BeanDeserializer d = (BeanDeserializer)MyObject.getDeserializer(Constants.AXIS_SAX,MyObject.class,MyObject.getTypeDesc().getXmlType());
InputSource source = new InputSource("c:\\test.xml");
SAXParser p = XMLUtils.getSAXParser();
XMLReader reader = p.getXMLReader();
reader.setContentHandler(d);
reader.setDTDHandler(d);
reader.setEntityResolver(d);
reader.setErrorHandler(d);
reader.parse(source);
MyObject obj = (MyObject)d.getValue();
-------------------------------------------------------------------
[EMAIL PROTECTED]
11/10/2004 09:31 AM
|
|
Hi,
How do I envoke the serialization process for objects created by the WSDL2Java process. I would like to write the SOAP request and response objects out as XML to log4j during the processing of the request. These are complex objects generated directly from a wsdl. It is not clear to me how to envoke this process within Axis.
Thanks,
-mike