導航:首頁 > 編程語言 > java編碼http

java編碼http

發布時間:2024-08-28 15:17:29

① 北大青鳥java培訓:http協議請求處理過程

隨著互聯網的不斷發展,用戶在訪問互聯網的時候使用的終端設備類型也在不斷的變化,但是這些都是基於http協議來實現的,下面我們就簡單分析一下,http發送請求的處理過程。
HTTP協議是基於TCP協議的,所以它使用面向連接的方式發送請求,通過stream二進制流的方式傳給對方。
當然,到了TCP層,它會把二進制流變成一個的報文段發送給伺服器。
在發送給每個報文段的時候,都需要對方有一個回應ACK,來保證報文可靠地到達了對方。
如果沒有回應,那麼TCP這一層會進行重新傳輸,直到可以到達。
同一個包有可能被傳了好多次,但是HTTP這一層不需要知道這一點,因為是TCP這一層在埋頭苦幹。
TCP層發送每一個報文的時候,都需要加上自己的地址(即源地址)和它想要去的地方(即目標地址),將這兩個信息放到IP頭裡面,交給IP層進行傳輸。
IP層需要查看目標地址和自己是否是在同一個區域網。
如果是,就發送ARP協議來請求這個目標地址對應的MAC地址,然後將源MAC和目標MAC放入MAC頭,發送出去即可。
如果不在同一個區域網,就需要發送到網關,還要需要發送ARP協議,來獲取網關的MAC地址,然後將源MAC和網關MAC放入MAC頭,發送出去。
網關收到包發現MAC符合,取出目標IP地址,根據路由協議找到下一跳的路由器,獲取下一跳路由器的MAC地址,將包發給下一跳路由器。
這樣路由器一跳一跳終於到達目標的區域網。
這個時候,後一跳的路由器能夠發現,目標地址就在自己的某一個出口的區域網上。
於是,在這個區域網上發送ARP,獲得這個目標地址的MAC地址,將包發出去。
目標的機器發現MAC地址符合,就將包收起來;發現IP地址符合,根據IP頭中協議項,知道自己上一層是TCP協議,於是解析TCP的頭,裡面有序列號,IT培訓http://www.kmbdqn.cn/建議需要看一看這個序列包是不是我要的,如果是就放入緩存中然後返回一個ACK,如果不是就丟棄。
TCP頭裡面還有埠號,HTTP的伺服器正在監聽這個埠號。
於是,目標機器自然知道是HTTP伺服器這個進程想要這個包,於是將包發給HTTP伺服器。
HTTP伺服器的進程看到,原來這個請求是要訪問一個網頁,於是就把這個網頁發給客戶端。

② 如何在java中發起http和https請求

1.寫http請求方法
[java] view plain

//處理http請求 requestUrl為請求地址 requestMethod請求方式,值為"GET"或"POST"
public static String httpRequest(String requestUrl,String requestMethod,String outputStr){
StringBuffer buffer=null;
try{
URL url=new URL(requestUrl);
HttpURLConnection conn=(HttpURLConnection)url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod(requestMethod);
conn.connect();
//往伺服器端寫內容 也就是發起http請求需要帶的參數
if(null!=outputStr){
OutputStream os=conn.getOutputStream();
os.write(outputStr.getBytes("utf-8"));
os.close();
}
//讀取伺服器端返回的內容
InputStream is=conn.getInputStream();
InputStreamReader isr=new InputStreamReader(is,"utf-8");
BufferedReader br=new BufferedReader(isr);
buffer=new StringBuffer();
String line=null;
while((line=br.readLine())!=null){
buffer.append(line);
}
}catch(Exception e){
e.printStackTrace();
}
return buffer.toString();
}
2.測試。
[java] view plain

public static void main(String[] args){
String s=httpRequest("http://www.qq.com","GET",null);
System.out.println(s);
}
輸出結果為www.qq.com的源代碼,說明請求成功。
註:1).第一個參數url需要寫全地址,即前邊的http必須寫上,不能只寫www.qq.com這樣的。

