Create webservice service in spring boot

Recently, due to business needs, Party A asked me to provide a web service interface in the project, and then he pushed the data. Then I said to the technology of Party A, you can directly access our interface through http post, and then he innocently said to me in a dull tone, what post interface? Aren't all interfaces webservice? Besides, isn't web service used as the access interface in sap? You can't do it directly. I didn't come to this new company for a long time. Because of the business relationship, I haven't been in contact with SAP related things before. I don't know what sap is. Later, baidu checked it. Shit, it looks like a good cow. It costs more than 100000. I think more than 100000 products can't even post requests. Forget it. If you say you use web service, use web service. Party A is the father.

Then, in the process of creating web service, I encountered many pits and lay many thunder. In order to avoid everyone picking pits, I'll sort it out as follows.

The first is the spring boot POM XML file, which mainly introduces the following dependencies

<dependency>
	        <groupId>javax.xml.bind</groupId>
	        <artifactId>jaxb-api</artifactId>
	        <version>2.3.0</version>
	    </dependency>
	    <dependency>
	        <groupId>com.sun.xml.bind</groupId>
	        <artifactId>jaxb-impl</artifactId>
	        <version>2.3.0</version>
	    </dependency>
	    <dependency>
	        <groupId>com.sun.xml.bind</groupId>
	        <artifactId>jaxb-core</artifactId>
	        <version>2.3.0</version>
	    </dependency>
	    <dependency>
	        <groupId>javax.activation</groupId>
	        <artifactId>activation</artifactId>
	        <version>1.1.1</version>
	    </dependency>
<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web-services</artifactId>
		</dependency>

		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
			<version>3.3.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-transports-http</artifactId>
			<version>3.2.2</version>
		</dependency>
        <dependency>
			<groupId>org.codehaus.woodstox</groupId>
			<artifactId>stax2-api</artifactId>
			<version>4.0.0</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.woodstox</groupId>
			<artifactId>woodstox-core-asl</artifactId>
			<version>4.4.1</version>
		</dependency>
        <!-- This is mainly client Yes, but there are many problems-->
		<dependency>
			<groupId>org.apache.axis</groupId>
			<artifactId>axis</artifactId>
			<version>1.4</version>
		</dependency>

		<dependency>
			<groupId>axis</groupId>
			<artifactId>axis-jaxrpc</artifactId>
			<version>1.4</version>
		</dependency>

		<dependency>
			<groupId>commons-discovery</groupId>
			<artifactId>commons-discovery</artifactId>
			<version>0.2</version>
		</dependency>
		<dependency>
			<groupId>wsdl4j</groupId>
			<artifactId>wsdl4j</artifactId>
			<version>1.6.3</version>
		</dependency>

My JDK environment is jdk11, so I want to introduce the first four dependencies.

In addition, the version of springboot can't be too high. My original version was 2.3.3 and couldn't run. Later, I found the problem caused by incompatible versions on the Internet, so I reduced the version of springboot to 2.0.1 and ran later.

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
         <version>2.0.1.RELEASE</version>
         <!--<version>2.3.3.RELEASE</version>-->
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

Then, create a new interface file for webservice, as shown below:

package com.mango.jkm.webservice;

import java.util.List;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

@WebService(name = "Wbceshijk", targetNamespace = "http://server.webservice.example.com")
public interface Wbceshijk {
	@WebMethod
    String emrService(@WebParam(name = "data") String data,@WebParam(name = "data2") String data2);
	@WebMethod
	String student1111(@WebParam(name = "data") String data,@WebParam(name = "data2") String data2);
	@WebMethod
	String aboutstudent(@WebParam(name="student") Student student);
	@WebMethod
	String studentlist(List<Student> list1);
}

Then is the implementation class of the interface

package com.mango.jkm.webservice;

import java.util.List;

import javax.jws.WebParam;
import javax.jws.WebService;

import org.springframework.stereotype.Component;

@Component
@WebService( targetNamespace = "http://server.webservice.example.com",
        endpointInterface = "com.mango.jkm.webservice.Wbceshijk")
public class Webserviceceshi implements Wbceshijk{

	@Override
    public String emrService( String data,String data2) {
        if(null == data || "".equals(data.trim())){
            return "The passed in parameter is null";
        }
        return "data="+data+"@data2="+data2;
    }

