top / index / prev / next / target / source

2005-08-10 diary: うそSOAP その2

いがぴょん画像(小) 日記形式でつづる いがぴょんコラム ウェブページです。

old-v2

うそSOAP その2

コンプレックス型を試しました。

うそSOAPコンプレックス型

コンプレックス型も試しました。 WsTest02.jws

import MyNamespace.WsTestInput;
import MyNamespace.WsTestOutput;

public class WsTest02 {

    public String method01(String arg1, int arg2) {
        return "戻り値:[" + arg1 + ", " + arg2 + "]";
    }

    public WsTestOutput[] method02(WsTestInput[] input) {
        WsTestOutput[] output = new WsTestOutput[2];
        output[0] = new WsTestOutput();
        output[0].setArg4("はろう");
        output[1] = new WsTestOutput();
        return output;
    }
}

入出力についてコンプレックス型にします。 WsTestInput.java

public class WsTestInput {
    private int arg1 = 0;

    private String arg2 = "";

    public int getArg1() {
        return arg1;
    }

    public void setArg1(int arg1) {
        this.arg1 = arg1;
    }

    public String getArg2() {
        return arg2;
    }

    public void setArg2(String arg2) {
        this.arg2 = arg2;
    }
}

※これはあくまでも初期入力です。Axisが生成するクラスを実際には利用します。WsTestOutput.java

public class WsTestOutput {
    private int arg3 = 0;

    private String arg4 = "";

    public int getArg3() {
        return arg3;
    }

    public void setArg3(int arg3) {
        this.arg3 = arg3;
    }

    public String getArg4() {
        return arg4;
    }

    public void setArg4(String arg4) {
        this.arg4 = arg4;
    }
}

※これはあくまでも初期入力です。Axisが生成するクラスを実際には利用します。 WSDLは おおよそ下記のようになります。 WsTest02.wsdl

