根据需求定制spingboot-spring-webservice的wsdl

 

springboot-ws基础框架搭建步骤:

1.用idea创建spring-boot项目,具体的步骤省略;

2.pom添加webservice依赖:  

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web-services</artifactId>
</dependency>

<dependency>
   <groupId>wsdl4j</groupId>
   <artifactId>wsdl4j</artifactId>
</dependency>

3.添加配置类,这是springboot-ws的核心配置类:

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

	@Bean(name = "sso")
	public Wsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) {
		DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
		wsdl11Definition.setPortTypeName("SSOWebServiceSoap");
		wsdl11Definition.setLocationUri("/ws");
		wsdl11Definition.setTargetNamespace("http://tempuri.org/");
		wsdl11Definition.setSchema(countriesSchema);
		wsdl11Definition.setCreateSoap11Binding(true);
		wsdl11Definition.setCreateSoap12Binding(true);
		Properties soapActions = new Properties();
		soapActions.setProperty("ApplicationRegister", "http://tempuri.org/ApplicationRegister");
		soapActions.setProperty("LoginVerify", "http://tempuri.org/LoginVerify");
		wsdl11Definition.setSoapActions(soapActions);
		return wsdl11Definition;
	}

	@Bean
	public XsdSchema countriesSchema() {
		return new SimpleXsdSchema(new ClassPathResource("sso.xsd"));
	}

}

 

4. 在resource文件夹下创建xsd文件如下,其中ApplicationRegister和ApplicationRegisterResponse分别表示请求的对象以及响应的结果对象,可以在配置类中指定该文件的位置:

<s:schema xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://tempuri.org/"
           targetNamespace="http://tempuri.org/" elementFormDefault="qualified">
    <s:element name="ApplicationRegister">
        <s:complexType>
            <s:sequence>
                <s:element minOccurs="0" maxOccurs="1" name="inputdata" type="s:string" />
            </s:sequence>
        </s:complexType>
    </s:element>
    <s:element name="ApplicationRegisterResponse">
        <s:complexType>
            <s:sequence>
                <s:element minOccurs="0" maxOccurs="1" name="ApplicationRegisterResult" type="s:string" />
            </s:sequence>
        </s:complexType>
    </s:element>
</s:schema>

  指定位置: 

@Bean
	public XsdSchema countriesSchema() {
		return new SimpleXsdSchema(new ClassPathResource("sso.xsd"));
	}

 

5. 在xsd文件上右键操作,根据xsd生成实体类:

   

6. 创建Endpoint类,Endpoint类主要用于描述webservice提供的方法:

@Endpoint
public class SsoEndpointApi {
	private static final String NAMESPACE_URI = "http://tempuri.org/";

	private SsoEndpointService ssoEndpointService;
	
	/*
	*方法说明:系统注册
	* */
	@PayloadRoot(namespace = NAMESPACE_URI, localPart = "ApplicationRegister")
	@ResponsePayload
	public ApplicationRegisterResponse applicationRegister(@RequestPayload ApplicationRegister applicationRegister) {
		return ssoEndpointService.applicationRegister(applicationRegister);
	}

转换注意事项:

   1. 将url地址的风格统一,spring-ws发布的webservice默认url是http://xx:xx/xxx.wsdl,不符合常规的http://xx:xx/xxx?wsdl格式,我们可以利用urlrewritefilter去做一下转发:

    添加依赖:

<dependency>
   <groupId>org.tuckey</groupId>
   <artifactId>urlrewritefilter</artifactId>
   <version>4.0.4</version>
</dependency>