	@Override
	public String student1111(String data, String data2) {
		// Method stub automatically generated by TODO
		return "22222data="+data+"@data2="+data2;
	}

	@Override
	public String aboutstudent(Student student) {
		// Method stub automatically generated by TODO
		System.out.println(student==null);
		return "student.getName()="+student.getName();
	}

	@Override
	public String studentlist(List<Student> list1) {
		// Method stub automatically generated by TODO
		return "list1.size()="+list1.size();
	}


}

Then there is the configuration of web service

package com.mango.jkm.webservice;

import javax.xml.ws.Endpoint;

import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class WebServiceConfig {

    @Autowired
    private Wbceshijk serverServiceDemo;

    /**
     * Apache CXF The core architecture takes BUS as the core and integrates other components.
     * Bus It is the backbone of CXF and provides a configurable place for shared resources. Its function is similar to Spring's ApplicationContext. These shared resources include
     * WSDl Manager, binding factory, etc. By expanding the bus, you can easily accommodate your own resources or replace existing resources. The default bus implementation is based on the Spring architecture,
     * Through dependency injection, components are concatenated at run time. BusFactory is responsible for the creation of Bus. The default BusFactory is spring BusFactory, which corresponds to the default
     * Bus implementation of. During construction, spring bus factory will search all bean configuration files under META-INF/cxf (included in the jar of CXF).
     * Build an ApplicationContext based on these configuration files. Developers can also provide their own configuration files to customize the Bus.
     */
    @Bean(name = Bus.DEFAULT_BUS_ID)
    public SpringBus springBus() {
        return new SpringBus();
    }

    /**
     * This method is used to change the prefix name of the service name in the project. If 127.0.0.1 or localhost cannot be accessed here, please use ipconfig to view the local ip to access
     * After this method is annotated, the prefix name (services by default) will not be changed, and the WSDL access address is http://127.0.0.1:8080/services/ws/api?wsdl
     * After removing the annotation, the WSDL access address is: http://127.0.0.1:8080/soap/ws/api?wsdl
     * http://127.0.0.1:8080/soap/List services or http://127.0.0.1:8080/soap/ws/api?wsdl View actual services
     * When creating a new Servlet, remember to add comments in the startup class: @ ServletComponentScan
     *
     * If an error occurs during startup: not loaded because dispatcherservlet registration found non dispatcherservlet
     * Spring boot may be incompatible with cfx version.
     * At the same time, in spring boot2 The version after 0.6 is integrated with xcf. It is not necessary to define the following methods, but directly in application Add in the properties configuration file:
     * cxf.path=/service((services by default)
     */
//    @Bean
//    public ServletRegistrationBean dispatcherServlet() {
//        return new ServletRegistrationBean(new CXFServlet(), "/soap/*");
//    }

    @Bean
    public Endpoint endpoint() {
        EndpointImpl endpoint = new EndpointImpl(springBus(), serverServiceDemo);
        endpoint.publish("/ws/api");
        return endpoint;
    }
}

Then I was in application Configuration information is added to the YML file (unnecessary)

cxf:
  path: /service

This is the Student class

package com.mango.jkm.webservice;

import java.io.Serializable;

import javax.xml.bind.annotation.XmlAccessType;

import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name="Student")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder={"name", "address","age"})
public class Student implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 3428504463675931746L;
	public String name;
	public String address;
	public String age;
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getAge() {
		return age;
	}

	public void setAge(String age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return  "#" + this.name + "#";
	}
}

Then, start springboot and access the corresponding address http://localhost:8081/service/ws/api?wsdl After getting the familiar interface, you can see that the web service is also started successfully (the port number of the web service is the port number of the spring boot project itself)

Then, you can access it with the soupui tool,

 

Click ok to see the four methods defined in the interface file

Click request1 of the emrService node to test, and you can see the returned data results

 

I feel that webservice is also a post interface, because I use the apipost tool to test. I put the xml of the request on the left in the body and get exactly the same result. In order to verify my guess, I sent a post request with the RestTemplate class of springboot, and found that I also got the return content on the right. This is my test class

package com.mango.jkm.webservice;

import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.encoding.XMLType;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.ser.BeanDeserializerFactory;
import org.apache.axis.encoding.ser.BeanSerializerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSONObject;