<?xml version="1.0" encoding="UTF-8"?><wsdl:definitions
 targetNamespace="http://localhost:8080/axis/WsTest02.jws"
 xmlns:apachesoap="http://xml.apache.org/xml-soap"
 xmlns:impl="http://localhost:8080/axis/WsTest02.jws"
 xmlns:intf="http://localhost:8080/axis/WsTest02.jws"
 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:tns1="http://MyNamespace"
 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
 xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <wsdl:types>
  <schema
   targetNamespace="http://MyNamespace"
   xmlns="http://www.w3.org/2001/XMLSchema">
   <import namespace="http://localhost:8080/axis/WsTest02.jws"/>
   <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
   <complexType name="WsTestInput">
    <sequence>
     <element name="arg1" type="xsd:int"/>
     <element name="arg2" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <complexType name="WsTestOutput">
    <sequence>
     <element name="arg3" type="xsd:int"/>
     <element name="arg4" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
  </schema>
  <schema
   targetNamespace="http://localhost:8080/axis/WsTest02.jws"
   xmlns="http://www.w3.org/2001/XMLSchema">
   <import namespace="http://MyNamespace"/>
   <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
   <complexType name="ArrayOfWsTestInput">
    <complexContent>
     <restriction base="soapenc:Array">
      <attribute ref="soapenc:arrayType" wsdl:arrayType="tns1:WsTestInput[]"/>
     </restriction>
    </complexContent>
   </complexType>
   <complexType name="ArrayOfWsTestOutput">
    <complexContent>
     <restriction base="soapenc:Array">
      <attribute ref="soapenc:arrayType" wsdl:arrayType="tns1:WsTestOutput[]"/>
     </restriction>
    </complexContent>
   </complexType>
  </schema>
 </wsdl:types>
 <wsdl:message name="method02Request">
    <wsdl:part name="input" type="impl:ArrayOfWsTestInput"/>
 </wsdl:message>
 <wsdl:message name="method01Response">
    <wsdl:part name="method01Return" type="xsd:string"/>
 </wsdl:message>
 <wsdl:message name="method01Request">
    <wsdl:part name="arg1" type="xsd:string"/>
    <wsdl:part name="arg2" type="xsd:int"/>
 </wsdl:message>
 <wsdl:message name="method02Response">
    <wsdl:part name="method02Return" type="impl:ArrayOfWsTestOutput"/>
 </wsdl:message>
 <wsdl:portType name="WsTest02">
    <wsdl:operation name="method01" parameterOrder="arg1 arg2">
       <wsdl:input message="impl:method01Request" name="method01Request"/>
       <wsdl:output message="impl:method01Response" name="method01Response"/>
    </wsdl:operation>
    <wsdl:operation name="method02" parameterOrder="input">
       <wsdl:input message="impl:method02Request" name="method02Request"/>
       <wsdl:output message="impl:method02Response" name="method02Response"/>
    </wsdl:operation>
 </wsdl:portType>
 <wsdl:binding name="WsTest02SoapBinding" type="impl:WsTest02">
    <wsdlsoap:binding style="rpc"
     transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="method01">
       <wsdlsoap:operation soapAction=""/>
       <wsdl:input name="method01Request">
          <wsdlsoap:body
           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
           namespace="http://MyNamespace"
           use="encoded"/>
       </wsdl:input>
       <wsdl:output name="method01Response">
          <wsdlsoap:body
           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
           namespace="http://localhost:8080/axis/WsTest02.jws"
           use="encoded"/>
       </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="method02">
       <wsdlsoap:operation soapAction=""/>
       <wsdl:input name="method02Request">
          <wsdlsoap:body
           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
           namespace="http://MyNamespace"
           use="encoded"/>
       </wsdl:input>
       <wsdl:output name="method02Response">
          <wsdlsoap:body
           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
           namespace="http://localhost:8080/axis/WsTest02.jws"
           use="encoded"/>
       </wsdl:output>
    </wsdl:operation>
 </wsdl:binding>
 <wsdl:service name="WsTest02Service">
    <wsdl:port binding="impl:WsTest02SoapBinding" name="WsTest02">
       <wsdlsoap:address location="http://localhost:8080/axis/WsTest02.jws"/>
    </wsdl:port>
 </wsdl:service></wsdl:definitions>

Axis 1.2.1に食わせて簡単に確認します。 コマンドライン java -classpath axis.jar;commons-logging-1.0.4.jar;commons-discovery-0.2.jar;jaxrpc.jar;saaj.jar;wsdl4j-1.5.1.jar org.apache.axis.wsdl.WSDL2Java -t -s WsTest02.wsdl

クライアントは下記のようになります。 TestCaller.java

import java.rmi.RemoteException;

import javax.xml.rpc.ServiceException;

import localhost.axis.WsTest02_jws.WsTest02;
import localhost.axis.WsTest02_jws.WsTest02ServiceLocator;
import MyNamespace.WsTestInput;
import MyNamespace.WsTestOutput;

public class TestCaller {

