使用spring-ws发布webservice服务

spring-ws

添加依赖、插件

pom.xml添加

xml 复制代码
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.ws</groupId>
            <artifactId>spring-ws-core</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/wsdl4j/wsdl4j -->
        <dependency>
            <groupId>wsdl4j</groupId>
            <artifactId>wsdl4j</artifactId>
            <version>1.6.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
plain 复制代码
<!--            要用的时候把下面插件打开, 不用了记得注释-->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>jaxb2-maven-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <id>xjc</id>
                        <goals>
                            <goal>xjc</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <sources>
                        <source>${project.basedir}/src/main/resources/xsd/fakeBindUrl.xsd</source>
                    </sources>
                </configuration>
            </plugin>

创建XSD文件

对比实际输入输出参考修改xsd

实际输入、输出

输入
xml 复制代码
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:snr="snr">
<soapenv:Header/>
<soapenv:Body>
<snr:bindRequest soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<RequestInfo xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<Root>
<Domain>host</Domain>
<Passwd>pasdasjidojoi</Passwd>
<SrvCode>489489489445645648</SrvCode>
<Content>
<![CDATA[<?xml version='1.0' encoding='UTF-8'?><FakePassQuery><FakeCode>admin</FakeCode><Password><![CDATA[dsaiodas54545]]]]><![CDATA[></Password><FakeType>1000</FakeType></FakePassQuery>]]>
</Content>
</Root>
</RequestInfo></snr:bindRequest></soapenv:Body></soapenv:Envelope>
输出
xml 复制代码
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header/>
    <SOAP-ENV:Body>
        <FakePassQueryResponse>
            <ExchangeId>a79bc02ea21a4a13a7c58108cc864a9d</ExchangeId>
            <ErrorCode>00000</ErrorCode>
            <IsSuccess>T</IsSuccess>
            <FakeContent>
                <FakeId>1</FakeId>
                <FakeCode>admin</FakeCode>
                <StaffName>admin</StaffName>
                <OrgId/>
                <EffDate>2024-01-01 00:00:00</EffDate>
                <ExpDate>2125-01-08 13:28:52</ExpDate>
                <StatusCd>0</StatusCd>
                <ContactTel/>
                <SmsTel/>
            </FakeContent>
        </FakePassQueryResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

xsd

xml 复制代码
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://spring.io/guides/gs-producing-web-service"
           targetNamespace="http://spring.io/guides/gs-producing-web-service" elementFormDefault="qualified">
    <xs:element name="bindRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="RequestInfo" type="tns:RequestInfo"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="RequestInfo">
        <xs:sequence>
            <xs:element name="Root" type="tns:Root"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="Root">
        <xs:sequence>
            <xs:element name="Domain" type="xs:string"/>
            <xs:element name="Passwd" type="xs:string"/>
            <xs:element name="SrvCode" type="xs:string"/>
            <xs:element name="Content" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="FakePassQuery">
        <xs:sequence>
            <xs:element name="FakeCode" type="xs:string"/>
            <xs:element name="Password" type="xs:string"/>
            <xs:element name="FakeType" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>

    <xs:element name="FakePassQueryResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="ErrorInfo" type="xs:string"/>
                <xs:element name="ResultCode" type="xs:string"/>
                <xs:element name="ExchangeId" type="xs:string"/>
                <xs:element name="ErrorCode" type="xs:string"/>
                <xs:element name="IsSuccess" type="xs:string"/>
                <xs:element name="FakeContent" type="tns:FakeContent"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="FakeContent">
        <xs:sequence>
            <xs:element name="FakeId" type="xs:string"/>
            <xs:element name="FakeCode" type="xs:string"/>
            <xs:element name="StaffName" type="xs:string"/>
            <xs:element name="OrgId" type="xs:string"/>
            <xs:element name="EffDate" type="xs:string"/>
            <xs:element name="ExpDate" type="xs:string"/>
            <xs:element name="StatusCd" type="xs:string"/>
            <xs:element name="ContactTel" type="xs:string"/>
            <xs:element name="SmsTel" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>

</xs:schema>

生成xsd实体

idea -> maven -> 插件 -> jaxb2 -> jaxb2:xjc