   实现UrlRewriteFilter:

package com.winning.webService.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.tuckey.web.filters.urlrewrite.Conf;
import org.tuckey.web.filters.urlrewrite.UrlRewriteFilter;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import java.io.IOException;
/**
 * @author zhanghong
 * @since 2018-08-17 16:01
 **/
@Component
public class WsdlUrlRewriteFilter extends UrlRewriteFilter {
    private static final String CONFIG_LOCATION = "classpath:/urlrewrite.xml";
    @Value(CONFIG_LOCATION)
    private Resource resource;
    @Override
    protected void loadUrlRewriter(FilterConfig filterConfig) throws ServletException {
        try {
            Conf conf = new Conf(filterConfig.getServletContext(), resource.getInputStream(), resource.getFilename(), "");
            checkConf(conf);
        } catch (IOException ex) {
            throw new ServletException("无法读取配置文件: " + CONFIG_LOCATION, ex);
        }
    }
}

    配置转发规则

    根据上面的CONFIG_LOCATION指明的位置,新建配置文件urlrewrite.xml,下面是一个例子

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN"
        "http://tuckey.org/res/dtds/urlrewrite3.2.dtd">
<urlrewrite use-query-string="true">
    <rule>
        <from>/ws/countries[\?]+wsdl</from>
        <to>/ws/countries.wsdl</to>
    </rule>
</urlrewrite>

2. springboot-ws 生成wsdl时候,所有的请求默认带上后缀名Request, 所有的响应默认带上后缀名Response,如果不带上,则识别不了,但是如果之前的cxf框架请求后缀不带Request,那么改造的时候需要如下的配置:

   自定义MyWsdl11Definition以及依赖的其他相关类:

public class MyWsdl11Definition implements Wsdl11Definition, InitializingBean {

    private final InliningXsdSchemaTypesProvider typesProvider = new InliningXsdSchemaTypesProvider();

    private final SuffixBasedMessagesProvider messagesProvider = new MySuffixBasedMessagesProvider();

    private final SuffixBasedPortTypesProvider portTypesProvider = new MySuffixBasedPortTypesProvider();

    private final SoapProvider soapProvider = new SoapProvider();

    private final ProviderBasedWsdl4jDefinition delegate = new ProviderBasedWsdl4jDefinition();

    private String serviceName;

    public MyWsdl11Definition() {
        delegate.setTypesProvider(typesProvider);
        delegate.setMessagesProvider(messagesProvider);
        delegate.setPortTypesProvider(portTypesProvider);
        delegate.setBindingsProvider(soapProvider);
        delegate.setServicesProvider(soapProvider);
    }

    public void setTargetNamespace(String targetNamespace) {
        delegate.setTargetNamespace(targetNamespace);
    }

    public void setSchema(XsdSchema schema) {
        typesProvider.setSchema(schema);
    }

    public void setSchemaCollection(XsdSchemaCollection schemaCollection) {
        typesProvider.setSchemaCollection(schemaCollection);
    }

    public void setPortTypeName(String portTypeName) {
        portTypesProvider.setPortTypeName(portTypeName);
    }

    public void setRequestSuffix(String requestSuffix) {
        portTypesProvider.setRequestSuffix(requestSuffix);
        messagesProvider.setRequestSuffix(requestSuffix);
    }

    public void setResponseSuffix(String responseSuffix) {
        portTypesProvider.setResponseSuffix(responseSuffix);
        messagesProvider.setResponseSuffix(responseSuffix);
    }

    public void setFaultSuffix(String faultSuffix) {
        portTypesProvider.setFaultSuffix(faultSuffix);
        messagesProvider.setFaultSuffix(faultSuffix);
    }

    public void setCreateSoap11Binding(boolean createSoap11Binding) {
        soapProvider.setCreateSoap11Binding(createSoap11Binding);
    }

    public void setCreateSoap12Binding(boolean createSoap12Binding) {
        soapProvider.setCreateSoap12Binding(createSoap12Binding);
    }

    public void setSoapActions(Properties soapActions) {
        soapProvider.setSoapActions(soapActions);
    }

    public void setTransportUri(String transportUri) {
        soapProvider.setTransportUri(transportUri);
    }