    public static void main(String[] args) {
        try {
            WsTest02 test = new WsTest02ServiceLocator().getWsTest02();

            WsTestInput[] input = new WsTestInput[1];
            input[0] = new WsTestInput();
            input[0].setArg1(3);
            input[0].setArg2("abc");
            WsTestOutput[] result = test.method02(input);
            System.out.println(result[0].getArg4());
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (ServiceException e) {
            e.printStackTrace();
        }
    }
}

クライアントが吐く電文は下記のようになります。 クライアント → サーバ

H:content-type=text/xml; charset=utf-8
H:accept=application/soap+xml, application/dime, multipart/related, text/*
H:user-agent=Axis/1.2.1
H:host=localhost:8080
H:cache-control=no-cache
H:pragma=no-cache
H:soapaction=""
H:content-length=1021<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <ns1:method02
   soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:ns1="http://MyNamespace">
   <input soapenc:arrayType="ns1:WsTestInput[1]"
    xsi:type="soapenc:Array"
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
    <input href="#id0"/>
   </input>
  </ns1:method02>
  <multiRef id="id0"
   soapenc:root="0"
   soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
   xsi:type="ns2:WsTestInput"
   xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:ns2="http://MyNamespace">
   <arg1 href="#id1"/>
   <arg2 xsi:type="xsd:string">abc</arg2>
  </multiRef>
  <multiRef id="id1"
   soapenc:root="0"
   soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
   xsi:type="xsd:int"
   xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">3</multiRef>
 </soapenv:Body></soapenv:Envelope>

うそSOAPクライアント実装は下記のようになります。 HttpCaller.java (うそSOAPクライアント)

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;

public class HttpCaller implements ContentHandler {
    private static final int COUNT = 100;

    private void callMethod() {
        HttpClient client = new HttpClient();
        client.getHostConfiguration().setHost("localhost", 8080, "http");

        PostMethod method = new PostMethod("/axis/WsTest02.jws");

        String request = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                + "<soapenv:Envelope"
                + " xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\""
                + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""
                + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
                + " <soapenv:Body>"
                + "  <ns1:method02"
                + "   soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\""
                + "   xmlns:ns1=\"http://MyNamespace\">"
                + "   <input soapenc:arrayType=\"ns1:WsTestInput[1]\""
                + "    xsi:type=\"soapenc:Array\""
                + "    xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"
                + "    <input href=\"#id0\"/>"
                + "   </input>"
                + "  </ns1:method02>"
                + "  <multiRef id=\"id0\""
                + "   soapenc:root=\"0\""
                + "   soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\""
                + "   xsi:type=\"ns2:WsTestInput\""
                + "   xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\""
                + "   xmlns:ns2=\"http://MyNamespace\">"
                + "   <arg1 href=\"#id1\"/>"
                + "   <arg2 xsi:type=\"xsd:string\">abc</arg2>"
                + "  </multiRef>"
                + "  <multiRef id=\"id1\""
                + "   soapenc:root=\"0\""
                + "   soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\""
                + "   xsi:type=\"xsd:int\""
                + "   xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">3</multiRef>"
                + " </soapenv:Body>" + "</soapenv:Envelope>";
        byte[] requestBytes = null;
        try {
            requestBytes = request.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }
        method.addRequestHeader("content-type", "text/xml; charset=utf-8");
        method
                .addRequestHeader("accept",
                        "application/soap+xml, application/dime, multipart/related, text/*");
        method.addRequestHeader("user-agent", "Usoap/1.2.1");
        method.addRequestHeader("host", "localhost:8080");
        method.addRequestHeader("cache-control", "no-cache");
        method.addRequestHeader("pragma", "no-cache");
        method.addRequestHeader("soapaction", "");
        method.addRequestHeader("content-length", String
                .valueOf(requestBytes.length));

        method.setRequestBody(new ByteArrayInputStream(requestBytes));
        try {
            client.executeMethod(method);

            try {
                SAXSource source = new SAXSource();
                source.setInputSource(new InputSource(method
                        .getResponseBodyAsStream()));
                SAXResult result = new SAXResult();
                result.setHandler(this);
                getTransformer().transform(source, result);
            } catch (TransformerConfigurationException e2) {
                e2.printStackTrace();
            } catch (TransformerException e2) {
                e2.printStackTrace();
            } catch (TransformerFactoryConfigurationError e2) {
                e2.printStackTrace();
            }
        } catch (HttpException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        method.releaseConnection();
    }

    public static void main(String[] args) {
        new HttpCaller().callMethod();
    }

    /**
     * ここから SAX2コンテントハンドら領域です。
     */

    public void setDocumentLocator(Locator arg0) {
        System.out.println("setDocumentLocator(" + arg0 + ")");
    }

    public void startDocument() throws SAXException {
        System.out.println("startDocument()");
    }

    public void endDocument() throws SAXException {
        System.out.println("endDocument()");
    }

