WebService---跨平台跨语言的远程调用技术

时间:2020-07-11
本文章向大家介绍WebService---跨平台跨语言的远程调用技术,主要包括WebService---跨平台跨语言的远程调用技术使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

                                WebService---跨平台跨语言的远程调用技术


一、webservice和dubbo两者的区别

0)两者都是远程调用技术,Dubbo不跨语言,不跨平台;WebService是跨平台和跨语言的
1)Dubbo推荐使用dubbo协议(快但不通用),WebService推荐使用HTTP协议(慢但通用)
2)Dubbo主要用在一个系统内部的服务间远程调用,WebService主要应用在两个不同系统服务整合。

服务端和客户端之间对象传输的方法: 对于dubbo协议,是把对象序列化成二进制字节传输

                    对于http协议,是把对象转换成json格式或者xml格式传输

扩展:

①Soap协议是基于http的应用层协议,soap协议传输是xml数据。而xml是webservice的跨平台的基础
②JAVA 中共有三种WebService 规范,分别JAX-WS、JAX-RS、JAXM&SAAJ(废弃)。
webservice规范JAX-WS,客户端与服务端通讯: soap协议 = http+ xml
webservice规范JAX-RS(RESTful webservice的开发),客户端与服务端通讯: http协议 + XML/JSON (json是由于restful)
③webservice的应用场景: 可以用于两家公司系统(也可以称为服务方和客户方)的对接和整合,异构系统整合


二、使用

CXF 是一个开源的 webServices 框架,故一般都是通过CXF来时用webService。

Cxf是基于SOA总线结构,依靠spring完成模块的集成

cxf框架的最终访问路径:= http://IP地址:端口/web.xml/cxf.xml的address/接口Path/方法Path       (spring整合了CXF的访问地址)

