Spring WS для
Webservice — это достойная структура для разработки и реализации Web-сервиса. Он также имеет хорошую
поддержку тестирования JUnit . В этом разделе я буду рассказывать о том, как мы реализуем веб-сервис с использованием
Test Driven Development (TDD) . Рабочий образец здесь, в
Github .
В качестве первого шага нам нужно определить схему XSD:
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:data="http://mycompany.com/it/enterprise/data/v1" xmlns:msg="http://mycompany.com/it/enterprise/msg/v1" xmlns:svc="http://mycompany.com/it/enterprise/contract/TestService/v1" targetNamespace="http://mycompany.com/it/enterprise/contract/TestService/v1" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0"> <xsd:import namespace="http : //mycompany.com/it/enterprise/data/v1" schemaLocation="TestTransactions_v1.xsd"/> <xsd:element name="TestServiceRequest" type="data:TestServiceRequestType"/> <xsd:element name="TestServiceResponse" type="data:TestServiceResponseType"/> </xsd:schema> <?xml version="1.0" encoding="UTF-8"?><xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:data="http://mycompany.com/it/enterprise/data/v1" xmlns:msg="http://mycompany.com/it/enterprise/msg/v1" targetNamespace="http://mycompany.com/it/enterprise/data/v1" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:complexType name="TestServiceRequestType"> <xsd:sequence> <xsd:element name="Document"> <xsd:complexType> <xsd:sequence> <xsd:element name="Id" type="xsd:string" minOccurs="0"/> <xsd:element name="Type" type="xsd:string" minOccurs="0"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> <xsd:complexType name="TestServiceResponseType"> <xsd:sequence> <xsd:element name="Document"> <xsd:complexType> <xsd:sequence> <xsd:element name="Result" type="xsd:string" minOccurs="0"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:schema>
Написание теста JUnit, как показано ниже,
public class TestIntegrationEndPointTest { @Autowired private ApplicationContext applicationContext; private MockWebServiceClient mockClient; @Before public void createClient() { mockClient = MockWebServiceClient.createClient(applicationContext); } @Test public void testWsEndPointTest() throws Exception { Source requestPayload = new StringSource("<?xml version=\"1.0\" encoding=\"UTF-8\"?><v1:TestServiceRequest xmlns:v1=\"http://mycompany.com/it/enterprise/contract/TestService/v1\" xmlns:v11=\"http://mycompany.com/it/enterprise/data/v1\"><v11:Document><v11:Id>101</v11:Id><v11:Type>MaterialMaster</v11:Type></v11:Document></v1:TestServiceRequest>"); Source responsePayload = new StringSource("<testServiceResponseType xmlns=\"http://mycompany.com/it/enterprise/data/v1\" xmlns:ns2=\"http://mycompany.com/it/enterprise/contract/TestService/v1\"><Document><Result>SUCCESS</Result></Document></testServiceResponseType>"); mockClient.sendRequest(withPayload(requestPayload)).andExpect(payload(responsePayload)); } }
Теперь тест по-прежнему не пройден, так как требуется автоматическое подключение Spring, конфигурация определения bean-компонента Spring для Spring WS выглядит следующим образом:
<bean> <property name="endpointMap"> <map> <entry key="{http://mycompany.com/it/enterprise/contract/TestService/v1}TestServiceRequest" value-ref="TestBatchEndpoint" /> </map> </property> </bean> <int-ws:inbound-gateway id="TestBatchEndpoint" reply-channel="test.batch.webservice.out" request-channel="test.batch.webservice.in" /> <bean id="marshaller" > <property name="contextPath" value="com.mycompany.it.enterprise.contract.testservice.v1" /> </bean> <bean id="testServiceActivator" class="com.mycompany.it.eis.webservice.ws.TestServiceActivator"/> <bean id="resultTransformer" class="org.springframework.integration.xml.transformer.ResultToStringTransformer"/>
Spring Integration и Spring WS выглядят так, как показано ниже
<int:bridge input-channel="test.batch.webservice.in" output-channel="test.batch.webservice.unmarshalling.in"></int:bridge> <int-xml:unmarshalling-transformer id="defaultUnmarshaller" input-channel="test.batch.webservice.unmarshalling.in" output-channel="test.batch.webservice.unmarshalling.out" unmarshaller="marshaller"/> <int:service-activator id="test.batch.webservice.activator" input-channel="test.batch.webservice.unmarshalling.out" ref="testServiceActivator" output-channel="test.batch.webservice.marshalling.in"> </int:service-activator> <int-xml:marshalling-transformer input-channel="test.batch.webservice.marshalling.in" output-channel="test.batch.webservice.out" marshaller="marshaller" result-transformer="resultTransformer" />
IBatisTemplate выглядит так, как показано ниже,
<bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">> <property name="sqlMapClient" ref="sqlMapClient" /> </bean>
Вам нужно создать заглушки Java из XSL для того, что вам нужно запустить,
mvn jaxb2:xjc
Предполагается, что у вас есть XSD в местоположении src / main / xsd по умолчанию, обратитесь к этой статье для получения дополнительной информации.
В классе Test вам нужно добавить возможности тестирования Spring JUnit следующим образом:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "classpath:META-INF/spring/test-webservice/test-webservice-integration-config.xml", "classpath:config/test-webservice-beans-config-test.xml" }) public class TestIntegrationEndPointTest {
TestServiceActivator выглядит примерно так:
public class TestServiceActivator { private static Logger logger = Logger.getLogger(TestServiceActivator.class); @Autowired SqlMapClientTemplate ibatisTemplate; public TestServiceResponseType processRequest(JAXBElement element) throws Exception { TestServiceRequestType request = (TestServiceRequestType) element.getValue(); String status = "SUCCESS"; String type = request.getDocument().getType(); String id = request.getDocument().getId(); TestObject notifyObject = new TestObject(); notifyObject.setId(id); notifyObject.setType(type); ibatisTemplate.insert("testInsert", notifyObject); TestServiceResponseType response = new TestServiceResponseType(); Document doc = new Document(); doc.setResult(status); response.setDocument(doc); logger.debug("Successfully saved request"); return response; } }
Один хак, который нам нужно сделать, это то, что нам нужно добавить @XmlRootElement к заглушкам, которые были созданы в соответствии с этой статьей
@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "TestServiceResponseType", propOrder = { "document" }) public class TestServiceResponseType { @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "TestServiceRequestType", propOrder = { "document" }) public class TestServiceRequestType {
Как только вы это сделаете, мы можем запустить тест mvn, и он будет работать. Если вы заметили в этом примере, мы протестировали String WS от начала до конца, используя JUnit и Spring Integraiton.
Для дальнейшего чтения см. Http://blog.springsource.org/2011/01/11/spring-web-services-2-0-released/ .