    public void startPrefixMapping(String arg0, String arg1)
            throws SAXException {
        System.out.println("startPrefixMapping(" + arg0 + ", " + arg1 + ")");
    }

    public void endPrefixMapping(String arg0) throws SAXException {
        System.out.println("endPrefixMapping(" + arg0 + ")");
    }

    public void startElement(String uri, String localname, String qname,
            Attributes attributes) throws SAXException {
        System.out.println("startElement(uri:" + uri + ", localname:"
                + localname + ", QName" + qname + ")");
        for (int index = 0; index < attributes.getLength(); index++) {
            System.out.println(" Local :" + attributes.getLocalName(index));
            System.out.println("  QName:" + attributes.getQName(index));
            System.out.println("  uri  :" + attributes.getURI(index));
            System.out.println("  type :" + attributes.getType(index));
            System.out.println("  Value:" + attributes.getValue(index));
        }
    }

    public void endElement(String arg0, String arg1, String arg2)
            throws SAXException {
        System.out.println("endElement(uri:" + arg0 + ", localname:" + arg1
                + ", QName:" + arg2 + ")");
    }

    public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
        System.out.println("characters(" + new String(arg0, arg1, arg2) + ")");
    }

    public void ignorableWhitespace(char[] arg0, int arg1, int arg2)
            throws SAXException {
        System.out.println("ignorableWhitespace("
                + new String(arg0, arg1, arg2) + ")");
    }

    public void processingInstruction(String arg0, String arg1)
            throws SAXException {
        System.out.println("processingInstruction(" + arg0 + ", " + arg1 + ")");
    }

    public void skippedEntity(String arg0) throws SAXException {
        System.out.println("skippedEntity(" + arg0 + ")");
    }

    public static final Transformer getTransformer()
            throws TransformerFactoryConfigurationError,
            TransformerConfigurationException {
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer();
        transformer.setOutputProperty("encoding", "UTF-8");
        transformer.setOutputProperty("standalone", "yes");
        transformer.setOutputProperty("indent", "yes");
        return transformer;
    }
}

電文内容改善版の うそSOAPクライアント HttpCaller.java (うそSOAPクライアント改)

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;

public class HttpCaller implements ContentHandler {
    private static final int COUNT = 100;

