gdx 发表于 2017-3-1 12:03:27

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,都需要把请求头原封不动的组装进去。
  基于以上两点,我们可以做的事情就有很多了。
页: [1]
查看完整版本: Jetty + HttpClient 处理http请求