spring integrates cxf to easily write webService client and server

WebService is a kind of remote calling technology which is cross programming language and cross operating system platform. It is widely used in practical development, interface implementation and system integration.

Server side

  1. List item

Add maven dependency
In addition to the spring related dependencies in the project, you need to add the following two dependencies.

    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxws</artifactId>
      <version>3.3.5</version>
    </dependency>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-transports-http</artifactId>
      <version>3.3.5</version>
      <scope>compile</scope>
    </dependency>
  1. Configure web.xml

In addition to the general spring related configuration, the cxfServlet configuration needs to be added here.

<!--  1.cxfServlet To configure-->
  <servlet>
    <servlet-name>cXFServlet</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>cXFServlet</servlet-name>
    <url-pattern>/webservice/*</url-pattern>
  </servlet-mapping>
<!--  2.To configure spring container-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
<!--    3.Monitor-->
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  1. Write webService interface and implementation class
    IHelloService interface class
    Interface needs annotation @ webservice
@WebService
public interface IHelloService {

    /**
     *     How to publish service interface
     *      @param name
     */
    public String welcome(String name);
}

HelloServiceImpl interface implementation class

public class HelloServiceImpl implements IHelloService {
    @Override
    public String welcome(String name) {
        return "welcome to webService "+name;
    }
}

  1. Configure applicationContext.xml
    You need to add cxf related xsd in the namespace, and then configure the corresponding information of the service, including service address, service class, etc
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://cxf.apache.org/jaxws
        http://cxf.apache.org/schemas/jaxws.xsd">
    <cxf:server address="/hello">
        <jaxws:serviceBean>
            <bean class="service.impl.HelloServiceImpl"></bean>
        </jaxws:serviceBean>
    </cxf:server>
</beans>
  1. Start web service, test
    After the service is started successfully, we can access it in the browser: http://localhost:8081/webservice/hello?wsdl, where http://localhost:8081 is our server access portal, / webservice is the servlet mapping corresponding to the cxfServlet configured in the web.xml configuration file, / hello is the address of the service access, and finally we need to add the wsdl access wsdl specification.
    The following figure shows the display effect of ie browser, and the Firefox browser I tested is blank. The content of f12 corresponds to the content in the figure below.
    Client

  2. Add cxf related dependency

  3. Import the class corresponding to the service interface type
    Here, we need to add IHelloService and HelloServiceImpl of the server to the client code. In addition, whether it is the client or the server, the IHelloService interface needs to be annotated with @ webService annotation.

  4. Write applicationContext.xml of the client
    The server defines the interface service type and service address. Correspondingly, the client also needs to configure the service address and service interface type.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://cxf.apache.org/jaxws
        http://cxf.apache.org/schemas/jaxws.xsd"
    <jaxws:client id="helloService" serviceClass="service.impl.HelloServiceImpl" address="http://localhost:8081/webservice/hello"></jaxws:client>
</beans>
  1. Write unit tests
    Spring unit test is used here, so not only the dependency of junit, but also the dependency of spring test.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Client {

    //Injected object
    @Resource
    private HelloServiceImpl helloService;
    @Test
    public void doClientRemote(){
        System.out.println(helloService);
        String content = helloService.welcome("Elaine");
        System.out.println(content);
    }

}
  1. View output results
org.apache.cxf.jaxws.JaxWsClientProxy@45905bff
welcome to webService Elaine

It can be found that the HelloServiceImpl object we get is a proxy object. Because of the relevant interface in advance, it is naturally realized through jdk dynamic proxy.
When viewing the server output, there is a warning

org.apache.cxf.interceptor.Fault: Unexpected wrapper element {http://impl.service/}welcome found.   Expected {http://service/}welcome.

It's easy to understand that the type of proxy object we get in unit test is implementation class, cxf wants us to use interface type directly. Replaced by:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Client {

    //Injected object
    @Resource
    private IHelloService helloService;
    @Test
    public void doClientRemote(){
        System.out.println(helloService);
        String content = helloService.welcome("Elaine");
        System.out.println(content);
    }

}

Retest, no warning, no error.

96 original articles published, 13 praised, 20000 visitors+
Private letter follow

Tags: Apache Spring xml encoding

Posted on Sat, 14 Mar 2020 11:10:01 -0400 by WanamakerMedia