    private void callMethod() {
        HttpClient client = new HttpClient();
        client.getHostConfiguration().setHost("localhost", 8080, "http");

        PostMethod method = new PostMethod("/axis/WsTest02.jws");

        String request = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                + "<soapenv:Envelope"
                + " xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\""
                + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""
                + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
                + " <soapenv:Body>"
                + "  <ns1:method02"
                + "   soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\""
                + "   xmlns:ns1=\"http://MyNamespace\">"
                + "   <input soapenc:arrayType=\"ns1:WsTestInput[2]\""
                + "    xsi:type=\"soapenc:Array\""
                + "    xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\">"
                + "    <input>" + "     <arg1>123</arg1>"
                + "     <arg2>abc</arg2>" + "    </input>" + "    <input>"
                + "     <arg1>234</arg1>" + "     <arg2>あいう</arg2>"
                + "    </input>" + "   </input>" + "  </ns1:method02>"
                + " </soapenv:Body>" + "</soapenv:Envelope>";
        byte[] requestBytes = null;
        try {
            requestBytes = request.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }
        method.addRequestHeader("content-type", "text/xml; charset=utf-8");
        method
                .addRequestHeader("accept",
                        "application/soap+xml, application/dime, multipart/related, text/*");
        method.addRequestHeader("user-agent", "Usoap/1.2.1");
        method.addRequestHeader("host", "localhost:8080");
        method.addRequestHeader("cache-control", "no-cache");
        method.addRequestHeader("pragma", "no-cache");
        method.addRequestHeader("soapaction", "");
        method.addRequestHeader("content-length", String
                .valueOf(requestBytes.length));

        method.setRequestBody(new ByteArrayInputStream(requestBytes));
        try {
            client.executeMethod(method);

            try {
                SAXSource source = new SAXSource();
                source.setInputSource(new InputSource(method
                        .getResponseBodyAsStream()));
                SAXResult result = new SAXResult();
                result.setHandler(this);
                getTransformer().transform(source, result);
            } catch (TransformerConfigurationException e2) {
                e2.printStackTrace();
            } catch (TransformerException e2) {
                e2.printStackTrace();
            } catch (TransformerFactoryConfigurationError e2) {
                e2.printStackTrace();
            }
        } catch (HttpException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        method.releaseConnection();
    }

    public static void main(String[] args) {
        new HttpCaller().callMethod();
    }

    /**
     * ここから SAX2コンテントハンドら領域です。
     */

    public void setDocumentLocator(Locator arg0) {
        //System.out.println("handler.setDocumentLocator(\"" + arg0.toString()
        // + "\");");
    }

    public void startDocument() throws SAXException {
        System.out
                .println("TransformerFactory tf = TransformerFactory.newInstance();");
        System.out
                .println("SAXTransformerFactory saxTf = (SAXTransformerFactory) tf;");
        System.out
                .println("TransformerHandler handler = saxTf.newTransformerHandler();");
        System.out
                .println("handler.setResult(new StreamResult(response.getOutputStream()));");
        System.out.println("handler.startDocument();");
    }

    public void endDocument() throws SAXException {
        System.out.println("handler.endDocument();");
    }

    public void startPrefixMapping(String arg0, String arg1)
            throws SAXException {
        System.out.println("handler.startPrefixMapping(\"" + arg0 + "\", \""
                + arg1 + "\");");
    }

    public void endPrefixMapping(String arg0) throws SAXException {
        System.out.println("handler.endPrefixMapping(\"" + arg0 + "\");");
    }

    private boolean isFirstAttributes = true;

    public void startElement(String uri, String localname, String qname,
            Attributes attributes) throws SAXException {
        if (isFirstAttributes) {
            isFirstAttributes = false;
            System.out
                    .println("AttributesImpl attributes = new AttributesImpl();");
        } else {
            System.out.println("attributes = new AttributesImpl();");
        }
        for (int index = 0; index < attributes.getLength(); index++) {
            System.out.println("attributes.addAttribute(\""
                    + attributes.getURI(index) + "\", \""
                    + attributes.getLocalName(index) + "\", \""
                    + attributes.getQName(index) + "\", \""
                    + attributes.getType(index) + "\", \""
                    + attributes.getValue(index) + "\");");
        }
        System.out.println("handler.startElement(\"" + uri + "\", \""
                + localname + "\", \"" + qname + "\", attributes);");
    }

    public void endElement(String arg0, String arg1, String arg2)
            throws SAXException {
        System.out.println("handler.endElement(\"" + arg0 + "\", \"" + arg1
                + "\", \"" + arg2 + "\");");
    }

    public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
        // 第二引数に0をセットしている点に注意!
        System.out.println("handler.characters(\""
                + new String(arg0, arg1, arg2) + "\".toCharArray(), 0, " + arg2
                + ");");
    }

    public void ignorableWhitespace(char[] arg0, int arg1, int arg2)
            throws SAXException {
        System.out.println("handler.ignorableWhitespace(\""
                + new String(arg0, arg1, arg2) + "\".toCharArray(), 0, " + arg2
                + ");");
    }

    public void processingInstruction(String arg0, String arg1)
            throws SAXException {
        System.out.println("handler.processingInstruction(\"" + arg0 + "\", \""
                + arg1 + "\");");
    }

    public void skippedEntity(String arg0) throws SAXException {
        System.out.println("handler.skippedEntity(\"" + arg0 + "\");");
    }

