导航:首页 > 编程语言 > 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相关的资料

热点内容
如何用电脑设置校时服务器 浏览:558
安卓什么软件可以换铃声 浏览:562
如何解决解压馆的劣势 浏览:320
plc编程模块化 浏览:245
单片机寄存器地址 浏览:396
七猫免费小说缓存加密 浏览:29
天津保税仓有溯源码 浏览:332
安卓9开发版什么时候推送 浏览:61
程序员可以天天加班吗 浏览:499
垃圾压缩车品牌 浏览:555
自制搜索引擎pdf 浏览:76
触漫安卓手机怎么登苹果的号 浏览:320
银行app怎么收信用卡的钱 浏览:288
java十进制转十六进制算法 浏览:920
pos刷卡需要app认证怎么弄 浏览:252
快速配IP命令 浏览:829
小程序后台源码导入 浏览:920
苹果手机app上的未读怎么取消 浏览:514
蜻蜓fm导出文件夹 浏览:514
我的世界怎么弄人家的服务器 浏览:361