生成的文件在:target\generated-sources\jaxb

配置

java 复制代码
@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
    @Bean
    public ServletRegistrationBean<MessageDispatcherServlet> messageDispatcherServlet(ApplicationContext applicationContext) {
        MessageDispatcherServlet servlet = new MessageDispatcherServlet();
        servlet.setApplicationContext(applicationContext);
        servlet.setTransformWsdlLocations(true);
        return new ServletRegistrationBean<>(servlet, "/ws/*");
    }

    // 这里的BeanName就是实际访问路径,当前服务请求路径: ip:port/ws/fakeBindUrl
    @Bean(name = "fakeBindUrl")
    public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema subAcctInfoForSelfBindSchema) {
        DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
        wsdl11Definition.setPortTypeName("CountriesPort");
        wsdl11Definition.setLocationUri("/ws");
        wsdl11Definition.setTargetNamespace("snr");
        wsdl11Definition.setSchema(subAcctInfoForSelfBindSchema);
        return wsdl11Definition;
    }
    
    @Bean
    public XsdSchema subAcctInfoForSelfBindSchema() {
        return new SimpleXsdSchema(new ClassPathResource("xsd/fakeBindUrl.xsd"));
    }

    // 多个webservice服务,则注册多个wsdl11Definition、XsdSchema
    // 这里的BeanName就是实际访问路径,当前这个就是/ws/fakeBindUrl2
    // @Bean(name = "fakeBindUrl2")
    // public DefaultWsdl11Definition defaultWsdl11Definition2(XsdSchema subAcctInfoForSelfBindSchema2) {
    // 	DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
    // 	wsdl11Definition.setPortTypeName("CountriesPort");
    // 	wsdl11Definition.setLocationUri("/ws");
    // 	wsdl11Definition.setTargetNamespace("snr");
    // 	wsdl11Definition.setSchema(subAcctInfoForSelfBindSchema);
    // 	return wsdl11Definition;
    // }
    
    // @Bean
    // public XsdSchema subAcctInfoForSelfBindSchema2() {
    // 	return new SimpleXsdSchema(new ClassPathResource("xsd/fakeBindUrl.xsd"));
    // }
}

定义Endpoint

java 复制代码
@Endpoint
@Slf4j
public class bindRequestEndpoint {
    private static final String NAMESPACE_URI = "snr";
    
    @Autowired
    private SubAcctBindingService subAcctBindingService;
    
    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "bindRequest")
    @ResponsePayload
    public FakePassQueryResponse fakeBindUrl(@RequestPayload bindRequest requestInfo) {
        try {
            log.info("收到请求: {}", requestInfo);
            // 解析requestInfo的XML内容进行业务处理
            FakePassQuery FakePassQuery = parseInnerXML(requestInfo.getRequestInfo().getRoot().getContent());
            FakePassQueryResponse result = subAcctBindingService.processBindRequest(FakePassQuery);
            return result;
        } catch (Exception e) {
            log.error("处理请求时发生异常: ", e);
            // 组装错误响应
            FakePassQueryResponse response = new FakePassQueryResponse();
            response.setErrorInfo(e.getMessage());
            response.setResultCode("-1");
            response.setIsSuccess("F");
            return response;
        }
    }
}

启动服务

当前服务的ip端口号
ip:port/ws/fakeBindUrl?wsdl

其他

如遇报错可以在入参中尝试加入namespace

java 复制代码
@XmlRootElement(namespace="", ...)

1 counts of IllegalAnnotationExceptions

入参或出参定义有问题
@XmlTypepropOrder与实际属性不符等等

相关推荐
咩咩啃树皮4 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
鱟鲥鳚4 小时前
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)
java·spring boot
大模型码小白6 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
腾渊信息科技公司6 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地7 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
wuqingshun3141598 小时前
TCP超时重传机制是为了解决什么问题?
java
莫逸风10 小时前
【AgentScope 2.0】 0. 学习指南
java·llm·agent·agentscope
隔窗听雨眠10 小时前
Spring Boot在云原生时代的编程范式革新研究
spring boot·后端·云原生
z1234567898611 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
yaoxin52112311 小时前
470. Java 反射 - Member 接口与 AccessFlag
java·开发语言·python