public class WbClient {
	public static void invokeService3() {
		  try {
	            //1. Direct reference to remote wsdl files  
	            String endpoint = "http://localhost:8081/service/ws/api?wsdl";  
	            Service service = new Service();
	            Call call = (Call) service.createCall(); //Create service
	            call.setTargetEndpointAddress(endpoint);  
	            //2. Define enrollment and interface methods
	            QName qn=new QName("http://server. webservice. example. Com ", / / targetNamespace in WSDL file
	                    "aboutstudent");
	            call.setOperationName(qn);

	            //3. Set parameters
	        
	        
	            Student student=new Student();
	            student.setName("Zhang Xiaoxin");
	            student.setAddress("sssss");
	            student.setAge("10");
	            call.registerTypeMapping(Student.class,qn,  
                        new BeanSerializerFactory(Student.class, qn),  
                        new BeanDeserializerFactory(Student.class, qn));  
	            call.addParameter("student",
	            		new QName("http://server.webservice.example.com", "Student"), javax.xml.rpc.ParameterMode.IN);
//	            call.addParameter("student", org.apache.axis.encoding.XMLType.XSD_ANYTYPE,
//                        javax.xml.rpc.ParameterMode.IN);// Interface parameters
	            call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);//Set return type  

	            call.setUseSOAPAction(true);
	            String result = (String)call.invoke(new Object[]{student});
	            System.out.println("result="+result); 
	           
	           
	        } catch (Exception e) {  
	            e.printStackTrace();
	        }
		
	}
	public static void invokeService_2(){

		  try {
	            //1. Direct reference to remote wsdl files  
	            String endpoint = "http://localhost:8081/service/ws/api?wsdl";  
	            Service service = new Service();
	            Call call = (Call) service.createCall(); //Create service
	            call.setTargetEndpointAddress(endpoint);  
	            //2. Define enrollment and interface methods
	            call.setOperationName(new QName("http://server. webservice. example. Com ", / / targetNamespace in WSDL file
	                    "emrService") //Method of realizing function of interface
	                    );
	            
	            //3. Set parameters
	            call.addParameter("data", XMLType.XSD_STRING,ParameterMode.IN);// Interface parameters  
	            call.addParameter("data2",XMLType.XSD_STRING,ParameterMode.IN);// Interface parameters  
	            call.setReturnType(XMLType.XSD_STRING);// Set return type  
	           
	          
	            
	            //4. Pass parameters to the method and call the method
	            String result = (String) call.invoke(new Object[] {"1111" ,"2222"});  
	            System.out.println("result="+result);
	        } catch (Exception e) {  
	            e.printStackTrace();
	        }

//		
	}
	public static void restfangwen() {
		RestTemplate restTemplate = new RestTemplate();
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_XML);
		String xml="<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"http://server.webservice.example.com\">\r\n"
				+ "   <soapenv:Header/>\r\n"
				+ "   <soapenv:Body>\r\n"
				+ "      <ser:aboutstudent>\r\n"
				+ "         <!--Optional:-->\r\n"
				+ "         <student>\r\n"
				+ "            <!--Optional:-->\r\n"
				+ "            <name>zx</name>\r\n"
				+ "            <!--Optional:-->\r\n"
				+ "            <address>address</address>\r\n"
				+ "            <!--Optional:-->\r\n"
				+ "            <age>18</age>\r\n"
				+ "         </student>\r\n"
				+ "      </ser:aboutstudent>\r\n"
				+ "   </soapenv:Body>\r\n"
				+ "</soapenv:Envelope>";
		HttpEntity requestEntity = new HttpEntity<>(xml, headers);
		ResponseEntity<String> resEntity = restTemplate.postForEntity("http://localhost:8081/service/ws/api",
				requestEntity, String.class);
		String result=resEntity.getBody();
		
		System.out.println("str="+result);
	}
	public static void main(String[] args) {
		WbClient.restfangwen();
	}
}

In this test class, I access the aboutstudent method in webservice to get the corresponding returned content

str=<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:aboutstudentResponse xmlns:ns2="http://server.webservice.example.com"><return>student.getName()=zx</return></ns2:aboutstudentResponse></soap:Body></soap:Envelope>

axis can access the emrService method and return the correct data. If the input parameter is not a java basic type but a class, it will be difficult to make it work. All methods on the Internet are difficult to make it work. I don't know why. Dear gods, if you succeed, please say it in the message area. I'm very grateful.

Keywords: Spring Boot webservice

Added by otterbield on Sat, 12 Feb 2022 06:12:10 +0200