    public void setLocationUri(String locationUri) {
        soapProvider.setLocationUri(locationUri);
    }

    public void setServiceName(String serviceName) {
        soapProvider.setServiceName(serviceName);
        this.serviceName = serviceName;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (!StringUtils.hasText(delegate.getTargetNamespace()) && typesProvider.getSchemaCollection() != null &&
                typesProvider.getSchemaCollection().getXsdSchemas().length > 0) {
            XsdSchema schema = typesProvider.getSchemaCollection().getXsdSchemas()[0];
            setTargetNamespace(schema.getTargetNamespace());
        }
        if (!StringUtils.hasText(serviceName) && StringUtils.hasText(portTypesProvider.getPortTypeName())) {
            soapProvider.setServiceName(portTypesProvider.getPortTypeName() + "Service");
        }
        delegate.afterPropertiesSet();
    }

    @Override
    public Source getSource() {
        return delegate.getSource();
    }

}
public class MySuffixBasedMessagesProvider extends SuffixBasedMessagesProvider {

    protected String requestSuffix = DEFAULT_REQUEST_SUFFIX;

    public String getRequestSuffix() {
        return this.requestSuffix;
    }

    public void setRequestSuffix(String requestSuffix) {
        this.requestSuffix = requestSuffix;
    }

    @Override
    protected boolean isMessageElement(Element element) {
        if (isMessageElement0(element)) {
            String elementName = getElementName(element);
            Assert.hasText(elementName, "Element has no name");
            return elementName.endsWith(getResponseSuffix())
                    || (getRequestSuffix().isEmpty() ? true : elementName.endsWith(getRequestSuffix()))
                    || elementName.endsWith(getFaultSuffix());
        }
        return false;
    }

    protected boolean isMessageElement0(Element element) {
        return "element".equals(element.getLocalName())
                && "http://www.w3.org/2001/XMLSchema".equals(element.getNamespaceURI());
    }
}

 

public class MySuffixBasedPortTypesProvider extends SuffixBasedPortTypesProvider {

    private String requestSuffix = DEFAULT_REQUEST_SUFFIX;

    public String getRequestSuffix() {
        return requestSuffix;
    }

    public void setRequestSuffix(String requestSuffix) {
        this.requestSuffix = requestSuffix;
    }

    @Override
    protected String getOperationName(Message message) {
        String messageName = getMessageName(message);
        String result = null;
        if (messageName != null) {
            if (messageName.endsWith(getResponseSuffix())) {
                result = messageName.substring(0, messageName.length() - getResponseSuffix().length());
            } else if (messageName.endsWith(getFaultSuffix())) {
                result = messageName.substring(0, messageName.length() - getFaultSuffix().length());
            } else if (messageName.endsWith(getRequestSuffix())) {
                result = messageName.substring(0, messageName.length() - getRequestSuffix().length());
            }
        }
        return result;
    }

    @Override
    protected boolean isInputMessage(Message message) {
        String messageName = getMessageName(message);

        return messageName != null && !messageName.endsWith(getResponseSuffix());
    }

    private String getMessageName(Message message) {
        return message.getQName().getLocalPart();
    }

}

 在配置类WebServiceConfig中添加配置:

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

	@Bean(name = "sso")
	public Wsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) {
		//DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
		MyWsdl11Definition wsdl11Definition = new MyWsdl11Definition();
		wsdl11Definition.setPortTypeName("SSOWebServiceSoap");
		wsdl11Definition.setLocationUri("/ws");
		wsdl11Definition.setRequestSuffix("");
		wsdl11Definition.setTargetNamespace("http://tempuri.org/");
		wsdl11Definition.setSchema(countriesSchema);
		wsdl11Definition.setCreateSoap11Binding(true);
		wsdl11Definition.setCreateSoap12Binding(true);
		Properties soapActions = new Properties();
		soapActions.setProperty("ApplicationRegister", "http://tempuri.org/ApplicationRegister");
		soapActions.setProperty("LoginVerify", "http://tempuri.org/LoginVerify");
		wsdl11Definition.setSoapActions(soapActions);
		return wsdl11Definition;
	}

	@Bean
	public XsdSchema countriesSchema() {
		return new SimpleXsdSchema(new ClassPathResource("sso.xsd"));
	}

	@Override
	public void addInterceptors(List<EndpointInterceptor> interceptors) {
		interceptors.add(new CustomEndpointInterceptor());
	}
}

