matsukaz's blog

Agile, node.js, ruby, AWS, cocos2d-xなどなどいろいろやってます

Spring Web Services まとめ その3

payload endpointsの実装種類 (Chapter 5)

その2では、JDomを利用してpayload endpointsを実装するため、AbstractJDomPayloadEndpointクラスを継承した。その他のAPIを利用する場合には、それぞれ対応したクラスを継承する。以下は、利用可能なAPIと継承元クラスの対応関係である。

API 継承元クラス
dom4j AbstractDom4jPayloadEndpoint
DOM AbstractDomPayloadEndpoint
JDom AbstractJDomPayloadEndpoint
SAX AbstractSaxPayloadEndpoint
StAX(イベント イテレータ API) AbstractStaxEventPayloadEndpoint
StAX(XMLInputFactoryとXMLOutputFactoryを利用) AbstractStaxPayloadEndpoint
StAX(カーソル API) AbstractStaxStreamPayloadEndpoint
XOM AbstractXomPayloadEndpoint
Marshaller(JAXB/Castor/XMLBeans/JiBX/XStreamなど) AbstractMarshallingPayloadEndpoint

継承元クラス間の違いは、invokeInternal()の引数の違いと言える。
例えば、AbstractJDomPayloadEndpointではorg.jdom.Elementを引数に受け取っていたが、AbstractDom4jPayloadEndpointの場合にはorg.dom4j.Elementとorg.dom4j.Documentを引数に受け取っている。
AbstractMarshallingPayloadEndpointは他のクラスと異なり、invokeInternal()の引数にはObjectを受け取る。実装時には、ObjectをJavaのオブジェクトにキャストして利用する。以下は、AbstractMarshallingPayloadEndpointの実装例である。

package samples;

import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;

public class MarshallingOrderEndpoint extends AbstractMarshallingPayloadEndpoint{

    private final OrderService orderService;

    public SampleMarshallingEndpoint(OrderService orderService, Marshaller marshaller) {
        super(marshaller);
        this.orderService = orderService;
    }

    protected Object invokeInternal(Object request) throws Exception {
        OrderRequest orderRequest = (OrderRequest) request;
        Order order = orderService.getOrder(orderRequest.getId());
        return order;
    }
}

サービスのリクエストは引数のOrderRequestに変換され、戻り値のOrderはサービスのレスポンスへと変換されている。
AbstractMarshallingPayloadEndpointを利用する場合には、上記の実装の他にSpringのコンフィギュレーションXMLにMarshallerを指定する必要がある。以下は、JAXB 2.0を利用した場合の記述例である。

<beans>
    <bean id="orderEndpoint" class="samples.MarshallingOrderEndpoint">
        <constructor-arg ref="orderService"/>
        <constructor-arg ref="marshaller"/>
    </bean>

    <bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="classesToBeBound">
            <list>
                <value>samples.OrderRequest</value>
                <value>samples.Order</value>
            </list>
        </property>
    </bean>

    <bean id="orderService" class="samples.DefaultOrderService"/>

    <!-- Other beans, such as the endpoint mapping -->
</beans>

Marshallerのクラス指定を変更することで、Marshallerを切り替えることができる。以下は、Marshallerと指定するクラスの対応関係である。

Marshaller クラス
JAXB 1.0 org.springframework.oxm.jaxb.Jaxb1Marshaller
JAXB 2.0 org.springframework.oxm.jaxb.Jaxb2Marshaller
Castor org.springframework.oxm.castor.CastorMarshaller
JiBX org.springframework.oxm.jibx.JibxMarshaller
XML Beans org.springframework.oxm.xmlbeans.XmlBeansMarshaller
XStream org.springframework.oxm.xstream.XStreamMarshaller