嗨我是Spring WebServices的新手.我想通过一个标准示例,其中WSDL作为Provider的输入提供.现在,这个WSDL的客户端代码将如何呈现.我们需要在客户端生成存根代码吗?
我目前正面临使用Spring WS的错误代码和消息的问题.
我们使用带有JAXB2绑定的Spring WS 2.0以及@Endpoint和@PayloadRoot注释以方便使用.
我们的端点如下所示:
@Endpoint
public class MyEndpoint() {
private static final String MY_NAMESPACE=...;
@PayloadRoot(namespace=MY_NAMESPACE, localPart="myPart")
public MyPartResponse handleMyPart(MyPart myPart) {
....
}
}
Run Code Online (Sandbox Code Playgroud)
我们仅将soap用作围绕由XSD定义的POX消息的薄包装器.这也意味着我们使用返回码和消息而不是故障.
每个响应都继承自
<xs:complexType name="ResultBase">
<xs:sequence>
<xs:element name="errorCode" type="tns:ErrorCode" />
<xs:element name="errorMessage" type="xs:string" />
</xs:sequence>
</xs:complexType>
Run Code Online (Sandbox Code Playgroud)
并在成功的情况下添加一些细节,如下所示:
<xs:element name="MySpecificResponse">
<xs:complexType>
<xs:complexContent>
<xs:extension base="tns:ResultBase">
<xs:sequence>
<xs:element name="mySpecificElement" type="tns:MySpecificType" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
Run Code Online (Sandbox Code Playgroud)
可以干净地映射handleMyPart方法中抛出的所有异常.
但是,有两种类型的错误仍然未被捕获并生成错误而不是明确的错误消息:
在一天结束时,这些是与使用Spring WS的每个POX Web服务相关的问题.如何拦截这些异常并将其映射到响应对象?
但请记住:所有响应对象都略有不同,因为它们都是从公共响应对象继承的,但是为它添加了一些唯一的可选内容.
我有一个Web服务,我试图使用Spring和Jaxb实现.我已经使用这两种方法提供了一些工作服务 - 但由于响应的格式,这项特殊服务给我带来了困难.在我的XSD中,响应定义如下(注意它是单个元素):
<!-- Response definition -->
<element name="ServiceResponse" type="Q1:Outcome"/>
<!-- Outcome definition -->
<complexType name="Outcome">
<sequence>
<element name="ErrorCode">
<simpleType>
<restriction base="string">
<maxLength value="8"/>
</restriction>
</simpleType>
</element>
<element name="ErrorText">
<simpleType>
<restriction base="string">
<maxLength value="1000"/>
</restriction>
</simpleType>
</element>
<element name="DocumentId">
<simpleType>
<restriction base="string">
<maxLength value="30"/>
</restriction>
</simpleType>
</element>
</sequence>
</complexType>
Run Code Online (Sandbox Code Playgroud)
我有一个看起来像这样的服务方法:
@PayloadRoot( localPart = SERVICE_REQUEST, namespace = NAMESPACE )
public Outcome processFileRequest( ServiceRequest requestObject )
Run Code Online (Sandbox Code Playgroud)
我最终得到一个如下所示的异常:
java.lang.IllegalStateException:没有适配器端点[公共dortman.xsd.objects.Outcome dortman.annotated.MyTestEndpoint.processFileRequest(dortman.xsd.objects.ServiceRequest)]:请问您的端点实现类似的MessageHandler或PayloadEndpoint支持的接口?
在Spring论坛和Stackoverflow上找到一些相关帖子之后,似乎返回对象需要具有XmlRootElement注释或包含在JAXBElement中.为了尝试第一个,我将XSD中的响应更改为:
<!-- Response definition -->
<element name="ServiceResponse">
<complexType>
<sequence>
<element name="FileSize" type="long"/>
</sequence> …Run Code Online (Sandbox Code Playgroud) 我有一个用例,如果SOAP请求没有针对NewWebService的XSD和WSDL进行验证,则需要对NewWebService的所有调用都路由到OldWebService.NewWebService位于ServerA上,OldWebService位于ServerB上.
抽象地说,我知道我需要一些机制来允许我接受命中NewWebService的SOAP请求,将其发送到OldWebService,然后将SOAP结果返回给客户端.我对spring-ws的有限经验使得很难决定如何实现这一目标.
我的第一个想法是在NewWebService中构建一个SOAP客户端,只要无法验证有效负载,就会调用OldWebService.这是最好的解决方案,还是有更好的方法允许NewWebService充当某些请求的传递?
我正在尝试在子上下文中使用spring安全上下文,因此我可以在servlet上下文文件中使用url安全性.
我有:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/spring-security.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>myapp-soap</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
Run Code Online (Sandbox Code Playgroud)
在web.xml上,spring-security.xml上的一般安全配置和
<!-- Authorization configurations -->
<security:http auto-config="false" use-expressions="true"
create-session="never"
authentication-manager-ref="authenticationManager"
entry-point-ref="authenticationEntryPoint">
<security:custom-filter
position="PRE_AUTH_FILTER" ref="serviceAuthenticationFilter"/>
<security:intercept-url
pattern="/GetForbiddenUrl" access="hasRole('roleThatDoesntExist')" />
<security:intercept-url pattern="/**" access="permitAll" />
</security:http>
<!-- annotation security -->
<security:global-method-security pre-post-annotations="enabled"/>
Run Code Online (Sandbox Code Playgroud)
在myapp-soap-servlet.xml上.它不起作用但失败了
ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/my-app/v1/soap]] (ServerService Thread Pool -- 192) JBWEB000284: Exception starting filter springSecurityFilterChain:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' is defined
Run Code Online (Sandbox Code Playgroud)
但是,如果我将<security:http>部分移动到spring-security root …
几乎所有API都处理不同的发行版本.通常你会看到这种版本:
但是我没有找到一个描述如何在Spring堆栈中组织它们的源代码.我想在每个控制器上都有一个/v1前缀@RequestMapping("/v1/questions")不是最好的方法.
想象一下@Service,只有当前版本的一层(在我们的例子中是V2).
我们的服务应该处理V1和V2的请求.唯一的变化是V2在问题实体上添加了一个新字段(这意味着V1问题可以很容易地转换为V2问题).
现在的问题是:
~.web.* @Controllerjava包的观点?~.web.* @Controller他们知道他们的版本的不同?以这种方式RequestMapping?或者是否可以使用上下文配置它们:在V1 java包中进行组件扫描?一个例子看起来像这样(我在各处添加了包):
// on V1 Question look like this:
public class project.domain.Question
{
private String question;
}
// on v2 Question looks like this:
public class project.domain.Question
{
private String question;
private Date creationDate;
}
@Service
public class project.service.QuestionService
{
public long create(Question q) {...};
public Question read(long id) {...};
public void remove(long id) …Run Code Online (Sandbox Code Playgroud) 我正在尝试从本教程创建一个示例项目,并在tomcat-6.0.14上运行服务器端项目,但是当我尝试使用以下xml的SoapUI调用webservice时:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://mycompany.com/hr/schemas">
<soapenv:Header/>
<soapenv:Body>
<sch:HolidayRequest>
<!--You may enter the following 2 items in any order-->
<sch:Holiday>
<sch:StartDate>2006-07-03</sch:StartDate>
<sch:EndDate>2006-07-03</sch:EndDate>
</sch:Holiday>
<sch:Employee>
<sch:Number>42</sch:Number>
<sch:FirstName>Kevin</sch:FirstName>
<sch:LastName>Garnett</sch:LastName>
</sch:Employee>
</sch:HolidayRequest>
</soapenv:Body>
</soapenv:Envelope>
Run Code Online (Sandbox Code Playgroud)
返回xml是:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring xml:lang="en">No adapter for endpoint [public void com.mycompany.hr.ws.HolidayEndpoint.handleHolidayRequest(org.jdom.Element) throws java.lang.Exception]: Is your endpoint annotated with @Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Run Code Online (Sandbox Code Playgroud)
为什么没有端点适配器发生?我用Google搜索,但没有找到根本原因.有人可以提供一些帮助吗?
这是我的代码和配置:
的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 …Run Code Online (Sandbox Code Playgroud) 我必须准备一个web服务来接受已定义的wsdl结构.我按照这里的教程,在这里可以下载测试项目的源代码.
对于像这样的xsd:
<xs:element name="getCountryRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Run Code Online (Sandbox Code Playgroud)
应用程序返回的请求的Wsdl操作正常,如下所示:
<wsdl:binding name="CountriesPortSoap11" type="tns:CountriesPort">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getCountry">
<soap:operation soapAction=""/>
<wsdl:input name="getCountryRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getCountryResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
Run Code Online (Sandbox Code Playgroud)
但是当我将xsd更改为(元素名称中没有'Request')时:
<xs:element name="getCountry">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Run Code Online (Sandbox Code Playgroud)
wsdl无效,并且没有<input>指定:
<wsdl:binding name="CountriesPortSoap11" type="tns:CountriesPort">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getCountry">
<soap:operation soapAction=""/>
<wsdl:output name="getCountryResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
Run Code Online (Sandbox Code Playgroud)
我该如何解决这个问题?如何Request在wsdl中将无元素作为soap操作输入正确显示?
在开始之前:我知道子节点从父节点继承命名空间,这就是我的问题发生的原因.不幸的是,我发送XML的Web服务不接受没有命名空间的子节点,并且因为它是一个政府实体,所以它们的部分变化是不太可能的.
话虽这么说,我使用Spring-WS在我的应用程序和Web服务之间进行通信,因此框架使用变换器以一种方式使用转换器将我的有效负载源解析为框架的有效负载结果:
transformer.transform(Source, Result);
Run Code Online (Sandbox Code Playgroud)
在进行转换之前,我的XML有这两个节点,如下所示:
<enviNFe xmlns="http://www.portalfiscal.inf.br/nfe" versao="3.10">
<NFe xmlns="http://www.portalfiscal.inf.br/nfe">
Run Code Online (Sandbox Code Playgroud)
转换后,第二个命名空间被删除(正如我之前所说,我知道原因):
<enviNFe xmlns="http://www.portalfiscal.inf.br/nfe" versao="3.10">
<NFe>
Run Code Online (Sandbox Code Playgroud)
我也知道我可以使用marshallers来实现相同的结果并自己编写解析代码.使用这种方法也是可以接受的,但我不知道使用除上面列出的方法之外的其他方法来实现相同的事情(转换javax.xml.transform.Source为javax.xml.transform.Result).
那我有两个问题:
1 - 我可以避免使用默认方法(不使用marshallers)的行为吗?
2 - 是否还有其他工具可以进行相同的转换?
我有一个简单的 Spring Boot 应用程序,我想将请求发送到 SOAP 端点。不幸的是,每次我尝试这样做时,我都会收到:javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath。我非常有信心我拥有所有必需的库,但我不知道为什么会发生这种情况
Caused by: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:177)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:364)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:508)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:465)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:366)
at org.springframework.oxm.jaxb.Jaxb2Marshaller.createJaxbContextFromContextPath(Jaxb2Marshaller.java:540)
at org.springframework.oxm.jaxb.Jaxb2Marshaller.getJaxbContext(Jaxb2Marshaller.java:500)
... 18 common frames omitted
Caused by: java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
at javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:122)
at javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:155)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:174)
... 24 common frames omitted
Run Code Online (Sandbox Code Playgroud)
我使用的是JDK17
openjdk 17.0.2 2022-01-18
OpenJDK …Run Code Online (Sandbox Code Playgroud) spring-ws ×10
java ×7
web-services ×5
spring ×4
jaxb ×2
soap ×2
cxf ×1
jaxb2 ×1
jboss7.x ×1
rest ×1
spring-boot ×1
spring-mvc ×1
spring-oxm ×1
wsdl ×1
xml ×1
xml-parsing ×1