问题:
RPC,所谓远程调用,就是由服务消费者发起请求调用服务提供者中的方法完成功能处理,然后服务提供者再将执行结果响应给服务消费者的一个过程。那么浏览器和服务器的交互方式,好像就是远程调用,那么我们能不能参照
浏览器和服务器交互的模式来实现项目之间的远程调用呢?
方案:
- 服务器消费者--->浏览器--->在服务消费者中声明类似浏览器发起请求和接收响应的代码。
- 服务器提供者--->MVC的web项目
实现:
HttpClient
使用:
1、服务提供者的代码就是正常的Web项目
2、服务器消费中导入HttpClient的jar包,然后编写相关代码完成rpc远程调用,参照源码
一.服务提供方代码
package com.bjsxt.controller;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSON;
import com.bjsxt.pojo.Pet;
import com.bjsxt.service.PetService;
@Controller
public class PetCon {
@Resource
private PetService petServiceImpl;
/**
* 获取所有的宠物信息
*/
@RequestMapping("pet")
public String getPet(HttpServletRequest req){
List<Pet> pl = petServiceImpl.getPetInfoService();
req.setAttribute("pl", pl);
return "pet.jsp";
}
/**
* 获取所有的宠物信息
* @param pname
* @param color
* @return
*/
@ResponseBody
@RequestMapping("pet2")
public List<Pet> getPet(String pname,String color){
System.out.println("Pet2请求数据===="+pname+":"+color);
List<Pet> pl = petServiceImpl.getPetInfoService();
return pl;
}
/**
* 处理Ajax请求,返回所有的宠物信息,Jsop方式
* @param pname
* @param color
* @return
* callback({name:zhansgan,age:18})
*/
@ResponseBody
@RequestMapping(value="petAjax",produces="text/script;charset=UTF-8")
public String getPetAjax(String callback,String pname,String color){
System.out.println("getPetAjax请求数据==跨域=="+pname+":"+color);
List<Pet> pl = petServiceImpl.getPetInfoService();
//将数据转换为json字符串
String jsonString = JSON.toJSONString(pl);
return callback+"("+jsonString+")";
}
/**
* 获取所有的宠物信息,coresFilter方式
*/
@ResponseBody
@RequestMapping("petFilter")
public List<Pet> getPetFilter(String pname,String color){
System.out.println("Pet2请求数据===="+pname+":"+color);
List<Pet> pl = petServiceImpl.getPetInfoService();
return pl;
}
}
service接口和service实现类略....
pom.xml文件如下..
<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.rpc</groupId>
<artifactId>04-HttpServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<commons.version>1.2</commons.version>
<jsp.version>2.0</jsp.version>
<jstl.version>1.2</jstl.version>
<servlet.version>2.5</servlet.version>
<spring.version>4.3.18.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commons.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp.version}</version>
<scope>provided</scope>
</dependency>
<!-- servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<!-- jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<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>2.9.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<!-- 添加CoresFilter过滤器依赖 -->
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<!--
tomcat插件,maven内嵌的tomcat
作用:用来测试maven的web项目
-->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>7070</port><!-- tomcat的访问端口 -->
<path>/server</path><!-- web项目的上下文 -->
<!-- http://localhost:8080/xxx -->
</configuration>
</plugin>
</plugins>
</build>
</project>
三.服务消费方代码(重点)
package com.bjsxt.main;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import com.alibaba.fastjson.JSON;
import com.bjsxt.pojo.Pet;
public class TestHttpClient {
public static void main(String[] args) {
try {
//获取HttpClient链接对象
HttpClient hc=HttpClients.createDefault();
//创建URL
String url="http://localhost:7070/server/pet2";
//创建请求对象
HttpPost hp=new HttpPost(url);
//创建请求实体
//创建BasicNameValuePair对象,存储键值对请求数据
BasicNameValuePair bp1=new BasicNameValuePair("pname", "大黄");
BasicNameValuePair bp2=new BasicNameValuePair("color", "黄色");
//创建List集合对象,存储请求实体数据
List<BasicNameValuePair> lb=new ArrayList<>();
lb.add(bp1);
lb.add(bp2);
//创建封装请求实体数据的对象
UrlEncodedFormEntity ufo=new UrlEncodedFormEntity(lb,"UTF-8");
//设置实体数据到HttpPost请求对象中
hp.setEntity(ufo);
//发起请求
HttpResponse resp = hc.execute(hp);
//获取响应头
Header[] allHeaders = resp.getAllHeaders();
for(Header h:allHeaders){
System.out.println(h.getName()+":"+h.getValue());
}
//获取响应实体
InputStream is = resp.getEntity().getContent();
int len=0;
//将is字节流,转化为字符流
InputStreamReader reader = new InputStreamReader(is);
char[] buf=new char[1024]; //创建StringBuffer对象
StringBuffer result = new StringBuffer();
while((len=reader.read(buf))!=-1){
result.append(String.valueOf(buf,0,len));
}
System.out.println(result);
List<Pet> parseArray = JSON.parseArray(result.toString(), Pet.class);
System.out.println(parseArray);
} catch (Exception e) {
// TODO: handle exception
}
}
}
pom.xml文件
<dependencies>
<!-- httpclient客户端工具包 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<version>4.3.5</version>
<artifactId>httpclient</artifactId>
</dependency>
<!-- javabean对象和json串之间转化为工具包 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
</dependencies>
</project>
四.工具类
下面是自己常用的一个对post和get请求封装的HttpClient工具类
package com.ego.commons.utils;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
public class HttpClientUtil {
public static String doGet(String url, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
String resultString = "";
CloseableHttpResponse response = null;
try {
// 创建uri
URIBuilder builder = new URIBuilder(url);
if (param != null) {
for (String key : param.keySet()) {
builder.addParameter(key, param.get(key));
}
}
URI uri = builder.build();
// 创建http GET请求
HttpGet httpGet = new HttpGet(uri);
// 执行请求
response = httpclient.execute(httpGet);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
public static String doGet(String url) {
return doGet(url, null);
}
public static String doPost(String url, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建参数列表
if (param != null) {
List<NameValuePair> paramList = new ArrayList<>();
for (String key : param.keySet()) {
paramList.add(new BasicNameValuePair(key, param.get(key)));
}
// 模拟表单
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList,"utf-8");
httpPost.setEntity(entity);
}
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return resultString;
}
public static String doPost(String url) {
return doPost(url, null);
}
public static String doPostJson(String url, String json) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建请求内容
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return resultString;
}
}
网友评论