2).第二個參數是請求方式,一般介面調用會給出URL和請求方式說明。
3).第三個參數是我們在發起請求的時候傳遞參數到所要請求的伺服器,要傳遞的參數也要看介面文檔確定格式,一般是封裝成json或xml.
4).返回內容是String類,但是一般是有格式的json或者xml。
二:發起https請求。
1.https是對鏈接加了安全證書SSL的,如果伺服器中沒有相關鏈接的SSL證書,它就不能夠信任那個鏈接,也就不會訪問到了。所以我們第一步是自定義一個信任管理器。自要實現自帶的X509TrustManager介面就可以了。
[java] view plain

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
public class MyX509TrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
}
註:1)需要的包都是java自帶的,所以不用引入額外的包。
2.)可以看到裡面的方法都是空的,當方法為空是默認為所有的鏈接都為安全,也就是所有的鏈接都能夠訪問到。當然這樣有一定的安全風險,可以根據實際需要寫入內容。

2.編寫https請求方法。
[java] view plain

/*
* 處理https GET/POST請求
* 請求地址、請求方法、參數
* */
public static String httpsRequest(String requestUrl,String requestMethod,String outputStr){
StringBuffer buffer=null;
try{
//創建SSLContext
SSLContext sslContext=SSLContext.getInstance("SSL");
TrustManager[] tm={new MyX509TrustManager()};
//初始化
sslContext.init(null, tm, new java.security.SecureRandom());;
//獲取SSLSocketFactory對象
SSLSocketFactory ssf=sslContext.getSocketFactory();
URL url=new URL(requestUrl);
HttpsURLConnection conn=(HttpsURLConnection)url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestMethod(requestMethod);
//設置當前實例使用的SSLSoctetFactory
conn.setSSLSocketFactory(ssf);
conn.connect();
//往伺服器端寫內容
if(null!=outputStr){
OutputStream os=conn.getOutputStream();
os.write(outputStr.getBytes("utf-8"));
os.close();
}
//讀取伺服器端返回的內容
InputStream is=conn.getInputStream();
InputStreamReader isr=new InputStreamReader(is,"utf-8");
BufferedReader br=new BufferedReader(isr);
buffer=new StringBuffer();
String line=null;
while((line=br.readLine())!=null){
buffer.append(line);
}
}catch(Exception e){
e.printStackTrace();
}
return buffer.toString();
}
可見和http訪問的方法類似,只是多了SSL的相關處理。
3.測試。先用http請求的方法訪問,再用https的請求方法訪問,進行對比。

http訪問:
[java] view plain

public static void main(String[] args){
String s=httpRequest("https://kyfw.12306.cn/","GET",null);
System.out.println(s);
}
結果為:

https訪問:

[java] view plain

public static void main(String[] args){
String s=httpsRequest("https://kyfw.12306.cn/","GET",null);
System.out.println(s);
}
結果為:

可見https的鏈接一定要進行SSL的驗證或者過濾之後才能夠訪問。

三:https的另一種訪問方式——導入服務端的安全證書。
1.下載需要訪問的鏈接所需要的安全證書。https://kyfw.12306.cn/ 以這個網址為例。
1)在瀏覽器上訪問https://kyfw.12306.cn/。

2)點擊上圖的那個打了×的鎖查看證書。

3)選擇復制到文件進行導出,我們把它導入到java項目所使用的jre的lib文件下的security文件夾中去,我的是這個路徑。D:\Program Files (x86)\Java\jre8\lib\security

註:中間需要選導出格式,就選默認的就行,還需要命名,我命名的是12306.

2.打開cmd,進入到java項目所使用的jre的lib文件下的security目錄。
3.在命令行輸入 Keytool -import -alias 12306 -file 12306.cer -keystore cacerts
4.回車後會讓輸入口令,一般默認是changeit,輸入時不顯示,輸入完直接按回車,會讓確認是否信任該證書,輸入y,就會提示導入成功。

5.導入成功後就能像請求http一樣請求https了。

測試:
[java] view plain

public static void main(String[] args){
String s=httpRequest("https://kyfw.12306.cn/","GET",null);
System.out.println(s);
}
結果:
現在就可以用http的方法請求https了。
註:有時候這一步還是會出錯,那可能是jre的版本不對,我們右鍵run as——run configurations,選擇證書所在的jre之後再運行。

③ java的HTTP請求:返回的響應為亂碼,轉碼根本不起作用,請看下面代碼。跪求高手解答!

// 定義BufferedReader輸入流來讀取URL響應
in = new BufferedReader(new InputStreamReader(conn.getInputStream(),「UTF-8」));