使用步骤:(是使用了Jax-RS规范的CXF框架

首先我们要知道这是远程调用,所以要有服务端和客户端

在服务端和客户端都得导入依赖。

  1. 服务端,要有实体类,接口,实现类
  2. 客户端 只要有实体类就行,和测试类

①。单独的CXF框架的使用如下:

在服务端-------------------------------------------------------服务端-------------------------------------------------------

1.添加依赖

  <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>3.0.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http-jetty</artifactId>
            <version>3.0.1</version>
        </dependency>


        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-client</artifactId>
            <version>3.0.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-extension-providers</artifactId>
            <version>3.0.1</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.12</version>
        </dependency>

        <!--json转换-->
        <dependency>
            <groupId>org.codehaus.jettison</groupId>
            <artifactId>jettison</artifactId>
            <version>1.3.7</version>
        </dependency>

2.引入实体类,且必须得在实体类上加注解@XmlRootElement(name = "类名") // 该注解是用于CXF在传递Java对象的时候转换格式(XML/JSON)必须的注解

@XmlRootElement(name = "User") // 该注解是用于CXF在传递Java对象的时候转换格式(XML/JSON)必须的注解
public class User{
	private Integer id;
	private String username;
	private String city;

  

3.引入service层的接口和实现


在客户端----------------------------------客户端------------------------

1.添加依赖,同上

2.编写实体类

3.测试类,用WebClient.自带的静态方法 

package cn.itcast.client;

import cn.itcast.domain.User;
import org.apache.cxf.jaxrs.client.WebClient;
import org.junit.Test;

import java.util.List;

/**
 * 客户端调用代码
 */
public class Client {

    /**
     * WebClient方法解释:
     *    create(): 服务端的方法访问路径   
     *    type(): 客户端传输给服务端的数据类型: application/xml或application/json
     			--指的是请求的参数,或者服务端方法的参数
     *    accept(): 客户端接收服务端的数据类型: application/xml或application/json
     			--指的是服务端方法的返回数据的传输格式
     		上面都要与服务端的@Consumes("application/xml")
							@Produces({ "application/xml","application/json")一致,或者包含于其内
     *    post(): 发出post请求
     *    put(): 发出put请求
     *    delete(): 发出delete请求
     *    getCollection(Class): 发出get请求,获取响应数据(服务器方法返回数据),接收集合类型,转换为指定对象类型
     *    get(Class): 发出get请求,获取响应数据,接收一个JavaBean类型,转换为指定对象类型
     */

    /**
     * 添加方法
     */
    @Test
    public void testSaveUser(){
        User user = new User();
        user.setUsername("张三");

        WebClient.create("http://127.0.0.1:8888/userService/user")
                .type("application/xml")
                .post(user);

    }

    /**
     * 修改方法
     */
    @Test
    public void testUpdateUser(){
        User user = new User();
        user.setId(1);
        user.setUsername("李四");

        WebClient.create("http://127.0.0.1:8888/userService/user")
                .type("application/xml")
                .put(user);

    }

    /**
     * 查询所有数据
     */
    @Test
    public void testFindAllUsers(){
        List<User> list =  (List<User>)WebClient.create("http://127.0.0.1:8888/userService/user")
                .accept("application/json")
                .getCollection(User.class);
        for (User user:list){
            System.out.println(user);
        }

    }

    /**
     * 查询一个
     */
    @Test
    public void testFinUserById(){
        User user = WebClient
                .create("http://127.0.0.1:8888/userService/user/1")
                .accept("application/xml")
                .get(User.class);
        System.out.println(user);
    }

    /**
     * 删除
     */
    @Test
    public void testDeleteUser(){
        WebClient
                .create("http://127.0.0.1:8888/userService/user/1")
                .delete();
    }
}




②。以上是单独的CXF框架的使用,但是我们一般是整合了spring依赖来使用的 

1.创建一个新的springcxf_server项目

2.添加依赖

<dependencies>
    <!-- cxf 进行rs开发 必须导入  -->
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
      <version>3.0.1</version>
    </dependency>
    <!-- 日志引入  -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.12</version>
    </dependency>

    <!-- 客户端 -->
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-rs-client</artifactId>
      <version>3.0.1</version>
    </dependency>

    <!-- 扩展json提供者 -->
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-rs-extension-providers</artifactId>
      <version>3.0.1</version>
    </dependency>

    <!-- 转换json工具包,被extension providers 依赖 -->
    <dependency>
      <groupId>org.codehaus.jettison</groupId>
      <artifactId>jettison</artifactId>
      <version>1.3.7</version>
    </dependency>

    <!-- spring 核心 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <!-- spring web集成 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <!-- spring 整合junit  -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <!-- junit 开发包 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
  </dependencies>

3.实现类,服务接口及其实现 

 4.配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	version="2.5">

	
	<!--监听器读取cxf配置-->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext-cxf.xml</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	
	<!--启动CXF-->
	<!--
	   /ws/*: 接收带有ws前缀的路径
	-->
	<servlet>
		<servlet-name>cxfServlet</servlet-name>
		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
		<load-on-startup>1</load-on-startup>  //让其项目启动,发布服务
	</servlet>
	<servlet-mapping>
		<servlet-name>cxfServlet</servlet-name>
		<url-pattern>/ws/*</url-pattern>
	</servlet-mapping>
	
</web-app>

5.配置applicationContext-cxf.xml

<?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:jaxrs="http://cxf.apache.org/jaxrs"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
    <!-- 原来的约束名称jaxrs-common.xsd,改为 jaxrs.xsd -->
<!-- 一个Bug-->

    <!--配置要发布哪些服务
      最终访问地址 = http://IP地址:端口/web.xml/cxf.xml的address/接口Path/方法Path
      serviceClass: 服务的实现类
    -->
    <jaxrs:server address="/user" serviceClass="cn.itcast.service.UserServiceImpl">
        <jaxrs:inInterceptors>
            <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
        </jaxrs:inInterceptors>
        <jaxrs:outInterceptors>
            <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
        </jaxrs:outInterceptors>
    </jaxrs:server>




</beans>

6.测试

上面定还是服务端,我们还是使用上面写的客户端来测试  

 package cn.itcast.client;

import cn.itcast.domain.User;
import org.apache.cxf.jaxrs.client.WebClient;
import org.junit.Test;

import java.util.List;

/**
 * 演示CXF客户端代码(调用Spring版本)
 */
public class ClientDemo_Spring {

    /**
     *
     * WebClient: 发送任何类型的请求,传递参数等行为
     *   create(): 定义请求路径
     *   post(): 发出一个post请求
     *   type(): 定义客户端传递的数据格式
     *   getCollection(): 发送GET请求,并把响应内容转换为List集合
     *   get(): 发送GET请求,并把响应内容转换一个对象
     */

    /**
     * 调用服务save方法
     */
    @Test
    public void testSave(){

    User user = new User();
        user.setId(1);
        user.setUsername("eric");

        /*WebClient.create("http://localhost:8888/userService")
                .type("application/xml")
                .post(user);*/

        WebClient.create("http://localhost:8082/ws/userService")
                .type("application/json")
                .post(user);
    }

    /**
     * 调用服务update方法
     */
    @Test
    public void testUpdate(){

        User user = new User();
        user.setId(1);
        user.setUsername("jack");

        WebClient.create("http://localhost:8082/ws/userService")
                .type("application/xml")
                .put(user);
    }

    /**
     * 调用服务delete方法
     */
    @Test
    public void testDelete(){

        WebClient.create("http://localhost:8082/ws/userService/10")
                .delete();
    }

    /**
     * 调用服务findAll方法
     */
    @Test
    public void testFindAll(){

       List<User> userList =  (List<User>)WebClient.create("http://localhost:8082/ws/userService")
                .accept("application/xml")
                .getCollection(User.class);

       for(User user:userList){
           System.out.println(user);
       }
    }

    /**
     * 调用服务findById方法
     */
    @Test
    public void testFindById(){

        User user = WebClient.create("http://localhost:8082/ws/userService/1")
                .get(User.class);
        System.out.println(user);
    }
}

  

原文地址:https://www.cnblogs.com/lanto/p/13285102.html