java 调用webservice_Java实现远程服务生产与消费(RPC)的4种方法

本文将通过具体的远程服务发布与消费案例展示4种RPC远程调用方法.

一. 通过rmi实现远程服务的生产与消费

  • Java自身提供了java.rmi包, 方便开发者进行远程服务的部署与消费, 下面将通过具体案例进行讲解.

远程服务提供者实现.

创建rmi-provider项目(Maven)

  1. 创建UserService接口.
//将要发布的服务的接口public interface UserService extends Remote { public String helloRmi(String name) throws RemoteException;}
  1. 创建UserServiceImpl实现类
  • 注意, UserServiceImpl除了实现UserService接口外, 还要继承UnicastRemoteObject类, 你可以理解为它是一个发布出去供他人调用的类, 当UserServiceImpl实现了这个类后, UserServiceImpl就能被发布出去供别人调用.
//将要发布的服务的实现类public class UserServiceImpl extends UnicastRemoteObject implements UserService { public UserServiceImpl() throws RemoteException { super(); } public String helloRmi(String name) throws RemoteException { return "hello " + name; }}
  1. 发布远程服务
public static void main(String[] args) { try { //完成远程服务的发布 LocateRegistry.createRegistry(8888);//将远程服务发布在本地的8888端口 String name = "rmi://localhost:8888/rmi";//发布的远程服务被访问的url UserService userService = new UserServiceImpl();//创建一个提供具体服务的远程对象 Naming.bind(name, userService);//给远程服务绑定一个url System.out.println("--- 已发布rmi远程服务 ---"); } catch (Exception e) { e.printStackTrace(); }}

远程服务消费者实现

创建rmi-consumer项目

  1. 把rmi-provider项目种的UserService接口与UserServiceImpl实现类复制到本rmi-consumer项目中.(这一步可以进行优化解耦, 我们可以多创建一个rmi-resource项目, 让rmi-provider和rmi-consumer共同依赖rmi-resource项目, 然后把资源文件比如远程服务所用到的UserService等放入rmi-resource项目中)
  2. 远程服务消费者对远程服务发起调用.
public static void main(String[] args) { try { //发布远程服务的访问url String name = "rmi://localhost:8888/rmi"; //通过发布远程服务的url, 获取远程服务的代理对象 UserService userService = (UserService) Naming.lookup(name); System.out.println("获得的远程服务的代理对象:" + userService.getClass().getName()); String result = userService.helloRmi("rmi");//拿到远程方法调用的结果 System.out.println("result: " + result); }catch (Exception e) { e.printStackTrace(); }}//最后输出获得的远程服务的代理对象:com.sun.proxy.$Proxy0result: hello rmi
  • 通过最后的输出我们看到获得的远程服务对象是动态代理产生的.

二. 通过WebService实现远程服务的生产与消费

  • WebService协议是RPC的一种具体实现, 服务提供方和消费方通过http + xml进行通信.

远程服务提供者实现.

  1. 首先创建远程服务接口UserService及其实现类UserServiceImpl.
  • 注意, 使用WebService时需要对远程服务加上注解@WebService
@WebServicepublic interface UserService { public String sayHello(String name);}@WebServicepublic class UserServiceImpl implements UserService { @Override public String sayHello(String name) { return "hello " + name + "~"; }}
  1. 发布远程服务, 过程和rmi差不多, 需要提供远程服务的访问地址和具体的远程服务实现类, 使用Endpoint类的publish()方法进行发布, 这都是JDK封装好的.
public class WsProviderApp { public static void main(String[] args) { //发布的WebService的被访问地址 String address = "http://localhost:9999/ws"; //创建远程服务对象 UserService userService = new UserServiceImpl(); //发布服务 Endpoint.publish(address, userService); System.out.println("远程服务已经发布..."); }}

查看远程服务文档wdsl

  • 和rmi不同的是, WebService发布后, 调用者可以通过查看它的文档对远程服务发起调用.
  • 查看的方法是在浏览器中输入远程服务的访问地址加上?wdsl, 比如本案例中是http://localhost:9999/ws?wsdl
  • 注意, 在客户端调用远程方法时需要用工具对wdsl文档进行解析, 并获得调用远程方法的工具类. 具体操作见下一段.

远程服务消费者实现.

  1. 首先根据文档获得调用远程服务的工具类, JDK已经为我们封装好了获取的工具, 它在bin目录下, 名字是wsimport
  2. 打开命令行, 在命令行中输入解析命令
wsimport -keep -d C:githubRepositoriesshoppingws-consumersrcmainjava -p com.shenghao.client http://localhost:9999/ws?wsdl解释:1. wsimport 是命令的名字2. -keep 用于保留生成的类, 如果没有该指令会只生成class文件3. -d 后面接项目中存放这些工具类的包, 填绝对路径4. -p 填wdsl文档的地址
890212911f5744ab1b1012bdd174d9cc.png
53ba5bcc0abece10f5d70e6a3e118bc5.png
  1. 可以看到命令执行完后, 指定的包中出现一堆相关的类, 最直接调用到的类是UserServiceImplService. 下面演示对远程方法进行调用.
public static void main(String[] args) { //创建服务类对象 UserServiceImplService service = new UserServiceImplService(); //获得远程服务的代理对象 UserServiceImpl userService = service.getUserServiceImplPort(); System.out.println(userService.getClass().getName()); //对远程服务对象的方法进行调用 String result = userService.sayHello("炭烧生蚝"); System.out.println(result);}//结果输出com.sun.proxy.$Proxy32hello 炭烧生蚝~

三. 通过HttpClient实现远程服务的生产与消费

  • 这里我们换一个案例进行演示. 假设现在有一套用户系统和一套订单系统, 要实现用户系统访问订单系统以获得某个用户的订单信息.

远程服务提供者实现

  • 提供远程服务的过程和响应web请求很相似, 只不过响应的不是标签, 而是json字符串. 微信小程序前后端通信也是这个原理.
  1. 创建名为order-sys的Maven项目, 指定打包为war包.

点击这里查看pom.xml文件, 常规操作

  1. 创建订单类
public class Order { private String id; private Double total; private String date; //get / set ...}
  1. 对外提供服务, 发布时打包发布到Tomcat上
@Controllerpublic class OrderController { /** * 接收http请求, 响应订单集合, 异步响应 * 将list集合序列化为json串响应 * @param uid * @return */ @RequestMapping("/loadOrderList2") @ResponseBody public List loadOrderList2(String uid){ System.out.println("uid: " + uid); //模拟订单数据 Order o1 = new Order(); o1.setId("111"); o1.setTotal(333.33); o1.setDate("2019-4-29"); Order o2 = new Order(); o2.setId("222"); o2.setTotal(444.44); o2.setDate("2019-5-29"); Order o3 = new Order(); o3.setId("333"); o3.setTotal(555.55); o3.setDate("2019-6-29"); List list = new ArrayList<>(); list.add(o1); list.add(o2); list.add(o3); return list; }}

远程服务消费者实现

  1. 在服务消费端使用HttpClient发送请求, 可以理解为模拟浏览器发送post/get请求. HttpClient为我们封装了拼接一个请求的细节, 使得发送一个请求变得容易.
public static void main(String[] args) throws IOException { //发送远程的http请求的地址 String url = "http://localhost:7070/order/loadOrderList2"; //创建HttpClient对象 CloseableHttpClient client = HttpClients.createDefault(); //创建HttpPost对象, 发送post请求 HttpPost method = new HttpPost(url); //封装发送到服务提供者的参数 NameValuePair id = new BasicNameValuePair("uid
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值