④ javacurlhttp請求時間細節,怎麼實現

以下代碼是Java實現Http的Post、Get、代理訪問請求,可以參考一下

packagecom.snowfigure.kits.net;

importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.InputStreamReader;
importjava.io.OutputStreamWriter;
importjava.io.UnsupportedEncodingException;
importjava.net.HttpURLConnection;
importjava.net.InetSocketAddress;
importjava.net.Proxy;
importjava.net.URL;
importjava.net.URLConnection;
importjava.util.List;
importjava.util.Map;

/**
*Http請求工具類
*@authorsnowfigure
*@since2014-8-2413:30:56
*@versionv1.0.1
*/
publicclassHttpRequestUtil{
staticbooleanproxySet=false;
staticStringproxyHost="127.0.0.1";
staticintproxyPort=8087;
/**
*編碼
*@paramsource
*@return
*/
publicstaticStringurlEncode(Stringsource,Stringencode){
Stringresult=source;
try{
result=java.net.URLEncoder.encode(source,encode);
}catch(UnsupportedEncodingExceptione){
e.printStackTrace();
return"0";
}
returnresult;
}
(Stringsource){
Stringresult=source;
try{
result=java.net.URLEncoder.encode(source,"GBK");
}catch(UnsupportedEncodingExceptione){
e.printStackTrace();
return"0";
}
returnresult;
}
/**
*發起http請求獲取返回結果
*@paramreq_url請求地址
*@return
*/
publicstaticStringhttpRequest(Stringreq_url){
StringBufferbuffer=newStringBuffer();
try{
URLurl=newURL(req_url);
HttpURLConnectionhttpUrlConn=(HttpURLConnection)url.openConnection();

httpUrlConn.setDoOutput(false);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);

httpUrlConn.setRequestMethod("GET");
httpUrlConn.connect();

//將返回的輸入流轉換成字元串
InputStreaminputStream=httpUrlConn.getInputStream();
=newInputStreamReader(inputStream,"utf-8");
BufferedReaderbufferedReader=newBufferedReader(inputStreamReader);

Stringstr=null;
while((str=bufferedReader.readLine())!=null){
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
//釋放資源
inputStream.close();
inputStream=null;
httpUrlConn.disconnect();

}catch(Exceptione){
System.out.println(e.getStackTrace());
}
returnbuffer.toString();
}

/**
*發送http請求取得返回的輸入流
*@paramrequestUrl請求地址
*@returnInputStream
*/
(StringrequestUrl){
InputStreaminputStream=null;
try{
URLurl=newURL(requestUrl);
HttpURLConnectionhttpUrlConn=(HttpURLConnection)url.openConnection();
httpUrlConn.setDoInput(true);
httpUrlConn.setRequestMethod("GET");
httpUrlConn.connect();
//獲得返回的輸入流
inputStream=httpUrlConn.getInputStream();
}catch(Exceptione){
e.printStackTrace();
}
returninputStream;
}


/**
*向指定URL發送GET方法的請求
*
*@paramurl
*發送請求的URL
*@paramparam
*請求參數,請求參數應該是name1=value1&name2=value2的形式。
*@returnURL所代表遠程資源的響應結果
*/
publicstaticStringsendGet(Stringurl,Stringparam){
Stringresult="";
BufferedReaderin=null;
try{
StringurlNameString=url+"?"+param;
URLrealUrl=newURL(urlNameString);
//打開和URL之間的連接
URLConnectionconnection=realUrl.openConnection();
//設置通用的請求屬性
connection.setRequestProperty("accept","*/*");
connection.setRequestProperty("connection","Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1)");
//建立實際的連接
connection.connect();
//獲取所有響應頭欄位
Map<String,List<String>>map=connection.getHeaderFields();
//遍歷所有的響應頭欄位
for(Stringkey:map.keySet()){
System.out.println(key+"--->"+map.get(key));
}
//定義BufferedReader輸入流來讀取URL的響應
in=newBufferedReader(newInputStreamReader(
connection.getInputStream()));
Stringline;
while((line=in.readLine())!=null){
result+=line;
}
}catch(Exceptione){
System.out.println("發送GET請求出現異常!"+e);
e.printStackTrace();
}
//使用finally塊來關閉輸入流
finally{
try{
if(in!=null){
in.close();
}
}catch(Exceptione2){
e2.printStackTrace();
}
}
returnresult;
}

/**
*向指定URL發送POST方法的請求
*
*@paramurl
*發送請求的URL
*@paramparam
*請求參數,請求參數應該是name1=value1&name2=value2的形式。
*@paramisproxy
*是否使用代理模式
*@return所代表遠程資源的響應結果
*/
publicstaticStringsendPost(Stringurl,Stringparam,booleanisproxy){
OutputStreamWriterout=null;
BufferedReaderin=null;
Stringresult="";
try{
URLrealUrl=newURL(url);
HttpURLConnectionconn=null;
if(isproxy){//使用代理模式
@SuppressWarnings("static-access")
Proxyproxy=newProxy(Proxy.Type.DIRECT.HTTP,newInetSocketAddress(proxyHost,proxyPort));
conn=(HttpURLConnection)realUrl.openConnection(proxy);
}else{
conn=(HttpURLConnection)realUrl.openConnection();
}
//打開和URL之間的連接

//發送POST請求必須設置如下兩行
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");//POST方法


//設置通用的請求屬性

conn.setRequestProperty("accept","*/*");
conn.setRequestProperty("connection","Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1)");
conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");

conn.connect();

//獲取URLConnection對象對應的輸出流
out=newOutputStreamWriter(conn.getOutputStream(),"UTF-8");
//發送請求參數
out.write(param);
//flush輸出流的緩沖
out.flush();
//定義BufferedReader輸入流來讀取URL的響應
in=newBufferedReader(
newInputStreamReader(conn.getInputStream()));
Stringline;
while((line=in.readLine())!=null){
result+=line;
}
}catch(Exceptione){
System.out.println("發送POST請求出現異常!"+e);
e.printStackTrace();
}
//使用finally塊來關閉輸出流、輸入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOExceptionex){
ex.printStackTrace();
}
}
returnresult;
}

