一、RMI
RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。
1、服务提供者实现
UserService接口
import java.rmi.Remote;
import java.rmi.RemoteException;
/***
* 创建需要发布的服务对应的业务接口
* Remote 接口用于标识其方法可以从非本地虚拟机上调用的接口。
*/
public interface UserService extends Remote {
public String helloRmi(String name) throws RemoteException;
}
UserServiceImpl
import com.bjsxt.service.UserService;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
/**
* 创建发布的服务对应的实现类
*/
public class UserServiceImpl extends UnicastRemoteObject implements UserService {
public UserServiceImpl() throws RemoteException {
}
@Override
public String helloRmi(String name) throws RemoteException {
return "Hello"+name;
}
}
发布服务
import com.bjsxt.service.UserService;
import com.bjsxt.service.impl.UserServiceImpl;
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
public class ProviderApp {
public static void main(String[] args) {
try {
/**
* 完成远程服务的发布
*/
//将远程服务发布到本地的8888端口上
LocateRegistry.createRegistry(8888);
//发布的远程服务的访问url
String name = "rmi://localhost:8888/rmi";
//创建一个提供具体服务的远程对象
UserService userService = new UserServiceImpl();
//给提供远程服务的对象绑定一个url
Naming.bind(name,userService);
System.out.println("===============发布rmi远程服务==================");
}catch (Exception e){
e.printStackTrace();
}
}
2、消费者实现
UserService:拷贝接口即可
消费远程服务
import com.bjsxt.service.UserService;
import java.rmi.Naming;
public class ConsumerApp {
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);
}catch (Exception e){
e.printStackTrace();
}
}
}
3、RMI 相关 API 总结
Romote接口
标识某个方法可以被远程调用
UnicastRemoteObject 类
实现 Remote 远程对象的导出
Naming
给提供远程服务的对象的绑定 url,通过远程的 url,获得提供远程服务的代理对象
LocateRegistry 类
指定发布的远程服务的方法接口
4、提取公共资源的思想
将公共的接口或工具类提取到一个工程中,在需要用到他们的工程中添加依赖即可.
二、WebService
Web service 是一个平台独立的,低耦合的 web 的应用程序用于开发分布式的互操作的应用程序。Web Service 技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。
SOAP(Simple Object Access Protocol) 简单对象访问协议:
SOAP=http+xml
WSDL(Web Services Description Language) Web Service 的描述语言:
一个 webservice 服务的说明书,通过该说明书可以完成 webservice 服务的调用
1、服务提供者实现
UserService接口
import javax.jws.WebService;
/***
* 需要发布的服务对应的接口
* @WebService 发布远程的 web 服务,默认情况下该接口中的
* 所有 public 方法都会被发布
*/
@WebService
public interface UserService {
//@WebMethod(),如果不想发布某一个服务,用这个注解实现
public String sayHello(String name);
}
UserServiceImpl
import com.bjsxt.service.UserService;
import javax.jws.WebService;
@WebService
public class UserServiceImpl implements UserService {
@Override
public String sayHello(String name) {
return "hello-----"+name;
}
}
发布webservice服务
import com.bjsxt.service.UserService;
import com.bjsxt.service.impl.UserServiceImpl;
import javax.xml.ws.Endpoint;
public class WsProviderApp {
public static void main(String[] args) {
/***
* 完成 webservice 服务的发布
*/
//发布的webservice服务的访问地址
String address = "http://localhost:9999/ws";
//创建userservice对象
UserService userService = new UserServiceImpl();
//发布具体的webservice服务
Endpoint.publish(address,userService);
System.out.println("============发布webservice服务================");
}
}
2、获取wsdl文档
http://localhost:9999/ws?wsdl
3、服务消费者实现
使用wsimport 生成消费者代码
wsimport -keep -d D:ideaegows-consumersrcmainjava -p com.bjsxt.client http://localhost:9999/ws?wsdl
消费远程服务
import com.bjsxt.client.UserServiceImpl;
import com.bjsxt.client.UserServiceImplService;
public class WsConsumerApp {
public static void main(String[] args) {
/***
* 完成 webservice 服务的消费
*/
//创建服务类对象
UserServiceImplService service = new UserServiceImplService();
//获取远程服务的代理对象
UserServiceImpl userService = service.getUserServiceImplPort();
System.out.println(userService.getClass().getName());
//进行远程服务的调用
String name = userService.sayHello("张三");
System.out.println(name);
}
}
4、WEBSERVICE 相关 API 总结
@WebService
指定发布远程的服务,哪些功能发布为远程服务
EndPoint
发布具体的远程服务,给提供远程服务的对象绑定一个 url
三、HttpClient
HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。
HttpClient 是 Apache Jakarta Common 下的子项目,供高效的、最新的、功能丰富的支持HTTP 协议的客户端编程工具包。实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)支持RestFul。
1、服务提供者实现
创建实体类,配置文件
pom文件配置依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjsxt</groupId>
<artifactId>order-sys</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<!-- spring 依赖 -->
<spring.version>4.3.18.RELEASE</spring.version>
<jstl.version>1.2</jstl.version>
<servlet-api.version>2.5</servlet-api.version>
<jsp-api.version>2.0</jsp-api.version>
<jackson.version>2.9.0</jackson.version>
</properties>
<dependencies>
<!-- jsp相关依赖 -->
<!-- servlet依赖 -->
<!-- jstl依赖 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- springmvc依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
<build>
<finalName>order</finalName>
<plugins>
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/order</path>
<port>7070</port>
</configuration>
</plugin>
</plugins>
</build>
</project>
controller层(异步和同步)
package com.bjsxt.web.controller;
import com.bjsxt.pojo.Order;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.ArrayList;
import java.util.List;
@Controller
public class OrderController {
/**
* 接收 http 请求,响应订单集合
* 同步方式,返回text静态页面
* **/
@RequestMapping("/loadOrderList")
public String loadOrderList(String uid, Model model){
Order o1 = new Order();
o1.setId("111");
o1.setTotal(123.0);
o1.setDate("2018-10-10");
Order o2 = new Order();
o2.setId("222");
o2.setTotal(222.22);
o2.setDate("2014-10-10");
Order o3 = new Order();
o3.setId("333");
o3.setTotal(12399.00);
o3.setDate("2019-10-01");
List<Order> list = new ArrayList<>();
list.add(o1);
list.add(o2);
list.add(o3);
model.addAttribute("list",list);
return "index.jsp";
}
/**
* 接收 http 请求,响应订单集合,完成的是异步响应
* 将 List 集合序列化为 json 串响应
* **/
@RequestMapping("/loadOrderList2")
@ResponseBody
public List<Order> loadOrderList2(String uid){
System.out.println("uid="+uid);
Order o1 = new Order();
o1.setId("101");
o1.setTotal(1234.2);
o1.setDate("2018-12-10");
Order o2 = new Order();
o2.setId("202");
o2.setTotal(2323.3);
o2.setDate("2019-10-10");
Order o3 = new Order();
o3.setId("303");
o3.setTotal(4422.0);
o3.setDate("2019-11-01");
List<Order> list = new ArrayList<>();
list.add(o1);
list.add(o2);
list.add(o3);
return list;
}
}
2、消费者
创建实体类,配置文件
pom文件配置依赖
<!--阿里的json解析工具包,可以将json字符串和Java对象做转换-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjsxt</groupId>
<artifactId>user-sys</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.5</version>
</dependency>
<!--阿里的json解析工具包,可以将json字符串和Java对象做转换-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
</dependencies>
</project>
测试类Post请求
注意:返回数据给服务器是靠 NameValuePair实现的,创建对象封装数据,利用post方式发送
//创建httpPOST对象,发送post请求
HttpPost method = new HttpPost(url);
//封装请求体数据
method.setEntity(new UrlEncodedFormEntity(params,"utf-8"));
package com.bjsxt.test.client;
import com.alibaba.fastjson.JSON;
import com.bjsxt.pojo.Order;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class TestHttpClient {
public static void main(String[] args) throws IOException {
/**
* 启动消费者进行服务的消费
* httpClient 发送远程请求,服务提供响应的为 json,
* json 直接可以解析 java 对象,或者 java 对象的集合
* **/
//创建 NameValuePair 对象,封装发送服务提供者的参数
NameValuePair id = new BasicNameValuePair("uid","1001");
/* NameValuePair name = new BasicNameValuePair("uname","1001");
NameValuePair address = new BasicNameValuePair("address","1001");*/
List<NameValuePair> params = new ArrayList<>();
params.add(id);
//发送远程的http请求的地址
String url = "http://localhost:7070/order/loadOrderList2";
//创建HTTPClient客户端对象
HttpClient client = HttpClients.createDefault();
//创建httpPOST对象,发送post请求
HttpPost method = new HttpPost(url);
//封装请求体数据
method.setEntity(new UrlEncodedFormEntity(params,"utf-8"));
//发送具体的http请求,返回HttpResponse对象,里面封装了响应头数据
HttpResponse response = client.execute(method);
//获取响应头信息
Header[] headers = response.getAllHeaders();
for(Header h : headers){
System.out.println(h.getName()+"---"+h.getValue());
}
//获取服务提供者响应的具体数据
HttpEntity entity = response.getEntity();
//获取http的响应体
InputStream content = entity.getContent();
int len = 0;
char[] buf = new char[1024];
//将字节流转换成字符流
InputStreamReader reader = new InputStreamReader(content);
//创建StringBuffer
StringBuffer result = new StringBuffer();
while ((len=reader.read(buf))!=-1){
result.append(String.valueOf(buf,0,len));
}
System.out.println(result);
//将result,json字符串解析为Order集合
List<Order> list = JSON.parseArray(result.toString(), Order.class);
for(Order o : list){
System.out.println(o.getId()+"---"+o.getTotal()+"---"+o.getDate());
}
}
}