关于http协议------HttpServlet、HttpClient、URLConnection的关系

记录一次HTTP相关内容的学习

关于HttpServlet

在大多数的Web应用程序中,客户端都是通过Http协议去访问服务器端的资源,而我们编写的Servlet主要是用于Http协议的请求和响应处理。为了快速开发应用于Http协议的Servlet类,Sun公司在javax.servlet.http包中提供了一个抽象类HttpServlet,它继承于GenericServlet,用于创建适合基于Http协议的Web Servlet。创建一个HTTPservlet必须继承HttpServlet类,并且重写里面的doGet,doPost方法。。。。

创建一个servlet用于处理请求 

public class ThreeServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

System.out.println("这是GET方式发送的请求,Servlet使用doGet()方法来处理.");

}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

System.out.println("这是POST方式发送的请求,Servlet使用doPost()方法来处理.");

}

}

HttpClient和HttpURLConnection

简单来说,HttpClient就是一个增强版的HttpURLConnection,HttpURLConnection可以做的事情HttpClient全部可以做;HttpURLConnection没有提供的有些功能,HttpClient也提供了,但它只是关注于如何发送请求、接收响应,以及管理HTTP连接。

使用HttpClient发送请求、接收响应很简单,只要如下几步即可: 

1.创建HttpClient对象。 

2.如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。 

3.如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。 

4.调用HttpClient对象的execute(HttpUriRequest request)发送请求,执行该方法返回一个HttpResponse。 

5.调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。 

public classHttpClientTest{

publicString doPost(String url, String params) {

CloseableHttpClient httpClient = HttpClients.createDefault();//创建Httpclient对象

HttpPost httpPost =newHttpPost(url);//创建HttpPost对象

httpPost.setHeader("Accept","application/xml");

httpPost.setHeader("Content-Type","application/xml");

String charSet ="UTF-8";

StringEntity entity =newStringEntity(params, charSet);

httpPost.setEntity(entity);//使用setEntity方法来设置请求参数

CloseableHttpResponse response =null;

try{

response = httpClient.execute(httpPost);//调用httpclient对象的execute发送请求,执行方法返回一个httpresponse

StatusLine status = response.getStatusLine();

intstate = status.getStatusCode();

if(state == HttpStatus.SC_OK) {

HttpEntity responseEntity = response.getEntity();//调用httpResponse的getEntity方法可获得httpEntity对象,程序可通过该对象获取服务器的响应内容

String xmlString = EntityUtils.toString(responseEntity);

returnxmlString;

}else{

System.out.println("请求返回:"+ state +"("+ url +")");

}

}catch(Exception e) {

e.printStackTrace();

}finally{

if(response !=null){

try{

response.close();

}catch(IOException e) {

e.printStackTrace();

}

}

try{

httpClient.close();

}catch(IOException e) {

e.printStackTrace();

}

}

return null;

}

public static voidmain(String[] args)throwsUnsupportedEncodingException {

String url ="http://172.21.65.253/sessions";

HttpClientTest client =newHttpClientTest();

String result = client.doPost(url,"paramString");

System.out.println("URL:");

System.out.println(" "+url);

System.out.println("请求:");

System.out.println(" "+params);

System.out.println("响应:");

System.out.println(" "+result);

}

}

使用HttpURLConnection发送HTTP请求

public static String requestContentWithGet(String urlStr) {

String content = null;

if (urlStr != null && urlStr.startsWith("http://")) {

URL url = null;

HttpURLConnection conn = null;

try {

url = new URL(urlStr);

conn = (HttpURLConnection) url.openConnection();

conn.setDoOutput(true); //设置是否向conn输出,因为这个是post请求,参数要放在http正文内,因此需要设为true, 默认情况下是false

conn.setDoInput(true); //设置是否从conn读入,默认情况下是true

conn.setUseCaches(false); //Post请求不能使用缓存

conn.setRequestMethod("POST"); // 设定请求的方法为"POST",默认是GET

conn.setConnectTimeout(6*1000); //设置连接主机超时

conn.setReadTimeout(6*1000); //设置从主机读取数据超时

conn.setRequestProperty("Content-type", "application/x-java-serialized-object"); //设定传送的内容类型是可序列化的java对象,(如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)

conn.setRequestProperty("accept", "*/*");

conn.setRequestProperty("Charset", "UTF-8");

conn.connect(); //连接,所有的配置必须要在connect之前完成

OutputStream outStrm = conn.getOutputStream(); //此处getOutputStream会隐含的进行connect(即:如同调用上面的connect()方法,所以在开发中不调用上述的connect()也可以)。

ObjectOutputStream objOutputStrm = new ObjectOutputStream(outStrm); //现在通过输出流对象构建对象输出流对象,以实现输出可序列化的对象。

objOutputStrm.writeObject(new String("我是测试数据")); //向对象输出流写出数据,这些数据将存到内存缓冲区中

objOutputStm.flush(); //刷新对象输出流

objOutputStm.close(); //关闭流对象。此时,不能再向对象输出流写入任何数据,先前写入的数据存在于内存缓冲区中,在调用下边的getInputStream()函数时才把准备好的http请求正式发送到服务器

int responseCode = conn.getResponseCode();

if (responseCode == HttpURLConnection.HTTP_OK) {

//调用conn连接对象的getInputStream()函数, 将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端。

content = convertStream2String(conn.getInputStream()); //getInputStream()方法已调用,本次HTTP请求已结束,下边向对象输出流的输出已无意义,因此,要重新发送数据时需要重新创建连接、重新设参数、重新创建流对象、重新写数据

} else {

content = "";

}

} catch (Exception e) {

} finally {

if (conn != null) {

conn.disconnect();

conn = null;

}

}

}

return content;

}

总的来说  

也就是servlet相当于服务端,是用于接收请求发送响应,也就是说当用Java写一个HTTP发送以及接收响应完整的过程时,首先我们应该创建我们服务的servlet,开启servlet后,创建请求,发送请求,接收响应。我们平常所用的Tomcat就相当于一个servlet。


很多细节都没写,后面慢慢完善吧!可能会有我理解不正确的地方,欢迎指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容

  • 经验:1.在网络端接收数据后写入本地时要用write(byte[],0,len),不要用write(byte[])...
    123yuan123阅读 352评论 0 2
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,099评论 18 139
  • 湛蓝的天空中飘着大团大团的云 聚了又散 一整夜淅淅沥沥的梅雨之后 又是一个晴天 清晨的阳光洒在爬山虎密布的墙壁上 ...
    步宁凝阅读 258评论 3 7
  • 《望江南·初秋》 钟声晚,众芳欲语迟。寒蝉处处夕阳血,残琴铮铮红上烟。同送子规声。 《望江南·中秋》 登霄汉,长歌...
    生活恋情阅读 349评论 1 0
  • Can't locate API module structure `php5_module' http://wi...
    宁静世界阅读 859评论 0 0