publicstaticvoidmain(String[]args){
//demo:代理訪問
Stringurl="http://api.adf.ly/api.php";
Stringpara="key=youkeyid&youuid=uid&advert_type=int&domain=adf.ly&url=http://somewebsite.com";

Stringsr=HttpRequestUtil.sendPost(url,para,true);
System.out.println(sr);
}

}

⑤ Java網路編程從入門到精通(23):HTTP消息頭欄位

專題推薦 網路編程 基礎到進階教程

一 通用頭欄位

Connection

這個欄位只在HTTP 協議中存在 它決定了客戶端和伺服器進行了一次會話後 伺服器是否立即關閉網路連接 在客戶端最直接的表現是使用read方法(readLine方法也是一樣)讀完客戶端請求的Web資源後 是否立即返回 (readLine返回null) Connection有兩個值 Close和Keep Alive 當使用Connection Close時 和HTTP 協議是一樣的 當read方法讀完數據時立即返回 而使用Connection Keep Alive時 read方法在讀完數據後還要爛局被阻塞一段時間 直接讀取數據超時時間過後 還繼續往下執行 在上一篇文章中討論的readHttpResponse(……)方法實現的第 行可以驗證Connection的作用 下面讓我們來使用HTTP模擬器來做一個實驗

( )在HTTP模擬器中輸入如下的域名

( )HTTP模擬器中輸入如下的HTTP請求信息

GET/HTTP/ 孫喚Host:

( )按兩下回車(輸入一個空行)後 發送請求消息 並得到如圖 如示的HTTP響應消息頭

( )輸入y或Y後(在顯示響應頭後 要立刻輸入Y或y) 顯示響應消息的內容 在顯示完內容後 大約過了 秒鍾才進入 host port> 提示符(因為在sendHttpRequest()的實現代碼中的 行設置了讀取數據超時)

( )在 host port> 提示符下直接按回車 輸入最近一次使用的域名和 埠 再次輸入如下的HTTP請求

GET/HTTP/ Host: Connection:close

輸入完以上的HTTP請求後 重新執行第 步操作 最後在顯示HTTP響應消息內容後 直接直入了 host port> 提示符 除了這種方法 將請求的第一行改為GET / HTTP/ 這樣也可以無需等待直接結束

通過設置Connection 可以在下載Web資源(如多線程下載工具 Web瀏覽器等)後 立即斷開網路連接 這樣可以有效地降低客戶機的資源消耗

Date

