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 + "\n");      
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,都需要把请求头原封不动的组装进去。

 

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

 

转载于:https://www.cnblogs.com/cz123/p/5443224.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值