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捕获请求
直接上代码
package test;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class JettyServer {
public static void main(String[] args) {
try {
// 进行服务器配置
Server server = new Server(8888);
server.setHandler(new MyHandler());
// 启动服务器
server.start();
server.join();
} catch (Exception e) {
e.printStackTrace();
}
}
} class MyHandler extends AbstractHandler { @Override
public void handle(String target, Request baseRequest,
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
//写自己的处理
} }
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);
}
2、用HttpClient转发请求
把捕获的请求进行重新组装之后,就可以通过HttpClient转发出去。
HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包。多说无益,简单语法请自行百度。
下面是一个完整的加入了HttpClient进行请求转发的类
package service;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
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.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair; public class RequestSender implements Runnable {
private HttpClient httpclient = null;
private RequestAdaptor requestAdaptor = null;//封装之后的请求
private String ip = null;
private String port = null; public RequestSender(RequestAdaptor requestAdaptor, String ip, String port) {
httpclient = new DefaultHttpClient();
this.requestAdaptor = requestAdaptor;
this.ip = ip;
this.port = port;
} @Override
public void run() {
send();
} public void send() {
if(requestAdaptor == null) {
return;
}
String method = requestAdaptor.getMethod();
String uri = requestAdaptor.getUri();
String host = ip + ":" + port;
String url = "http://" + host + uri;
if(method.equals("GET")) {
get(url);
}else if(method.equals("POST")) {
post(url);
}
} public void get(String url) {
url = url + "?" + requestAdaptor.getQueryString();
HttpGet httpGet = new HttpGet(url);
addHeaders(httpGet);
try{ HttpResponse resp = httpclient.execute(httpGet);
System.out.println(resp.getStatusLine().getStatusCode());
}catch(ClientProtocolException cp) {
cp.printStackTrace();
}catch(IOException io) {
io.printStackTrace();
}
//return showResponse(httpGet);
} public void post(String url) {
System.out.println(url);
HttpPost httpPost = new HttpPost(url);
addHeaders(httpPost);
UrlEncodedFormEntity uefEntity = null;
try {
uefEntity = new UrlEncodedFormEntity(requestAdaptor.getParamList(), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
httpPost.setEntity(uefEntity);
try{
HttpResponse resp = httpclient.execute(httpPost);
System.out.println(resp.getStatusLine().getStatusCode());
}catch(ClientProtocolException cp) {
cp.printStackTrace();
}catch(IOException io) {
io.printStackTrace();
}
//return showResponse(httpPost);
} public void addHeaders(HttpUriRequest httpUriRequest) {
List<Header> headers = requestAdaptor.getHeaders();
for(int i = 0 ; i< headers.size();i++){
httpUriRequest.addHeader(headers.get(i));
}
} public String showResponse(HttpUriRequest httpUriRequest) {
HttpResponse response = null;
try {
response = httpclient.execute(httpUriRequest);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instreams = null;
try {
instreams = entity.getContent();
} catch (UnsupportedOperationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
String str = convertStreamToString(instreams);
//System.out.println(str);
// Do not need the rest
httpUriRequest.abort();
return str;
}
return null;
} public static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
转发的核心是httpclient.execute(httpGet)和httpclient.execute(httpPost)
转发post请求的时候,需要把参数一个一个的组装进去;而转发get请求的时候就不用,应为参数已经跟在URL后面。但是,无论get还是post,都需要把请求头原封不动的组装进去。
基于以上两点,我们可以做的事情就有很多了。
Jetty + HttpClient 处理http请求的更多相关文章
- HttpClientUtil [使用apache httpclient模拟http请求]
基于httpclient-4.5.2 模拟http请求 以get/post方式发送json请求,并获取服务器返回的json -------------------------------------- ...
- 【JAVA】通过HttpClient发送HTTP请求的方法
HttpClient介绍 HttpClient 不是一个浏览器.它是一个客户端的 HTTP 通信实现库.HttpClient的目标是发 送和接收HTTP 报文.HttpClient不会去缓存内容,执行 ...
- Android系列之网络(三)----使用HttpClient发送HTTP请求(分别通过GET和POST方法发送数据)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...
- Android系列之网络(一)----使用HttpClient发送HTTP请求(通过get方法获取数据)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- 一步步教你为网站开发Android客户端---HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新ListView
本文面向Android初级开发者,有一定的Java和Android知识即可. 文章覆盖知识点:HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新List ...
- 使用httpclient发送post请求与get请求
最近因为项目的要求,需要使用httpclient来发送请求.但是查阅了许多博客,大家发送请求的方法各不相同.原因是因为httpclient的jar包的不同版本,其内部方法也不相同.因此抛开具体用到的j ...
- Java Apcahe的HTTPClient工具Http请求当请求超时重发
java Apcahe的HTTPClient工具Http请求当请求超时时底层会默认进行重发,默认重发次数为3次,在某些情况下为了防止重复的请求,需要将自动重发覆盖. 设置HTTP参数,设置不进行自动重 ...
- (一)----使用HttpClient发送HTTP请求(通过get方法获取数据)
(一)----使用HttpClient发送HTTP请求(通过get方法获取数据) 一.HTTP协议初探: HTTP(Hypertext Transfer Protocol)中文 “超文本传输协议”,是 ...
- SpringMVC,MyBatis项目中兼容Oracle和MySql的解决方案及其项目环境搭建配置、web项目中的单元测试写法、HttpClient调用post请求等案例
要搭建的项目的项目结构如下(使用的框架为:Spring.SpingMVC.MyBatis): 2.pom.xml中的配置如下(注意,本工程分为几个小的子工程,另外两个工程最终是jar包): 其中 ...
随机推荐
- BinarySearch的一些注意事项
BinarySearch原理比较简单,不过在处理实际问题的过程中需要注意几个小问题: 1. 找出有序数组中第一个为某特定值的数,以及没找到则返回-1 2. 找出有序数组中最后一个为某特定值的数,以及没 ...
- 数据库习题(oracle)
学生表 Student 字段值分别是 Sid ,Sname ,Sage ,Ssex 教师表 Teacher 字段值分别是 Tid ,Tname 课程表 Course 字段值分别是Cid ,Cname ...
- C++命名空间【转】
本讲基本要求 * 掌握:命名空间的作用及定义:如何使用命名空间. * 了解:使用早期的函数库 重点.难点 ◆命名空间的作用及定义:如何使用命名空间. 在学习本书前面各章时,读者 ...
- 如何在 FineUIMvc 中引用第三方 JavaScript 库
声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 引入第三方颜色选择器 在 FineUIMvc 中使用第三方 JavaScript 遵循一定的约定,也非常简单. 下面以官网示例为 ...
- HTTP协议介绍
一.什么是HTTP协议呢? 维基百科 写道 超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是互联网上应用最为广泛的一种网络协议.HTTP是一个客户端终端 ...
- CF #299 div1 B. Tavas and Malekas KMP-next数组
题目链接:http://codeforces.com/contest/536/problem/B 一个原始字符串,一个未知字符串,每一次从pos[i]开始覆盖未知字符串,问最后字符串的形式,以及判断过 ...
- 使用vue-cli构建多页面应用+vux(三)
上节中,我们成功的将vue-cli改造成了多入口,既然用了上简单的脚手架,那就希望用个合适的UI组件,去搜索了几个以后,最后选择了使用vux 贴上其vux的github地址 https://gith ...
- windows和linux双系统修改启动项
在windows系统的基础上再装linux系统的时候,电脑启动就会出现linux的启动引导项,默认的是进入linux.要使电脑默认进入windows只需要修改linux系统的启动引导文件(grub.c ...
- AngularJS入门教程:日期格式化
AngularJS入门教程:日期格式化[转载] 本地化日期格式化: ({{ today | date:'medium' }})Nov 24, 2015 2:19:24 PM ({{ today | d ...
- eNSP自学入门(基础)
写了上篇博客之后,就立即投入到了eNSP的怀抱之中了,自己从零基础,入门到现在.也学了不少东西,在这里和大家分享一下. 说一下学习的过程吧,老师说做网络工程的课程设计用eNSP,关于这个软件什么都没有 ...