2011-06-16 89 views
2

簡短的版本:我的Spring-WS SOAP EchoEndpoint只要我嘗試訪問它就會響應404。請幫忙,我花了兩天的時間試圖讓它正常工作。 :-Ispring-ws:獲取EchoEndpoint的工作,而不是返回404

更長的版本:我有一個Spring項目,我需要使SOAP服務的行爲看起來像系統中的SOAP服務一樣,並且會被棄用。因此,我不打算使用編組,而是通過XPath分析信封內容,並以與舊系統類似的方式進行響應。

但導致我有問題。我通過DispatcherServlet而不是MessageDispatcherServlet來連接spring-w,因爲它與我的其他WEB應用程序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:EchoEndPo int「,當我啓動應用程序,所以我知道它已初始化,可能只是沒有正確連接。每當我跑我的測試中我還看到這樣一行:

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> 

乾杯

回答

1

你可以嘗試使用普通MessageDispatcherServlet代替(這裏推薦http://forum.springsource.org/showthread.php?39673-Spring-WS-in-a-normal-spring-dispatcher-servlet雖然這是一個古老的線程)?當我需要來自同一個webapp的HTML和WS響應時,這對我很有用。如果將公共bean引出到單獨的XML配置文件中,在兩個調度程序之間共享Bean很簡單。另外,你似乎正在使用類路徑掃描,這使得它更容易。您可以按照此處的說明http://springtips.blogspot.com/2007/06/using-shared-parent-application-context.html分享singelton實例以及bean的配置。

PS有沒有必要

} catch (Exception ex) { 
      ex.printStackTrace(System.err); 
      Assert.fail(); 
     } 
在測試代碼

,才使試驗方法拋出異常。您仍然會知道測試需要修復,並且在Eclipse/Junit中您將獲得更好的堆棧跟蹤。

+0

當我這樣做時,難道我不會再一次實例化所有的單身人士嗎?因爲我不想要那個。讓我使用數據更新POST,其中包含我的結果與MessageDispatcherServlet – niklassaers 2011-06-16 09:58:13

+0

Voila,測試MessageDispatcherServlet並更新了帖子。感謝分享這些豆子的鏈接 – niklassaers 2011-06-16 10:33:59

0

就我而言,解決方案是關注URI中的情況。我把它放在所有的小寫字母中,但webservice期待着一個CamelCase動作名稱。

相關問題