Example of JAVA publishing Webservice service and Webservice service invocation tool

Spring boot publishes Web Service Services

SpringBoot publishing Webservice is actually exposing JAVA Class classes as Webservice services through Webservice annotations.

Dependencies required for publishing services

// Dependencies required for web service publishing

Only these two dependencies are needed to publish web service. JDK uses 1.8. After dependency is introduced, start looking at the code!

Write service classes to be exposed

Before writing the code, you need to know about the use of web service related annotations [understand by yourself]. There is no explanation here. Go directly to the code!

import org.apache.cxf.annotations.WSDLDocumentation;
import org.apache.cxf.annotations.WSDLDocumentationCollection;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.Endpoint;

 * @Author: zp
 * @Description: TODO
 * @Date: 2021/6/24 14:17
 * @Version: 1.0
@SOAPBinding(style = SOAPBinding.Style.RPC)
//wsdl xml document description
@WSDLDocumentation(value = "This service is SpringBoot take JAVA Class Annotated as WebService service,Services can be consumed according to JSON and XML Different data formats for different service choices. This service is only used as an example of a service, and there is no specific implementation of the service.",
        placement = WSDLDocumentation.Placement.TOP)
public class EWebService {

            @WSDLDocumentation("RequestDataByJson receive json Format input for service consumption"),
            @WSDLDocumentation(value = "Participants must follow json Data format for service consumption",
                    placement = WSDLDocumentation.Placement.INPUT_MESSAGE),
            @WSDLDocumentation(value = "RequestDataByJson Service response content",
                    placement = WSDLDocumentation.Placement.OUTPUT_MESSAGE)
    public Object RequestDataByJson(@WebParam(name="jsonReqParam")String jsonReqParam){
        return RequestOther(jsonReqParam);

            @WSDLDocumentation("RequestDataByXml receive xml Format input for service consumption"),
            @WSDLDocumentation(value = "Participants must follow xml Data format for service consumption",
                    placement = WSDLDocumentation.Placement.INPUT_MESSAGE),
            @WSDLDocumentation(value = "RequestDataByXml Service response content",
                    placement = WSDLDocumentation.Placement.OUTPUT_MESSAGE)
    public Object RequestDataByXml(@WebParam(name="xmlReqParam")String xmlReqParam){
        return  RequestOther(xmlReqParam);

    @WebMethod(exclude=true)//The current method is not published
    public Object RequestOther(String object){
//        Perform other service logic processing
//        SayHello sayHello = new SayHello();
//        sayHello.say("service call succeeded");
        return "RequestOther Service response succeeded! Input parameters are:"+object;

    public static void main(String[] args) {
        String url = "http://youIP:youPort/ESBWebservice";
        Endpoint publish = Endpoint.publish(url,new EWebService());
        if(publish.isPublished()) {
            System.out.println("=============server is running==============");
        }else {
            System.out.println("=============server is error================");

The Webservice service class is ready. Run the main method in this class directly to publish the Webservice service.

Publishing services

Run the main method in this class and pay attention to modifying your own ip and port. The effect after operation is shown in the figure:

Access in browser http://youIP:youPort/ESBWebservice?wsdl Check whether the service is published successfully! As shown in the figure:

Seeing such an interface means that the service is published successfully! Here is how to call the service.

General invocation of Webservice service

The general calling method is as follows:

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;

public static void main(String[] args) {
		try {
			String url ="http://youIP:youPort/ESBWebservice?wsdl";
			//Generate client instance
			JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
			Client client = dcf.createClient(url);
			//Service parameters
			String paramString = "Parameter content";
			//Automatic proxy initiation request
			Object[] obj = client.invoke("RequestDataByJson",paramString);
			System.out.println("The return value of the call is:"+obj[0]);
		} catch (Exception e) {

The call result is shown in the figure below:
The service responded successfully. However, this kind of calling method may cause some Webservice services to call normally on the SOAPUI, but various exceptions occur when using this method to access, resulting in the problem that the service call is impossible.

Frequently asked questions about Webservice service invocation

1,No operation was found with the name

2. Unmarshalling Error: unexpected element (uri: "return: HL7 org: V3", local: "return"). The required element is < {urn: HL7 org: V3} hipmessageserverresult >

3. The return value is an object and must be parsed

It is recommended to use the calling method of web service

This method combines the calling method in hutool with the wsdl parsing provided by jdk to encapsulate the calling method.

Call required dependencies

// Dependencies required for custom calls

Call tool class

import cn.hutool.http.webservice.SoapClient;
import com.ibm.wsdl.PortImpl;
import com.ibm.wsdl.extensions.soap.SOAPAddressImpl;
import com.ibm.wsdl.extensions.soap12.SOAP12AddressImpl;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import javax.wsdl.Definition;
import javax.wsdl.Service;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPMessage;
import java.io.ByteArrayInputStream;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
 * @Author: zp
 * @Description: webservice Service request tool
 * @Date: 2021/8/24 10:57
 * @Version: 1.0
public class WebserviceUtils {

	public static void main(String[] args) {
//		Map<String,Object> params = new HashMap<>();
//		params.put("theIpAddress","");
//		String url = "http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx?wsdl";
//		String methodName = "getCountryCityByIp";
//		System.out.println("the service response value is:" + requestwsdl (URL, methodname, parameters));

        Map<String,Object> params = new HashMap<>();
        params.put("jsonReqParam","Service parameters");
        String url = "http://youIP:youPort/ESBWebservice?wsdl";
        String methodName = "RequestDataByJson";
        System.out.println("The service response value is:"+requestWsdl(url,methodName,params));

	 * wsdl analysis
	 * @param url           wsdl address
	 * @param methodName    Requested method name
	 * @param parameter     Parameter value
	 * @return
	public static String requestWsdl(String url, String methodName, Map<String, Object> parameter) {
		try {
			WSDLFactory factory = WSDLFactory.newInstance();
			WSDLReader reader = factory.newWSDLReader();
			reader.setFeature("javax.wsdl.verbose", true);
			reader.setFeature("javax.wsdl.importDocuments", true);
			//Resolve wsdl address
			Definition def = reader.readWSDL(url);
			// Namespace to which the element belongs
			String namespaceURI = def.getTargetNamespace();
			String wsdlService = null;
			String soapVersion = SOAPConstants.SOAP_1_1_PROTOCOL;
			//Get the service and the binding name where the service is located according to the wsdl address and namespace
			Map<QName, Object> map1 = def.getServices();
			for (Map.Entry<QName, Object> vo : map1.entrySet()) {
				wsdlService = vo.getKey().getLocalPart();
			QName sname = new QName(namespaceURI, wsdlService);
			//Get the service information in the specified space
			Service service = def.getService(sname);
			Map<String, Object> ports = service.getPorts();
			Iterator<?> itor = ports.entrySet().iterator();
			while (itor.hasNext()) {
				Map.Entry<String, Object> map = (Map.Entry<String, Object>) itor.next();
				//If the wsdl address of the service is not consistent with the binding address of the service method name, you need to obtain the address where the service name is located
				PortImpl valueMap = (PortImpl) map.getValue();
				List extensList = valueMap.getExtensibilityElements();
				if (extensList != null) {
					for (int i = 0; i < extensList.size(); i++) {
						//Get the binding address of the service
						ExtensibilityElement extElement = (ExtensibilityElement) extensList.get(i);
						//After obtaining the locationURI, directly access the changed address for service consumption, and no longer use the wsdl address
						if (extElement instanceof SOAPAddressImpl) {
							SOAPAddressImpl soapAddress = (SOAPAddressImpl) extElement;
							url = soapAddress.getLocationURI();
							soapVersion = SOAPConstants.SOAP_1_1_PROTOCOL;
						if (extElement instanceof SOAP12AddressImpl) {
							SOAP12AddressImpl soapAddress = (SOAP12AddressImpl) extElement;
							url = soapAddress.getLocationURI();
							soapVersion = SOAPConstants.SOAP_1_2_PROTOCOL;
				//Avoid that some service providers provide a service in multiple ways and report errors. After obtaining it here, it will not be obtained again [e.g. weather query soap1.1 soap1.2 httpPost httpGet are provided]
			return  sendMessage(url, namespaceURI, methodName, parameter, soapVersion).trim();
		} catch (Exception e) {
			return  "Network error, please contact the administrator"+e.getMessage();

	 * <p>Title: sendMessage</p>
	 * <p>Description:Send a soap request to get the return value of the original service</p>
	 * @param wsdlUrl 		The service address or the binding address where the service is located
	 * @param namespaceURI  Namespace
	 * @param methodName    service name
	 * @param params  		Parameter map
	 * @param soapVersion   soap edition
	 * @return
	 * @throws Exception
	private static String sendMessage(String wsdlUrl, String namespaceURI,String methodName,Map<String, Object> params, String soapVersion) {
		String returnStr="";
		try {
			SoapClient client = SoapClient.create(wsdlUrl)
					// Set the method to be requested. The method prefix of this interface is web. Pass in the corresponding namespace
					// Set parameters, where the prefix of the method is automatically added:
			returnStr = client.send(true);
			if(StringUtils.isNotBlank(returnStr)) {
				// Different service definitions have different return information nodes and different namespaces, which makes it impossible to locate the value location -- "and convert it to the soap message body for value taking
				SOAPMessage soap = formatSoapString(returnStr,soapVersion);
				if(null!=soap) {
					try {
						Document doc = soap.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
						//Return information node in soapBody
						Node node = doc.getFirstChild();
						if(node != null) {
							returnStr = node.getTextContent().trim();
						}else {
							returnStr="Failed to get the return value";
					} catch (Exception e) {
						returnStr="Failed to get the return value";
			}else {
				returnStr =  "Failed to get value";
		} catch (Exception e1) {
			returnStr = "Service call failed!"+e1.getMessage();
		return returnStr;
	 * <p>Title: formatSoapString</p>
	 * <p>Description: Convert the string to the soapMessage body according to the message body string returned by soap and the soap version</p>
	 * @param soapString
	 * @param soapVersion
	 * @return
	public static SOAPMessage formatSoapString(String soapString,String soapVersion)
		MessageFactory msgFactory = null;
			if("SOAP 1.1 Protocol".equals(soapVersion)) {
				msgFactory = MessageFactory.newInstance();
			if("SOAP 1.2 Protocol".equals(soapVersion)) {
				msgFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
			SOAPMessage reqMsg = msgFactory.createMessage(new MimeHeaders(), new ByteArrayInputStream(soapString.getBytes(Charset.forName("UTF-8"))));
			return reqMsg;
		catch (Exception e)
			return null;

After verification, calling in this way can perfectly avoid these problems mentioned above!

Tags: Java webservice Spring Boot

Posted by simwiz on Sun, 19 Dec 2021 19:14:41 +1030