Spring-ws @ Endpoint / @ PayloadRoot配置给出404

时间:2014-06-24 20:49:58

标签: java spring web-services soap spring-ws

真的难倒这个 - 尝试利用Spring-ws的@Endpoint和@PayloadRoot自动建立一些WSDL端点,但我不断获得404(部署到Tomcat 7.0.54)。我已经搜索过这个寻找命名不一致的东西(似乎是问题的最常见原因),但我一无所获!

的pom.xml:

    <dependency>
        <groupId>org.springframework.ws</groupId>
        <artifactId>spring-ws-core</artifactId>
        <version>1.5.2</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.ws</groupId>
        <artifactId>spring-ws-core-tiger</artifactId>
        <version>1.5.2</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.9</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.castor</groupId>
        <artifactId>castor</artifactId>
        <version>1.2</version>
    </dependency>

Web.xml中:

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
                        http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
    <servlet-name>weather</servlet-name>
    <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>weather</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

耐候servlet.xml中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
                       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<bean id="weatherService" class="com.nick.example.weather.WeatherServiceImpl"/>

<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping"/>

<bean id="temperatureEndpoint" class="com.nick.example.weather.TemperatureMarshallingEndpoint">
    <property name="weatherService" ref="weatherService"/>
</bean>

<bean class="org.springframework.ws.server.endpoint.adapter.GenericMarshallingMethodEndpointAdapter">
    <property name="marshaller" ref="marshaller"/>
    <property name="unmarshaller" ref="marshaller"/>
</bean>

<bean id="marshaller" class="org.springframework.oxm.castor.CastorMarshaller">
    <property name="mappingLocation" value="classpath:mapping.xml"/>
</bean>

<bean id="temperature" class="org.springframework.ws.wsdl.wsdl11.DynamicWsdl11Definition">
    <property name="builder">
        <bean class="org.springframework.ws.wsdl.wsdl11.builder.XsdBasedSoap11Wsdl4jDefinitionBuilder">
            <property name="schema" value="/WEB-INF/temperature.xsd"/>
            <property name="portTypeName" value="Weather"/>
            <property name="locationUri" value="http://localhost:8080/weather/services"/>
        </bean>
    </property>
</bean>
</beans>

temperature.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified"
       elementFormDefault="qualified"
       targetNamespace="http://nick.com/weather/schemas"
       xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="GetTemperaturesRequest">
<xs:complexType>
  <xs:sequence>
    <xs:element type="xs:string" name="city"/>
    <xs:element type="xs:date" name="date" maxOccurs="5" minOccurs="1"/>
  </xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="GetTemperaturesResponse">
<xs:complexType>
  <xs:sequence>
    <xs:element name="TemperatureInfo" maxOccurs="5" minOccurs="1">
      <xs:complexType>
        <xs:sequence>
          <xs:element type="xs:float" name="min"/>
          <xs:element type="xs:float" name="max"/>
          <xs:element type="xs:float" name="average"/>
        </xs:sequence>
        <xs:attribute type="xs:string" name="city" use="optional"/>
        <xs:attribute type="xs:date" name="date" use="optional"/>
      </xs:complexType>
    </xs:element>
  </xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

TemperatureMarshallingEndpoint.java:

package com.nick.example.weather;

import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;

import java.util.List;

@Endpoint
public class TemperatureMarshallingEndpoint {

private static final String namespaceUri = "http://nick.com/weather/schemas";

private WeatherService weatherService;

public void setWeatherService(WeatherService weatherService) {
    this.weatherService = weatherService;
}

@PayloadRoot(
        localPart = "GetTemperaturesRequest",
        namespace = namespaceUri)
protected GetTemperaturesResponse getTemperature(GetTemperaturesRequest request) {
    List<TemperatureInfo> temperatures = weatherService.getTemperatures(request.getCity(), request.getDates());
    return new GetTemperaturesResponse(temperatures);
}
}

