java - 使用 Spring Boot 使用 SoapWeb 服务不起作用?
问题描述
我正在使用 open-jdk 11 和 spring boot 版本 2.3.0.RELEASE。我是肥皂网络服务的新手,我想尝试使用肥皂生产商样本进行测试。以下是我尝试使用的 wsdl 链接: http ://www.thomas-bayer.com/axis2/services/BLZService?wsdl
我在 pom.xml 中添加了以下插件,用于从 wsdl 生成类:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.14.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<generatePackage>soapws.credins.api</generatePackage>
<generateDirectory>${project.basedir}/src/main/java</generateDirectory>
<schemaDirectory>${project.basedir}/src/main/resources/wsdl</schemaDirectory>
<schemaIncludes>
<include>*.wsdl</include>
</schemaIncludes>
<clearOutputDir>true</clearOutputDir>
</configuration>
</plugin>
然后我运行 amvn install
并且所有类都成功生成。我创建了一个Jaxb2Marshaller
用于从 java 类转换为 xml 的 bean。下面是实现:
@Configuration
public class SoapConfiguration {
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("package.api");
return marshaller();
}
}
之后,我创建了一个客户端类,它可以进行如下的肥皂调用:
@Component
public class BankClient {
@Autowired
private Jaxb2Marshaller marshaller;
private WebServiceTemplate template;
public DetailsType getBankDetails(String blz) {
GetBankType request = new GetBankType();
request.setBlz(blz);
template = new WebServiceTemplate(marshaller);
DetailsType detail = (DetailsType) template
.marshalSendAndReceive("http://www.thomas-bayer.com/axis2/services/BLZService", request);
return detail;
}
}
执行调用时遇到问题:
org.springframework.oxm.MarshallingFailureException: JAXB marshalling exception; nested exception is javax.xml.bind.MarshalException
- with linked exception:
我通过添加如下@XmlRootElement
toGetBankType
类解决了这个问题:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getBankType", propOrder = {
"blz"
})
public class GetBankType {
@XmlElement(required = true)
protected String blz;
/**
* Gets the value of the blz property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getBlz() {
return blz;
}
/**
* Sets the value of the blz property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setBlz(String value) {
this.blz = value;
}
}
现在我被这个问题困住了:我无法弄清楚问题出在哪里。
org.springframework.ws.soap.client.SoapFaultClientException: The endpoint reference (EPR) for the Operation not found is http://www.thomas-bayer.com/axis2/services/BLZService and the WSA Action =
at org.springframework.ws.soap.client.core.SoapFaultMessageResolver.resolveFault(SoapFaultMessageResolver.java:38)
at org.springframework.ws.client.core.WebServiceTemplate.handleFault(WebServiceTemplate.java:830)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:624)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:378)
at soapws.client.BankUpClient.getBankDetails(BankUpClient.java:26)
我究竟做错了什么
解决方案
首先@XmlRootElement
从 package 中生成的类中删除package.api
。
接下来修改BankClient
如下:
@Component
public class BankClient {
@Autowired
private Jaxb2Marshaller jaxb2Marshaller;
private WebServiceTemplate template;
public JAXBElement<GetBankResponseType> getBankDetails(String blz) {
GetBankType getBankType = new GetBankType();
getBankType.setBlz(blz);
ObjectFactory objectFactory = new ObjectFactory();
JAXBElement<GetBankType> request = objectFactory.createGetBank(getBankType);
template = new WebServiceTemplate(jaxb2Marshaller);
JAXBElement<GetBankResponseType> response = (JAXBElement<GetBankResponseType>) template
.marshalSendAndReceive("http://www.thomas-bayer.com/axis2/services/BLZService", request);
return response;
}
}
要构建请求,您需要使用ObjectFactory
从 WSDL 自动生成的类。
ObjectFactory
类允许我们以编程方式从表示 XML 内容的 java 对象构造请求。
接下来要记住的是,您将从中获得的响应也WebServiceTemplate
将GetBankResponseType
包装在 XML 内容的表示中。
GetBankResponseType
将是一个对象,它将包含我们从肥皂接收到的信息的内容模型和属性值。
下面是 BankClient 的集成测试:
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class BankClientTest {
@Autowired
private BankClient client;
@BeforeEach
public void setup() {
}
@Test
void testGetBankDetails() {
// setup
String blzCode = "39580041";
String bezeichnungExpected = "Dresdner Bank";
String bicExpected = "DRESDEFF395";
String ortExpected = "Düren, Rheinl";
String plzExpected = "52304";
// execute
JAXBElement<GetBankResponseType> response = client.getBankDetails(blzCode);
// verify
assertEquals(bezeichnungExpected, response.getValue().getDetails().getBezeichnung());
assertEquals(bicExpected, response.getValue().getDetails().getBic());
assertEquals(ortExpected, response.getValue().getDetails().getOrt());
assertEquals(plzExpected, response.getValue().getDetails().getPlz());
}
}
推荐阅读
- javascript - 如何在客户端从 mongodb 获取数据?
- c - 使用双下划线时启用编译器警告
- python - 使用 tensorflow 加载 LSUN 数据集
- python - 根据 txt 文件中的搜索结果分配变量值
- sql-server - 不使用动态 SQL 查询表月数据
- grafana - 如何访问通过grafana中的URL传递的变量?
- plone - 根据用户 ID 列表设置内容访问权限
- angular - 如何在 Kendo Grid 内嵌编辑中格式化日期
- python-2.7 - 使用 gdal 在 S3 中保存图像
- python - Django 根据值从查询集中获得不同的结果