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/ .