3.  将名称空间前缀更改SOAP-ENVsoap:

   添加CustomEndpointInterceptor

public class CustomEndpointInterceptor extends EndpointInterceptorAdapter {
    private static final String DEFAULT_NS = "xmlns:SOAP-ENV";
    private static final String SOAP_ENV_NAMESPACE = "http://schemas.xmlsoap.org/soap/envelope/";
    private static final String PREFERRED_PREFIX = "soap";
    private static final String HEADER_LOCAL_NAME = "Header";
    private static final String BODY_LOCAL_NAME = "Body";
    private static final String FAULT_LOCAL_NAME = "Fault";

    @Override
    public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
        SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse();
        alterSoapEnvelope(soapResponse);
        return super.handleResponse(messageContext, endpoint);
    }

    @Override
    public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
        SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse();
        alterSoapEnvelope(soapResponse);
        return super.handleFault(messageContext, endpoint);
    }

    private void alterSoapEnvelope(SaajSoapMessage soapResponse) {
        try {
            SOAPMessage soapMessage = soapResponse.getSaajMessage();
            SOAPPart soapPart = soapMessage.getSOAPPart();
            SOAPEnvelope envelope = soapPart.getEnvelope();
            SOAPHeader header = soapMessage.getSOAPHeader();
            SOAPBody body = soapMessage.getSOAPBody();
            SOAPFault fault = body.getFault();
            envelope.removeNamespaceDeclaration(envelope.getPrefix());
            envelope.addNamespaceDeclaration(PREFERRED_PREFIX, SOAP_ENV_NAMESPACE);
            envelope.setPrefix(PREFERRED_PREFIX);
            header.setPrefix(PREFERRED_PREFIX);
            body.setPrefix(PREFERRED_PREFIX);
            if (fault != null) {
                fault.setPrefix(PREFERRED_PREFIX);
            }
            Iterator<SOAPBodyElement> it = body.getChildElements();
            while (it.hasNext()) {
                SOAPBodyElement node = it.next();
                node.setPrefix("");
                Iterator<SOAPBodyElement> it2 = node.getChildElements();
                while (it2.hasNext()) {
                    SOAPBodyElement node2 = it2.next();
                    node2.setPrefix("");
                }
            }
            soapMessage.saveChanges();
        } catch (SOAPException e) {
            e.printStackTrace();
        }
    }
}

 在WebServiceConfig中添加该拦截器:

@Override
	public void addInterceptors(List<EndpointInterceptor> interceptors) {
		interceptors.add(new CustomEndpointInterceptor());
	}

 

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
根据提供的引用内容,可以看出这是一个关于使用Spring Boot创建基于WSDLWebService的示例代码。在这个示例中,通过访问"http://localhost:8080/webservice/api?wsdl"来创建一个客户端,并调用getUser方法来获取用户信息。同时,还提供了WebServiceServer接口的定义,其中包含了invoke方法的参数定义。另外,还提供了MonthPlanWS接口的定义,其中包含了getMonthPlan方法的参数定义。这些接口定义了WebService的操作和参数。 #### 引用[.reference_title] - *1* [SpringBoot集成webservice](https://blog.csdn.net/qq_42582773/article/details/127917067)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [SpringBoot项目添加WebService服务](https://blog.csdn.net/weixin_43493089/article/details/125523527)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [springboot集成webservice](https://blog.csdn.net/bbj12345678/article/details/130217670)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值