    public static final Transformer getTransformer()
            throws TransformerFactoryConfigurationError,
            TransformerConfigurationException {
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer();
        transformer.setOutputProperty("encoding", "UTF-8");
        transformer.setOutputProperty("standalone", "yes");
        transformer.setOutputProperty("indent", "yes");
        return transformer;
    }
}

※リバースSAXのひな形になるものと期待します。 リバースSAXの出力結果を うそSOAPサーバにつっこみます UsoapServlet.java (うそSOAPサーバ改)

/*
 * うそSOAPサーブレット構築計画
 * Copyright (C) 2005 いがぴょん
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

/**
 * うそSOAPサーブレット ソースコード
 * 
 * @author iga
 * @version 2005.08.02
 */
public class UsoapServlet extends HttpServlet {

    /**
     * <code>ENCODING</code> HTMLで扱う文字コードを与えます。
     */
    public static final String ENCODING = "UTF-8";

    /**
     * Java Servletのエントリポイントです。
     * 
     * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest,
     *      javax.servlet.http.HttpServletResponse)
     */
    public final void service(final HttpServletRequest request,
            final HttpServletResponse response) throws ServletException,
            IOException {

        setResponseDefault(response);

        try {
            for (Enumeration enum = request.getHeaderNames(); enum
                    .hasMoreElements();) {
                String key = (String) enum.nextElement();
                System.out.println("H:" + key + "=" + request.getHeader(key)
                        + "");
            }

            BufferedReader reader = request.getReader();
            for (;;) {
                String readLine = reader.readLine();
                if (readLine == null) {
                    break;
                }
                System.out.println(readLine);
            }

            try {
                // ここからはリバースSAXの出力結果
                TransformerFactory tf = TransformerFactory.newInstance();
                SAXTransformerFactory saxTf = (SAXTransformerFactory) tf;
                TransformerHandler handler = saxTf.newTransformerHandler();
                handler.setResult(new StreamResult(response.getOutputStream()));
                handler.startDocument();
                handler.startPrefixMapping("soapenv",
                        "http://schemas.xmlsoap.org/soap/envelope/");
                handler.startPrefixMapping("xsd",
                        "http://www.w3.org/2001/XMLSchema");
                handler.startPrefixMapping("xsi",
                        "http://www.w3.org/2001/XMLSchema-instance");
                AttributesImpl attributes = new AttributesImpl();
                attributes.addAttribute("http://www.w3.org/2000/xmlns/",
                        "soapenv", "xmlns:soapenv", "CDATA",
                        "http://schemas.xmlsoap.org/soap/envelope/");
                attributes.addAttribute("http://www.w3.org/2000/xmlns/", "xsd",
                        "xmlns:xsd", "CDATA",
                        "http://www.w3.org/2001/XMLSchema");
                attributes.addAttribute("http://www.w3.org/2000/xmlns/", "xsi",
                        "xmlns:xsi", "CDATA",
                        "http://www.w3.org/2001/XMLSchema-instance");
                handler.startElement(
                        "http://schemas.xmlsoap.org/soap/envelope/",
                        "Envelope", "soapenv:Envelope", attributes);
                attributes = new AttributesImpl();
                handler.startElement(
                        "http://schemas.xmlsoap.org/soap/envelope/", "Body",
                        "soapenv:Body", attributes);
                handler.startPrefixMapping("ns1", "http://MyNamespace");
                attributes = new AttributesImpl();
                attributes.addAttribute("http://www.w3.org/2000/xmlns/", "ns1",
                        "xmlns:ns1", "CDATA", "http://MyNamespace");
                attributes.addAttribute(
                        "http://schemas.xmlsoap.org/soap/envelope/",
                        "encodingStyle", "soapenv:encodingStyle", "CDATA",
                        "http://schemas.xmlsoap.org/soap/encoding/");
                handler.startElement("http://MyNamespace", "method02Response",
                        "ns1:method02Response", attributes);
                handler.startPrefixMapping("soapenc",
                        "http://schemas.xmlsoap.org/soap/encoding/");
                attributes = new AttributesImpl();
                attributes.addAttribute("http://www.w3.org/2000/xmlns/",
                        "soapenc", "xmlns:soapenc", "CDATA",
                        "http://schemas.xmlsoap.org/soap/encoding/");
                attributes.addAttribute(
                        "http://schemas.xmlsoap.org/soap/encoding/",
                        "arrayType", "soapenc:arrayType", "CDATA",
                        "xsd:anyType[2]");
                attributes.addAttribute(
                        "http://www.w3.org/2001/XMLSchema-instance", "type",
                        "xsi:type", "CDATA", "soapenc:Array");
                handler.startElement("", "method02Return", "method02Return",
                        attributes);
                attributes = new AttributesImpl();
                attributes.addAttribute("", "href", "href", "CDATA", "#id0");
                handler.startElement("", "method02Return", "method02Return",
                        attributes);
                handler.endElement("", "method02Return", "method02Return");
                attributes = new AttributesImpl();
                attributes.addAttribute("", "href", "href", "CDATA", "#id1");
                handler.startElement("", "method02Return", "method02Return",
                        attributes);
                handler.endElement("", "method02Return", "method02Return");
                handler.endElement("", "method02Return", "method02Return");
                handler.endPrefixMapping("soapenc");
                handler.endElement("http://MyNamespace", "method02Response",
                        "ns1:method02Response");
                handler.endPrefixMapping("ns1");
                handler.startPrefixMapping("soapenc",
                        "http://schemas.xmlsoap.org/soap/encoding/");
                handler.startPrefixMapping("ns2", "http://MyNamespace");
                attributes = new AttributesImpl();
                attributes.addAttribute("http://www.w3.org/2000/xmlns/",
                        "soapenc", "xmlns:soapenc", "CDATA",
                        "http://schemas.xmlsoap.org/soap/encoding/");
                attributes.addAttribute("http://www.w3.org/2000/xmlns/", "ns2",
                        "xmlns:ns2", "CDATA", "http://MyNamespace");
                attributes.addAttribute("", "id", "id", "CDATA", "id0");
                attributes.addAttribute(
                        "http://schemas.xmlsoap.org/soap/encoding/", "root",
                        "soapenc:root", "CDATA", "0");
                attributes.addAttribute(
                        "http://schemas.xmlsoap.org/soap/envelope/",
                        "encodingStyle", "soapenv:encodingStyle", "CDATA",
                        "http://schemas.xmlsoap.org/soap/encoding/");
                attributes.addAttribute(
                        "http://www.w3.org/2001/XMLSchema-instance", "type",
                        "xsi:type", "CDATA", "ns2:WsTestOutput");
                handler.startElement("", "multiRef", "multiRef", attributes);
                attributes = new AttributesImpl();
                attributes.addAttribute(
                        "http://www.w3.org/2001/XMLSchema-instance", "type",
                        "xsi:type", "CDATA", "xsd:int");
                handler.startElement("", "arg3", "arg3", attributes);
                handler.characters("0".toCharArray(), 0, 1);
                handler.endElement("", "arg3", "arg3");
                attributes = new AttributesImpl();
                attributes.addAttribute(
                        "http://www.w3.org/2001/XMLSchema-instance", "type",
                        "xsi:type", "CDATA", "xsd:string");
                handler.startElement("", "arg4", "arg4", attributes);
                handler.characters("は".toCharArray(), 0, 1);
                handler.characters("ろ".toCharArray(), 0, 1);
                handler.characters("う".toCharArray(), 0, 1);
                handler.endElement("", "arg4", "arg4");
                handler.endElement("", "multiRef", "multiRef");
                handler.endPrefixMapping("ns2");
                handler.endPrefixMapping("soapenc");
                handler.startPrefixMapping("ns3", "http://MyNamespace");
                handler.startPrefixMapping("soapenc",
                        "http://schemas.xmlsoap.org/soap/encoding/");
                attributes = new AttributesImpl();
                attributes.addAttribute("http://www.w3.org/2000/xmlns/", "ns3",
                        "xmlns:ns3", "CDATA", "http://MyNamespace");
                attributes.addAttribute("http://www.w3.org/2000/xmlns/",
                        "soapenc", "xmlns:soapenc", "CDATA",
                        "http://schemas.xmlsoap.org/soap/encoding/");
                attributes.addAttribute("", "id", "id", "CDATA", "id1");
                attributes.addAttribute(
                        "http://schemas.xmlsoap.org/soap/encoding/", "root",
                        "soapenc:root", "CDATA", "0");
                attributes.addAttribute(
                        "http://schemas.xmlsoap.org/soap/envelope/",
                        "encodingStyle", "soapenv:encodingStyle", "CDATA",
                        "http://schemas.xmlsoap.org/soap/encoding/");
                attributes.addAttribute(
                        "http://www.w3.org/2001/XMLSchema-instance", "type",
                        "xsi:type", "CDATA", "ns3:WsTestOutput");
                handler.startElement("", "multiRef", "multiRef", attributes);
                attributes = new AttributesImpl();
                attributes.addAttribute(
                        "http://www.w3.org/2001/XMLSchema-instance", "type",
                        "xsi:type", "CDATA", "xsd:int");
                handler.startElement("", "arg3", "arg3", attributes);
                handler.characters("0".toCharArray(), 0, 1);
                handler.endElement("", "arg3", "arg3");
                attributes = new AttributesImpl();
                attributes.addAttribute(
                        "http://www.w3.org/2001/XMLSchema-instance", "type",
                        "xsi:type", "CDATA", "xsd:string");
                attributes.addAttribute(
                        "http://www.w3.org/2001/XMLSchema-instance", "nil",
                        "xsi:nil", "CDATA", "true");
                handler.startElement("", "arg4", "arg4", attributes);
                handler.endElement("", "arg4", "arg4");
                handler.endElement("", "multiRef", "multiRef");
                handler.endPrefixMapping("soapenc");
                handler.endPrefixMapping("ns3");
                handler.endElement("http://schemas.xmlsoap.org/soap/envelope/",
                        "Body", "soapenv:Body");
                handler.endElement("http://schemas.xmlsoap.org/soap/envelope/",
                        "Envelope", "soapenv:Envelope");
                handler.endPrefixMapping("xsi");
                handler.endPrefixMapping("xsd");
                handler.endPrefixMapping("soapenv");
                handler.endDocument();
            } catch (TransformerConfigurationException e) {
                e.printStackTrace();
            } catch (TransformerFactoryConfigurationError e) {
                e.printStackTrace();
            } catch (SAXException e) {
                // TODO 自動生成された catch ブロック
                e.printStackTrace();
            }

        } finally {
            // ReaderもWriterもクローズしません。flushも呼び出してはなりません。(2005.03.13に判明)
        }
    }

    /**
     * デフォルトとなるレスポンスヘッダーの付与
     * 
     * @param response
     *            レスポンスオブジェクトを与えます。
     */
    private void setResponseDefault(final HttpServletResponse response) {
        response.setContentType("text/xml; charset=" + ENCODING);
        response.addHeader("Content-Type", "text/xml");
        response.addHeader("charset", ENCODING);
        response.addHeader("Cache-Control", "no-cache");
        response.addHeader("Pragma", "no-cache");
        response.addHeader("Expires", "0");
    }

    public static final Transformer getTransformer()
            throws TransformerFactoryConfigurationError,
            TransformerConfigurationException {
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer();
        transformer.setOutputProperty("encoding", "UTF-8");
        transformer.setOutputProperty("standalone", "yes");
        transformer.setOutputProperty("indent", "yes");
        return transformer;
    }
}

※リバースSAXの出力結果を入力としています。 う、、、動きました。私自身びっくりです。ある意味、これはすごい技術かも知れませぬ。

関連する日記


この日記について