我在根目录下部署到Tomcat(&#34; /&#34;) - 没有错误,部署正常。下面是生成的wsdl,但有一个有趣的说明是我可以使用以http://localhost:8080开头并以&#34; /temperature.wsdl"结尾的任何URL来点击它。即http://localhost:8080/weather/services/temperature.wsdl使我与http://localhost:8080/blah/blah/blah/temperature.wsdl

相同的wsdl

WSDL:

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:schema="http://nick.com/weather/schemas" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://nick.com/weather/schemas">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://nick.com/weather/schemas">
<xs:element name="GetTemperaturesRequest">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="city" type="xs:string"/>
            <xs:element maxOccurs="5" minOccurs="1" name="date" type="xs:date"/>
        </xs:sequence>
     </xs:complexType>
</xs:element>
<xs:element name="GetTemperaturesResponse">
    <xs:complexType>
        <xs:sequence>
            <xs:element maxOccurs="5" minOccurs="1" name="TemperatureInfo">
                 <xs:complexType>
                     <xs:sequence>
                          <xs:element name="min" type="xs:float"/>
                          <xs:element name="max" type="xs:float"/>
                          <xs:element name="average" type="xs:float"/>
                     </xs:sequence>
                     <xs:attribute name="city" type="xs:string" use="optional"/>
                     <xs:attribute name="date" type="xs:date" use="optional"/>
                 </xs:complexType>
            </xs:element> 
        </xs:sequence>
    </xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message name="GetTemperaturesRequest">
    <wsdl:part element="schema:GetTemperaturesRequest" name="GetTemperaturesRequest"></wsdl:part>
</wsdl:message>
<wsdl:message name="GetTemperaturesResponse">
    <wsdl:part element="schema:GetTemperaturesResponse" name="GetTemperaturesResponse"></wsdl:part>
</wsdl:message>
<wsdl:portType name="Weather">
    <wsdl:operation name="GetTemperatures">
        <wsdl:input message="schema:GetTemperaturesRequest" name="GetTemperaturesRequest"></wsdl:input>
        <wsdl:output message="schema:GetTemperaturesResponse" name="GetTemperaturesResponse"></wsdl:output>
    </wsdl:operation>
</wsdl:portType>
<wsdl:binding name="WeatherBinding" type="schema:Weather">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="GetTemperatures">
        <soap:operation soapAction=""/>
        <wsdl:input name="GetTemperaturesRequest">
            <soap:body use="literal"/>
        </wsdl:input>
        <wsdl:output name="GetTemperaturesResponse">
            <soap:body use="literal"/>
        </wsdl:output>
    </wsdl:operation>
</wsdl:binding>
<wsdl:service name="WeatherService">
    <wsdl:port binding="schema:WeatherBinding" name="WeatherPort">
        <soap:address location="http://localhost:8080/weather/services"/>
    </wsdl:port>
</wsdl:service>
</wsdl:definitions>

我试图通过将SoapUI指向:http://localhost:8080/weather/services/temperature.wsdl

来针对这些设置SoapUI测试

生成一个看起来正确(我认为)的SOAP请求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://nick.com/weather/schemas">
<soapenv:Header/>
<soapenv:Body>
   <sch:GetTemperaturesRequest>
      <sch:city>Chicago</sch:city>
      <!--1 to 5 repetitions:-->
      <sch:date>2014-06-24</sch:date>
   </sch:GetTemperaturesRequest>
</soapenv:Body>
</soapenv:Envelope>

但是通过发送请求给我404回复:

HTTP/1.1 404 Not Found

有关我可能做错的任何见解?谢谢!

1 个答案:

答案 0 :(得分:2)

哇,令人难以置信 - 在所有事情上,它是我在TemperatureMarshallingEndpoint中的“getTemperature()”方法的访问修饰符。它是“受保护的”,但需要“公开”(在改变之后就像魅力一样!)