目录
本文将通过具体的远程服务发布与消费案例展示4种RPC远程调用方法.
UserService
接口.//将要发布的服务的接口
public interface UserService extends Remote {public String helloRmi(String name) throws RemoteException;
}
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;}
}
public static void main(String[] args) {try {//完成远程服务的发布ateRegistry(8888);//将远程服务发布在本地的8888端口String name = "rmi://localhost:8888/rmi";//发布的远程服务被访问的urlUserService userService = new UserServiceImpl();//创建一个提供具体服务的远程对象Naming.bind(name, userService);//给远程服务绑定一个urlSystem.out.println("--- 已发布rmi远程服务 ---");} catch (Exception e) {e.printStackTrace();}
}
rmi-provider
项目种的UserService
接口与UserServiceImpl
实现类复制到本rmi-consumer
项目中.(这一步可以进行优化解耦, 我们可以多创建一个rmi-resource
项目, 让rmi-provider
和rmi-consumer
共同依赖rmi-resource
项目, 然后把资源文件比如远程服务所用到的UserService
等放入rmi-resource
项目中)public static void main(String[] args) {try {//发布远程服务的访问urlString name = "rmi://localhost:8888/rmi";//通过发布远程服务的url, 获取远程服务的代理对象UserService userService = (UserService) Naming.lookup(name);System.out.println("获得的远程服务的代理对象:" + Class().getName());String result = userService.helloRmi("rmi");//拿到远程方法调用的结果System.out.println("result: " + result);}catch (Exception e) {e.printStackTrace();}
}//最后输出
获得的远程服务的代理对象:com.sun.proxy.$Proxy0
result: hello rmi
http + xml
进行通信.UserService
及其实现类UserServiceImpl
.WebService
时需要对远程服务加上注解@WebService
@WebService
public interface UserService {public String sayHello(String name);
}@WebService
public class UserServiceImpl implements UserService {@Overridepublic String sayHello(String name) {return "hello " + name + "~";}
}
rmi
差不多, 需要提供远程服务的访问地址和具体的远程服务实现类, 使用Endpoint
类的publish()
方法进行发布, 这都是JDK封装好的.public class WsProviderApp {public static void main(String[] args) {//发布的WebService的被访问地址String address = "localhost:9999/ws";//创建远程服务对象UserService userService = new UserServiceImpl();//发布服务Endpoint.publish(address, userService);System.out.println("远程服务已经发布...");}
}
rmi
不同的是, WebService发布后, 调用者可以通过查看它的文档对远程服务发起调用.?wdsl
, 比如本案例中是localhost:9999/ws?wsdl
bin
目录下, 名字是wsimport
wsimport -keep -d C:githubRepositoriesshoppingws-consumersrcmainjava -p com.shenghao.client localhost:9999/ws?wsdl解释:
1. wsimport 是命令的名字
2. -keep 用于保留生成的类, 如果没有该指令会只生成class文件
3. -d 后面接项目中存放这些工具类的包, 填绝对路径
4. -p 填wdsl文档的地址
UserServiceImplService
. 下面演示对远程方法进行调用.public static void main(String[] args) {//创建服务类对象UserServiceImplService service = new UserServiceImplService();//获得远程服务的代理对象UserServiceImpl userService = UserServiceImplPort();System.out.Class().getName());//对远程服务对象的方法进行调用String result = userService.sayHello("炭烧生蚝");System.out.println(result);
}//结果输出
com.sun.proxy.$Proxy32
hello 炭烧生蚝~
<html>
标签, 而是json
字符串. 微信小程序前后端通信也是这个原理.order-sys
的Maven项目, 指定打包为war
包. 4.3.18.RELEASE1.22.52.02.9.0jstljstl${jstl.version}javax.servletservlet-api${servlet-api.version}providedjavax.servletjsp-api${jsp-api.version}providedorg.springframeworkspring-webmvc${spring.version}com.jackson-databind${jackson.version}at.maventomcat7-maven-plugin2.2/order7070
public class Order {private String id;private Double total;private String date;//get / set ...
}
Tomcat
上@Controller
public class OrderController {/*** 接收http请求, 响应订单集合, 异步响应* 将list集合序列化为json串响应* @param uid* @return*/@RequestMapping("/loadOrderList2")@ResponseBodypublic List<Order> 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<Order> list = new ArrayList<>();list.add(o1);list.add(o2);list.add(o3);return list;}
}
HttpClient
发送请求, 可以理解为模拟浏览器发送post/get请求. HttpClient
为我们封装了拼接一个请求的细节, 使得发送一个请求变得容易.public static void main(String[] args) throws IOException {//发送远程的http请求的地址String url = "localhost:7070/order/loadOrderList2";//创建HttpClient对象CloseableHttpClient client = ateDefault();//创建HttpPost对象, 发送post请求HttpPost method = new HttpPost(url);//封装发送到服务提供者的参数NameValuePair id = new BasicNameValuePair("uid", "10001");List<NameValuePair> params = new ArrayList<>();params.add(id);//封装请求体数据method.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));//发送具体的http请求HttpResponse response = ute(method);//获得服务提供者响应的具体数据HttpEntity entity = Entity();//获得http的响应体InputStream is = Content();int len = 0;char[] buf = new char[1024];//使用字符流读InputStreamReader reader = new InputStreamReader(is);StringBuffer sb = new StringBuffer();while((len = ad(buf)) != -1){sb.append(String.valueOf(buf, 0, len));}System.out.println(sb);//将响应回来的json字符串解析为Order集合List<Order> list = JSON.String(), Order.class);for(Order o : list){System.out.Id() + "t" + o.getTotal() + "t" + o.getDate());}
}
HttpClient
中的订单系统, 通过访问loadOrderList2
方法能返回一个订单集合Json字符串.@Controller
public class RedController {//注入由spring提供的RestTemplate对象@Autowiredprivate RestTemplate restTemplate;/*** 发送远程的http请求, 消费http服务* 获得订单对象的集合*/@RequestMapping("/loadOrderList3")@ResponseBodypublic List<ResponseEntity<Order[]>> loadOrderList3(String uid){//发送远程http请求的urlString url = "localhost:7070/order/loadOrderList2";//发送到远程服务的参数MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();params.add("uid", uid);//通过RestTemplate对象发送post请求ResponseEntity<Order[]> entitys = restTemplate.postForEntity(url, params, Order[].class);//查看响应的状态码System.out.StatusCodeValue());//查看响应头HttpHeaders headMap = Headers();for(Map.Entry<String, List<String>> m : Set()){System.out.Key() + ": " + m.getValue());}return Arrays.asList(entitys);}
}
转载于:.html
本文发布于:2024-01-27 19:15:31,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/17063541312110.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |