You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3.1+Java17搭建SOAP客户端遇JAXB异常求助

问题描述

基于Java 17和Spring 3.1.0搭建Spring Boot SOAP客户端时遇到JAXB异常,具体操作及报错如下:

操作步骤

  1. 从WSDL生成类

    • 生成目录修改为${project.basedir}/target/generate-sources,改回src/main/java问题依旧。
    • pom.xml相关配置:
    <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>
    

    类生成正常,可在代码中正常导入使用。

  2. 创建Client和ClientConfig类

    • CountryClient类:
    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;
      }
    }
    
    • CountryClientConfig类:
    @Configuration
    public class CountryClientConfig {
    
        @Bean
        public Jaxb2Marshaller marshaller() {
            Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
            marshaller.setContextPath("de.mat.test.country"); // 仅此处修改
            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;
        }
    }
    
  3. 创建测试类(适配Spring新版本修改注解)

    @SpringBootTest // 原教程为@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)

解决方案

该问题核心是JAXBContext无法识别生成的实体类,针对Java 17+Spring 3.x的环境,可通过以下方式解决:

1. 替换setContextPath为setClassesToBeBound

Spring 3.x搭配Java 17时,setContextPath方法在处理模块路径下的生成类时易失效,改用setClassesToBeBound直接指定需要绑定的类,确保JAXB能识别:

@Bean
public Jaxb2Marshaller marshaller() {
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    // 替换原setContextPath,直接指定生成的请求、响应等类
    marshaller.setClassesToBeBound(GetCountryRequest.class, GetCountryResponse.class, Country.class, Currency.class);
    return marshaller;
}

2. 确保生成类被编译识别

  • 检查target/generate-sources目录是否被IDE标记为源码根目录,若未标记,手动设置该目录为Sources Root,确保编译时包含这些类。
  • 执行mvn clean compile命令,强制Maven编译生成类,避免类路径缺失问题。

3. 适配JPMS模块配置(若启用)

如果项目使用Java模块系统(存在module-info.java),需添加JAXB依赖并导出生成类的包:

module de.mat.test {
    requires jakarta.xml.bind;
    requires spring.ws;
    requires spring.context;
    // 导出生成类的包,允许JAXB访问
    exports de.mat.test.country;
}

4. 简化测试类注解

@SpringBootTest已包含上下文配置,可移除冗余的@ContextConfiguration:

@SpringBootTest(classes = CountryClientConfig.class)
public class ClientLiveTest {
    // 测试代码保持不变
}

5. 验证JAXB依赖兼容性

确保项目中JAXB依赖(如org.glassfish.jaxb:jaxb-runtime)与Spring 3.1.0兼容,建议使用Spring Boot管理的依赖版本,避免版本冲突。


内容的提问来源于stack exchange,提问作者P D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 01:17:03