• Jetty + HttpClient 处理http请求


    本人最近通过自己动手处理http请求,对http协议、Jetty以及HttpClient有了更深刻的理解,特在此与大家分享。

    此图是http协议的请求格式。根据请求方法,有get和post之分。get和post的区别在于参数传递的方式:post的参数就是请求包体那一行;get的参数跟在URL后面,也就没有请求包体。

    get方式的请求格式

    GET /search?hl=zh-CN&source=hp&q=domety&aq=f&oq= HTTP/1.1  
    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, 
    application/msword, application/x-silverlight, application/x-shockwave-flash, */* Referer: <a href="http://www.google.cn/">http://www.google.cn/</a> Accept-Language: zh-cn Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; TheWorld) Host: <a href="http://www.google.cn">www.google.cn</a> Connection: Keep-Alive Cookie: PREF=ID=80a06da87be9ae3c:U=f7167333e2c3b714:NW=1:TM=1261551909:LM=1261551917:S=ybYcq2wpfefs4V9g;
    NID=31=ojj8d-IygaEtSxLgaJmqSjVhCspkviJrB6omjamNrSm8lZhKy_yMfO2M4QMRKcH1g0iQv9u-2hfBW7bUFwVh7pGaRUb0RnHcJU37y-
    FxlRugatx63JLv7CWMD6UB_O_r

    post方式的请求格式

    POST /search HTTP/1.1  
    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, 
    application/msword, application/x-silverlight, application/x-shockwave-flash, */* Referer: <a href="http://www.google.cn/">http://www.google.cn/</a> Accept-Language: zh-cn Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; TheWorld) Host: <a href="http://www.google.cn">www.google.cn</a> Connection: Keep-Alive Cookie: PREF=ID=80a06da87be9ae3c:U=f7167333e2c3b714:NW=1:TM=1261551909:LM=1261551917:S=ybYcq2wpfefs4V9g;
    NID=31=ojj8d-IygaEtSxLgaJmqSjVhCspkviJrB6omjamNrSm8lZhKy_yMfO2M4QMRKcH1g0iQv9u-2hfBW7bUFwVh7pGaRUb0RnHcJU37y-
    FxlRugatx63JLv7CWMD6UB_O_r hl=zh-CN&source=hp&q=domety

    所以,对请求进行解析的时候需要区分。

    1、用Jetty捕获请求

    直接上代码

     1 package test;
     2 import org.eclipse.jetty.server.Request;  
     3 import org.eclipse.jetty.server.Server;  
     4 import org.eclipse.jetty.server.handler.AbstractHandler;
     5 
     6 import javax.servlet.ServletException;
     7 import javax.servlet.http.HttpServletRequest;
     8 import javax.servlet.http.HttpServletResponse;  
     9    
    10 public class JettyServer {   
    11     public static void main(String[] args) {  
    12         try {  
    13             // 进行服务器配置  
    14             Server server = new Server(8888); 
    15             server.setHandler(new MyHandler());               
    16             // 启动服务器  
    17             server.start();  
    18             server.join();  
    19         } catch (Exception e) {  
    20             e.printStackTrace();  
    21         }    
    22     }   
    23 }  
    24   
    25 class MyHandler extends AbstractHandler {
    26     
    27     @Override  
    28     public void handle(String target, Request baseRequest,  
    29         HttpServletRequest request, HttpServletResponse response)  
    30         throws IOException, ServletException {  
    31         //写自己的处理
    32     }  
    33     
    34 } 
    View Code

    Jetty类似于tomcat,但是Jetty比较轻量级,特别适合内嵌到自己写的程序中,比如Hadoop的内置Server就是Jetty。

    Jetty将请求进行了封装,比如Jetty自己的Request类,以及我们熟悉的HttpServletRequest类;并且把对象传递给handler。我们拿到HttpServletRequest的对象,就可以对请求进行解析、修改和拼装

    Enumeration params = request.getParameterNames();  
            while(params.hasMoreElements()){  
                String paraName = (String)params.nextElement(); 
                String paraValue = request.getParameter(paraName);
                paramList.add(new BasicNameValuePair(paraName, paraValue));
            }
    
    
    Enumeration headerNames = request.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String headerName = (String) headerNames.nextElement();
                    //HttpClient会自动加上这个请求头
                if(headerName.equals("Content-Length")) {
                    continue;
                }
                String headerValue = request.getHeader(headerName);            
                Header header = new BasicHeader(headerName, headerValue);
                headers.add(header);
            }
    View Code

    2、用HttpClient转发请求

    把捕获的请求进行重新组装之后,就可以通过HttpClient转发出去。

    HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包。多说无益,简单语法请自行百度。

    下面是一个完整的加入了HttpClient进行请求转发的类

      1 package service;
      2 import java.io.BufferedReader;  
      3 import java.io.IOException;  
      4 import java.io.InputStream;  
      5 import java.io.InputStreamReader;
      6 import java.io.UnsupportedEncodingException;
      7 import java.util.ArrayList;
      8 import java.util.Enumeration;
      9 import java.util.List;
     10 
     11 import javax.servlet.http.HttpServletRequest;
     12 
     13 import org.apache.http.Header;
     14 import org.apache.http.HttpEntity;  
     15 import org.apache.http.HttpResponse;
     16 import org.apache.http.NameValuePair;
     17 import org.apache.http.client.ClientProtocolException;  
     18 import org.apache.http.client.HttpClient;
     19 import org.apache.http.client.entity.UrlEncodedFormEntity;
     20 import org.apache.http.client.methods.HttpGet;
     21 import org.apache.http.client.methods.HttpPost;
     22 import org.apache.http.client.methods.HttpUriRequest;
     23 import org.apache.http.impl.client.DefaultHttpClient;
     24 import org.apache.http.message.BasicHeader;
     25 import org.apache.http.message.BasicNameValuePair;  
     26   
     27 public class RequestSender implements Runnable {  
     28     private HttpClient httpclient = null;
     29     private RequestAdaptor requestAdaptor = null;//封装之后的请求
     30     private String ip = null;
     31     private String port = null;
     32     
     33     public RequestSender(RequestAdaptor requestAdaptor, String ip, String port) {
     34         httpclient = new DefaultHttpClient();
     35         this.requestAdaptor = requestAdaptor;
     36         this.ip = ip;
     37         this.port = port;
     38     }
     39     
     40     @Override
     41     public void run() {
     42         send();    
     43     }
     44     
     45     public void send() {
     46         if(requestAdaptor == null) {
     47             return;
     48         }
     49         String method = requestAdaptor.getMethod();
     50         String uri = requestAdaptor.getUri();    
     51         String host = ip + ":" + port;
     52         String url = "http://" + host + uri;
     53         if(method.equals("GET")) {
     54             get(url);
     55         }else if(method.equals("POST")) {              
     56             post(url);
     57         }
     58     }
     59     
     60     public void get(String url) {
     61         url = url + "?" + requestAdaptor.getQueryString();
     62         HttpGet httpGet = new HttpGet(url);        
     63         addHeaders(httpGet);
     64         try{
     65             
     66             HttpResponse resp = httpclient.execute(httpGet);
     67             System.out.println(resp.getStatusLine().getStatusCode());
     68         }catch(ClientProtocolException cp) {
     69             cp.printStackTrace();
     70         }catch(IOException io) {
     71             io.printStackTrace();
     72         }
     73         //return showResponse(httpGet);
     74     }
     75     
     76     public void post(String url) {
     77         System.out.println(url);
     78         HttpPost httpPost = new HttpPost(url);
     79         addHeaders(httpPost); 
     80         UrlEncodedFormEntity uefEntity = null;
     81         try {
     82             uefEntity = new UrlEncodedFormEntity(requestAdaptor.getParamList(), "UTF-8");
     83         } catch (UnsupportedEncodingException e) {
     84             e.printStackTrace();
     85         }  
     86         httpPost.setEntity(uefEntity);  
     87         try{
     88             HttpResponse resp = httpclient.execute(httpPost);    
     89             System.out.println(resp.getStatusLine().getStatusCode());
     90         }catch(ClientProtocolException cp) {
     91             cp.printStackTrace();
     92         }catch(IOException io) {
     93             io.printStackTrace();
     94         }
     95         //return showResponse(httpPost);
     96     }
     97 
     98     public void addHeaders(HttpUriRequest httpUriRequest) {     
     99         List<Header> headers = requestAdaptor.getHeaders();
    100         for(int i = 0 ; i< headers.size();i++){              
    101             httpUriRequest.addHeader(headers.get(i));   
    102         } 
    103     }
    104     
    105     public String showResponse(HttpUriRequest httpUriRequest) {        
    106         HttpResponse response = null;
    107         try {
    108             response = httpclient.execute(httpUriRequest);
    109         } catch (ClientProtocolException e) {
    110             e.printStackTrace();
    111         } catch (IOException e) {
    112             e.printStackTrace();
    113         }    
    114         HttpEntity entity = response.getEntity();    
    115         if (entity != null) {    
    116             InputStream instreams = null;
    117             try {
    118                 instreams = entity.getContent();
    119             } catch (UnsupportedOperationException e) {
    120                 e.printStackTrace();
    121             } catch (IOException e) {
    122                 e.printStackTrace();
    123             }    
    124             String str = convertStreamToString(instreams);  
    125             //System.out.println(str);  
    126             // Do not need the rest    
    127             httpUriRequest.abort(); 
    128             return str;
    129         }  
    130         return null;
    131     }
    132 
    133       
    134     public static String convertStreamToString(InputStream is) {      
    135         BufferedReader reader = new BufferedReader(new InputStreamReader(is));      
    136         StringBuilder sb = new StringBuilder();            
    137         String line = null;      
    138         try {      
    139             while ((line = reader.readLine()) != null) {  
    140                 sb.append(line + "
    ");      
    141             }      
    142         } catch (IOException e) {      
    143             e.printStackTrace();      
    144         } finally {      
    145             try {      
    146                 is.close();      
    147             } catch (IOException e) {      
    148                e.printStackTrace();      
    149             }      
    150         }      
    151         return sb.toString();      
    152     }        
    153 }
    View Code

    转发的核心是httpclient.execute(httpGet)和httpclient.execute(httpPost)

    转发post请求的时候,需要把参数一个一个的组装进去;而转发get请求的时候就不用,应为参数已经跟在URL后面。但是,无论get还是post,都需要把请求头原封不动的组装进去。

    基于以上两点,我们可以做的事情就有很多了。

  • 相关阅读:
    转载:《TypeScript 中文入门教程》 14、输入.d.ts文件
    转载:《TypeScript 中文入门教程》 13、类型兼容性
    转载:《TypeScript 中文入门教程》 12、类型推导
    转载:《TypeScript 中文入门教程》 11、声明合并
    转载:《TypeScript 中文入门教程》 10、混入
    转载:《TypeScript 中文入门教程》 9、泛型
    转载:《TypeScript 中文入门教程》 8、函数
    转载:《TypeScript 中文入门教程》 7、模块
    转载:《TypeScript 中文入门教程》 6、命名空间
    转载:《TypeScript 中文入门教程》 5、命名空间和模块
  • 原文地址:https://www.cnblogs.com/cz123/p/5443224.html
Copyright © 2020-2023  润新知