Axis2のSOAPクライアントで大量のデータの送信を行う
JavaでAxis2でSOAPクライアントを作成する。
wsdlよりADBデータバインディングでStubクラスを自動生成したところまではよかったが、送信するデータの量が多い。
<data> <string>text1</string> <string>text2</string> .... </data>
こんな感じで、string要素が10万位あると、十メガぐらいになりそう。このままでは、巨大なオブジェクトをいったんメモリ上にロードしてから送信することになる。
これを回避する方法。
いろいろ調べたが、エレガントな方法は見つからなかったが、こんな方法でもできる、という方法。
data要素のserializeメソッドを書き換えます。
data要素のstring要素をserializeしていく部分
if (localData != null) { namespace = "http://quickstart.samples/xsd"; boolean emptyNamespace = namespace == null || namespace.length() == 0; prefix = emptyNamespace ? null : xmlWriter.getPrefix(namespace); // ここからが変更した部分 BufferedReader reader = null; try { // データはオブジェクトにsetせず、ファイルから読みだす reader = new BufferedReader(new FileReader(filename)); String line; int count = 0; while )((line = reader.readLine())( != null) { if (count % 1000 == 0) { // xmlWriterを定期的にflush xmlWriter.flush(); } if (!emptyNamespace) { if (prefix == null) { java.lang.String prefix2 = generatePrefix(namespace); xmlWriter.writeStartElement(prefix2, "string",namespace); xmlWriter.writeNamespace(prefix2, namespace); xmlWriter.setPrefix(prefix2, namespace); } else { xmlWriter.writeStartElement(namespace, "string"); } } else { xmlWriter.writeStartElement("string"); } xmlWriter.writeCharacters(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(line)); xmlWriter.writeEndElement(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } else { throw new org.apache.axis2.databinding.ADBException( "data cannot be null!!"); }
これで、メガ単位のデータでもOutOfMemoryになることなく送ることができます。