- PR -

Axisにserializerを組み込む

1
投稿者投稿内容
ドナ
常連さん
会議室デビュー日: 2003/07/08
投稿数: 42
投稿日時: 2003-12-21 14:28
UKです。
Axisにシリアライザーを組み込みApache SOAPでサポートされていない
型でもJava2WSDLやWSDL2Javaでサービス作成を行うことについて勉強しています。
コード:
public class NodeSerializer implements Serializer {
        public void serialize(QName name, Attributes attributes,
                          Object value, SerializationContext context)
        throws IOException
    {
        if (!(value instanceof Node))
            throw new IOException(Messages.getMessage("cantSerialize01"));

        context.startElement(name, attributes);
    	Node node = (Node)value;
    	    	context.writeString(getValueAsString(value, context));
        context.endElement();
    }

	public String getValueAsString(Object value, SerializationContext context){
		try{
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.reset();
			oos.writeObject(value);
			oos.flush();
			byte[] data = baos.toByteArray();
		
			String str = new String(data, "utf-8");
			return str;
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}
	
    public String getMechanismType() { return Constants.AXIS_SAX; }

    public Element writeSchema(Class javaType, Types types) throws Exception {
        return null;
    }
}

public class NodeDeserializer extends SimpleDeserializer
{
	 private DeserializationContext context = null;
	
    public NodeDeserializer(Class javaType, QName xmlType) {
        super(javaType, xmlType);
    }

    public Object makeValue(String str) throws Exception {
    	try{
			byte[] b = str.getBytes();
			ByteArrayInputStream bais = new ByteArrayInputStream(b);
			ObjectInputStream ois = new ObjectInputStream(bais);
			Node node = (Node)ois.readObject();
			return node;
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
    } 	
	 public void onStartElement(String namespace, String localName,
                               String prefix, Attributes attributes,
                               DeserializationContext context)
            throws SAXException 
    {
        this.context = context;
    } }





の様に既存のDataSerializerなどのソースを参考に
シリアライザー、デシリアライザーを作成しました。

クライアントプログラムを実行すると

org.xml.sax.SAXParseException: An invalid XML character (Unicode: 0x0
) was found in the element content of the document.

っといったエラーがでます。
シリアライザーの作成方法自体根本的に間違っているのでしょうか?
変換する際のエンコードが間違っているのかと思ってしらべましたが、解決できませんでした。
どなたかご教授宜しくお願いします。
t-wata
大ベテラン
会議室デビュー日: 2002/07/12
投稿数: 209
お住まい・勤務地: 東京
投稿日時: 2003-12-22 12:01
> シリアライザーの作成方法自体根本的に間違っているのでしょうか?

間違っています。何が間違っているかと言うと、ObjectOutputStreamでオブジェクト
を直列化したバイト配列をそのまま文字列にしている点です。
getValueAsStringはXML表現を返す必要があります。他のシリアライザーの実装を見てみるとよいでしょう。
ドナ
常連さん
会議室デビュー日: 2003/07/08
投稿数: 42
投稿日時: 2003-12-22 23:14
t-wataさんのご指摘通り他のシリアラーザーの実装を見て
自分なりに作り直してみました

serializerについて
getValueAsStringでの返り値をBase64.encode(data, 0, data.length)
に変更し、deserializerをBase64Deserializerをextendsして作成
すると期待通りの結果を得ることができました。

そこでserializerの方をgetValueAsStringを使用せずにBase64Serializerをextendsして
作成し直すとBase64Serializerでエラーがでます。
コード:

public class NodeSerializer extends Base64Serializer {
public NodeSerializer(Class javaType, QName xmlType) {
super(javaType, xmlType);
}

public void serialize(QName name, Attributes attributes,
Object value, SerializationContext context)
throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.reset();
oos.writeObject(value);
oos.flush();
byte[] data = baos.toByteArray();
super.serialize(name, attributes, data, context);
}

public String getMechanismType() { return Constants.AXIS_SAX; }

public Element writeSchema(Class javaType, Types types) throws Exception {
return null;
}
}



するとクライアント側で
at org.apache.axis.encoding.ser.Base64Serializer.getValueAsString(Base64
Serializer.java:102)
at org.apache.axis.encoding.ser.Base64Serializer.serialize(Base64Seriali
zer.java:93)
といったエラーがでます

Base64Serialzier.java:102を見ましたが、そこでClassCastExceptionが発生しているようです。ナゼなのでしょう?Base64Serializerのserializeメソッドの第3引数にはバイト配列
をわたしてまいけないのでしょうか?
すみませんが、もう少しお力添え宜しくお願いします

[ メッセージ編集済み 編集者: UK 編集日時 2003-12-23 10:59 ]
t-wata
大ベテラン
会議室デビュー日: 2002/07/12
投稿数: 209
お住まい・勤務地: 東京
投稿日時: 2003-12-24 17:45
new NodeSerializerするときに、javaTypeに、byte[].classを指定しないと、Byteの配列と見なされます。そのせいじゃないですか?
ドナ
常連さん
会議室デビュー日: 2003/07/08
投稿数: 42
投稿日時: 2003-12-24 18:17
t-wataさん、ありがとうございました。ちゃんと動きました。
1

スキルアップ/キャリアアップ(JOB@IT)