這個Date頭欄位描述了請求消息和響應消息被創建的時間 這個欄位值是一個HTTP date類型 它的格式必須是GMT(格林尼治)時間 GMT時間是就是北京時間減 小時 下面是Date欄位的一個例子

Date:Tue Nov : : GMT

Content Length

指定消息實體的則歷凱位元組數 在請求消息中POST方法必須使用Content Length來指定請求消息的實體內容的位元組數 在響應消息中這個欄位值指定了當前HTTP響應所返回的Web資源的位元組數

二 HTTP請求消息頭欄位

Host

Host欄位用於指定客戶端所訪問的資源所在的主機名和埠號 如果埠號等於連接伺服器時所使用的埠號 則埠號可以省略 下面是一個使用Host欄位的一個例子

Host:

這個欄位是必須的 如果HTTP請求不包含這個欄位 伺服器將返回 (Bad Request)響應狀態

Accept

Accept欄位頭確定客戶端可以接收的媒體類型 一般的格式是 */* 或 類型/ 子類型 這個子段頭可以傳遞多個媒體類型 中間用 隔開 如下面是一個Accept的例子

Accept: image/gif image/jpg

如果請求頭使用上述的Accept欄位值 則伺服器端在動態生成網頁的IMG頭時將首先包含gif格式的圖像 如果gif圖象不存在 則包含jpg格式的圖象

User Agent

這個欄位頭用於指定客戶端是用什麼訪問的伺服器 如果是IE 瀏覽器 並且本機安裝了 net 則User Agent會有如下的值

User Agent:Mozilla/ (patible;MSIE ;WindowsNT ;SV ;Maxthon; NETCLR ; NETCLR ;InfoPath ;InfoPath )

伺服器可以通過這個欄位檢查客戶機的瀏覽器版本 並根據不同的版本來確定向客戶端發送的數據

Range

Range欄位頭通過伺服器只傳輸一部分Web資源 這個欄位頭可以用來實現斷點續傳功能 有很多下載工具就是通過這個欄位頭進行斷點續傳的 Range欄位可以通過三種格式設置要傳輸的位元組范圍

( )Range bytes=

傳輸范圍從 到 位元組

( )Range bytes=

傳輸Web資源中第 個位元組以後的所有內容

( )Range bytes=

傳輸最後 個位元組

三 HTTP響應消息頭欄位

Accept Ranges

這個欄位說明Web伺服器是否支持Range(是否支持斷點續傳功能) 如果支持 則返回Accept Ranges bytes 如果不支持 則返回Accept Ranges none

Content Range

指定了返回的Web資源的位元組范圍 這個欄位值的格式是

開始位元組位置—結束位元組位置/Web資源的總位元組數

下面是一個使用Content Range的例子

Content Range /

測試

在HTTP模擬器中連接伺服器 並輸入如下的HTTP請求消息

GET /nokiaguy/HttpSimulator rar HTTP/ Host: Range:bytes=

返回的響應消息頭如圖 所示

從上圖可以看出 伺服器支持斷點繼傳功能 而且還可以驗證Content Length的值是當前會話傳過來的位元組數 並不是Web資源的總的位元組數 而Content Range欄位值中 / 後面的數才是Web資源總的位元組數

Location

lishixin/Article/program/Java/hx/201311/27047

閱讀全文

與java編碼http相關的資料

熱點內容
linux命令強制退出 瀏覽:77
videostation怎麼添加文件夾 瀏覽:184
pythonrawsocket 瀏覽:861
編譯原理計算思維能力 瀏覽:247
衛星加密技術的應用 瀏覽:901
怎麼看手機實用頻率高的app 瀏覽:72
c實現sha1演算法 瀏覽:784
h200cy1是多大壓縮機 瀏覽:62
hbase查看錶結構命令 瀏覽:861
怎麼將rar解壓成安裝包 瀏覽:29
程序員幾點開始學習 瀏覽:201
linux百度雲文件 瀏覽:398
下載軟體解壓到哪裡合適 瀏覽:264
百度智能雲演算法工程師 瀏覽:98
模鍛造pdf 瀏覽:211
dom編程api 瀏覽:58
批處理復制命令 瀏覽:503
廢鐵壓縮打包機 瀏覽:98
linux打開圖形界面命令 瀏覽:368
女孩子學習程序員還是剪輯師好 瀏覽:284