Короткая версия: Мой Spring-WS SOAP EchoEndpoint отвечает 404 всякий раз, когда я пытаюсь получить к нему доступ. Пожалуйста, помогите, я провел два дня, пытаясь заставить его работать правильно. : -I
Более длинная версия: у меня есть проект Spring, в котором мне нужно сделать SOAP-сервисы, которые действуют, выглядят и воспринимаются как SOAP-сервисы из системы, которые будут устаревшими. Поэтому я не собираюсь использовать маршаллинг, а скорее проанализировать содержимое конверта через XPath и сделать ответ таким образом, который выглядит как старая система.
Но в связи с этим у меня проблемы. Spring-ws я подключил через DispatcherServlet вместо MessageDispatcherServlet, потому что он находится в том же пространстве, что и остальные REST-сервисы моих веб-приложений. Вот мои родственные бобы:
<context:component-scan base-package="com.saers.niklas.view"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="" p:suffix=".jsp"/>
<bean name="jsonView" class="org.springframework.web.servlet.view.json.JsonView">
<property name="encoding" value="UTF-8"/>
<property name="contentType" value="application/json"/>
<property name="hijackSafe" value="true"/>
<property name="hijackSafePrefixPostFix"><value>(while(1);)</value></property>
</bean>
<aop:aspectj-autoproxy />
<sws:annotation-driven />
<context:component-scan base-package="com.saers.niklas.ws"/>
<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<bean class="com.saers.niklas.view.web.interceptors.AddObjectIDsToResponseInterceptor"/>
</property>
</bean>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="defaultHandler" ref="messageDispatcher"/>
</bean>
<bean id="messageDispatcher" class="org.springframework.ws.soap.server.SoapMessageDispatcher"/>
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<bean class="org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter">
<property name="messageFactory">
<bean class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" />
</property>
</bean>
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
Моя конечная точка выглядит так
package com.saers.niklas.ws;
import javax.xml.transform.Source;
import org.w3c.dom.*;
import org.springframework.ws.server.endpoint.annotation.*;
import org.springframework.xml.transform.StringSource;
@Endpoint
public class EchoEndpoint {
public EchoEndpoint() {
System.err.println("XXNJSXX: EchoEndPoint");
}
@PayloadRoot(localPart="echoRequest", namespace="http://niklas.saers.com/DemoService")
public Source echo(@RequestPayload Element requestElement) {
return new StringSource("<x/>");
}
}
и мой тест выглядит так:
package com.saers.niklas.ws;
import javax.xml.transform.*;
import junit.framework.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.xml.transform.*;
public class WSTest {
private static WebServiceTemplate template;
@BeforeClass
public static void setUp() {
template = new WebServiceTemplate();
template.setDefaultUri("http://localhost:8080/MyApp/ws/");
}
@Test
public void testEchoEndpoint() {
String xml = "<echoRequest xmlns=\"http://niklas.saers.com/DemoService\">Hello world</echoRequest>";
Source source = new StringSource(xml);
Result result = new StringResult();
try {
template.sendSourceAndReceiveToResult(source, result);
System.out.println(result);
} catch (Exception ex) {
ex.printStackTrace(System.err);
Assert.fail();
}
}
}
Тест не пройден с
org.springframework.ws.client.WebServiceTransportException: Not Found [404]
at org.springframework.ws.client.core.WebServiceTemplate.handleError(WebServiceTemplate.java:622)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:546)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:496)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:451)
at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceiveToResult(WebServiceTemplate.java:395)
at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceiveToResult(WebServiceTemplate.java:386)
at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceiveToResult(WebServiceTemplate.java:376)
at com.saers.niklas.ws.WSTest.testKommuneEndpoint(WSTest.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
, даже когда я получаю «XXNJSXX: EchoEndPoint» в выводе при запуске приложения, поэтому я знаю, что оно инициализировано, возможно, просто неправильно подключено. Всякий раз, когда я запускаю тест, я также вижу строку вроде:
2011-06-16 09:57:10 SaajSoapMessageFactory [INFO] Creating SAAJ 1.3 MessageFactory with SOAP 1.1 Protocol
Я также запустил WireShark, чтобы подтвердить, что запрос выполняется именно так, как я ожидаю, и я действительно получаю 404 назад. Вот запрос:
POST /MyApp/ws/ HTTP/1.1
Accept-Encoding: gzip
Accept: text/xml, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
SOAPAction: ""
Content-Type: text/xml; charset=utf-8
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.6.0_26
Host: localhost:8080
Connection: keep-alive
Content-Length: 229
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><echoRequest xmlns="http://niklas.saers.com/DemoService">Hello world</echoRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>
Чего мне не хватает?
EDIT1: Меня спросили, не возникла ли у меня такая же проблема с MessageDispatcherServlet, поэтому я настроил ее и, да, похоже, так и есть. Вот дополнение к web.xml:
<servlet>
<servlet-name>MDS</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:ws-servlet.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MDS</servlet-name>
<url-pattern>/soap2/*</url-pattern>
</servlet-mapping>
Все, что находится в ws-servlet.xml, это:
<context:annotation-config />
<context:component-scan base-package="com.saers.niklas.ws"/>
<sws:annotation-driven />
Я получаю те же 404 при вызове EchoRequest:
POST /MyApp/soap2/ HTTP/1.1
Accept-Encoding: gzip
Accept: text/xml, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
SOAPAction: ""
Content-Type: text/xml; charset=utf-8
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.6.0_26
Host: localhost:8080
Connection: keep-alive
Content-Length: 229
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><echoRequest xmlns="http://niklas.saers.com/DemoService">Hello world</echoRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>
Но на этот раз я не уверен, так ли это, потому что мой web.xml настроил DispatcherServlet для / ниже в файле:
<servlet-mapping>
<servlet-name>MyApp</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Приветствия
Nik