美文网首页Zookeeper
HttpClient方式实现RPC远程调用

HttpClient方式实现RPC远程调用

作者: 叫我不矜持 | 来源:发表于2019-03-23 20:04 被阅读0次

    问题:

    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;
        }
    }
    
    

    相关文章

      网友评论

        本文标题:HttpClient方式实现RPC远程调用

        本文链接:https://www.haomeiwen.com/subject/fbcevqtx.html