Java Spring Boot SOAP 客户端中的 JAXB 异常

问题描述 投票:0回答:1

我正在尝试创建一个 Java Spring Boot SOAP 客户端。 我按照以下说明操作:https://www.baeldung.com/spring-soap-web-service

我正在使用 Java 17 和 Spring 3.1.0。

基本步骤是:

  1. 从 wsdl 生成类
  • 在这里我对指令做了一个小小的修改。我将生成目录更改为:
    ${project.basedir}/target/generate-sources,这样我就不会在项目中生成文件
  • 但这不是问题的根源,因为我将其更改为指令(src / main / java)中的值并且没有任何改变

这是我的pom文件的一部分

<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>
        <schemaLanguage>WSDL</schemaLanguage>
        <generateDirectory>${project.basedir}/target/generate-sources</generateDirectory>
        <generatePackage>de.mat.test.country</generatePackage>
        <schemaDirectory>${project.basedir}/src/main/resources/wsdl</schemaDirectory>
        <schemaIncludes>
            <include>countries.wsdl</include>
        </schemaIncludes>
    </configuration>
</plugin>

类生成工作正常,因为我可以导入和使用以下类中的类。

  1. 我使用以下代码创建了 Client 和 ClientConfig
public class CountryClient extends WebServiceGatewaySupport {

  public GetCountryResponse getCountry(String country) {
    GetCountryRequest request = new GetCountryRequest();
    request.setName(country);

    var webServiceTemplate = getWebServiceTemplate();
    var response = webServiceTemplate.marshalSendAndReceive(request);
    GetCountryResponse getCountryResponse = (GetCountryResponse) response;
    return getCountryResponse;
  }
}
@Configuration
public class CountryClientConfig {

    @Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("de.mat.test.country"); // this is the only thing changed here
        return marshaller;
    }

    @Bean
    public CountryClient countryClient(Jaxb2Marshaller marshaller) {
        CountryClient client = new CountryClient();
        client.setDefaultUri("http://localhost:8080/ws");
        client.setMarshaller(marshaller);
        client.setUnmarshaller(marshaller);
        return client;
    }
}
  1. 最后我创建了测试类,由于较新的 spring 版本而对注释进行了更改
@SpringBootTest // this was @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CountryClientConfig.class, loader = AnnotationConfigContextLoader.class)
public class ClientLiveTest {

    @Autowired
    CountryClient client;

    @Test
    public void givenCountryService_whenCountryGermany_thenCapitalIsBerlin() {
        GetCountryResponse response = client.getCountry("GER");
        assertEquals("BLN", response.getCountry().getCapital());
    }

    @Test
    public void givenCountryService_whenCountrySpain_thenCurrencyEUR() {
        GetCountryResponse response = client.getCountry("ESP");
        assertEquals(Currency.EUR, response.getCountry().getCurrency());
    }
}

完成所有这些并运行测试后,我得到一个 JAXB 异常:

org.springframework.oxm.UncategorizedMappingException: Unknown JAXB exception
 at org.springframework.oxm.jaxb.Jaxb2Marshaller.convertJaxbException(Jaxb2Marshaller.java:958)
 at org.springframework.oxm.jaxb.Jaxb2Marshaller.marshal(Jaxb2Marshaller.java:716)
 at org.springframework.ws.support.MarshallingUtils.marshal(MarshallingUtils.java:80)
 at org.springframework.ws.client.core.WebServiceTemplate$2.doWithMessage(WebServiceTemplate.java:399)
 at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:569)
 at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:539)
 at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:391)
 at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:385)
 at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:375)
 at de.mat.test.client.CountryClient2.getCountry(CountryClient2.java:15)
 at de.mat.test.ClientLiveTest.givenCountryService_whenCountrySpain_thenCurrencyEUR(ClientLiveTest.java:31)
 at java.base/java.util.ArrayList.forEach(Unknown Source)
 at java.base/java.util.ArrayList.forEach(Unknown Source)
Caused by: jakarta.xml.bind.JAXBException: class de.mat.test.country.GetCountryRequest nor any of its super class is known to this context.
 at org.glassfish.jaxb.runtime.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:543)
 at org.glassfish.jaxb.runtime.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:444)
 at org.glassfish.jaxb.runtime.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:265)
 at org.glassfish.jaxb.runtime.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:197)
 at org.springframework.oxm.jaxb.Jaxb2Marshaller.marshal(Jaxb2Marshaller.java:712)

有谁知道这里的问题可能是什么? 我是否缺少注释或其他内容? 是因为我使用了较新的 Spring Boot 版本吗?

如果需要,我很乐意提供更多信息。

提前致谢, 保罗

java spring-boot soap marshalling soap-client
1个回答
0
投票

我能够使用 pom.xml 中的这些配置并删除所有 javax 依赖项,成功运行 Spring Boot 3.1.0 和 Java 17:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.5</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.ws</groupId>
    <artifactId>jaxws-rt</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
</dependency>
....
<build>
    <plugins>
        <plugin>
            <groupId>com.sun.xml.ws</groupId>
            <artifactId>jaxws-maven-plugin</artifactId>
            <version>4.0.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>wsimport</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <packageName>{com.example.wsdl}</packageName>
                <wsdlUrls>
                    <wsdlUrl>{url}</wsdlUrl>
                </wsdlUrls>
                <sourceDestDir>${basedir}/src/main/java</sourceDestDir>
                <extension>true</extension>
                <keep>true</keep>
                <verbose>true</verbose>
                <vmArgs>
                    <vmArg>-Djavax.xml.accessExternalSchema=all</vmArg>
                </vmArgs>
            </configuration>
        </plugin>
    </plugins>
</build>
© www.soinside.com 2019 - 2024. All rights reserved.