原文地址:http://www.cnblogs.com/kross/p/3615695.html

一直没弄懂Session,cookies什么的登陆验证到底是怎么回事,昨天分别用HttpURLConnection和HttpClient两个类来实验了一下,基本弄明白了Session验证登陆的机制和这两个类的区别。

第一步:先在本地写一个登陆页面和一个内容页面(登陆了才能进去)吧。代码大致如下:

下面是login.php,用于请求登陆的,通过post传递参数,如果登陆成功就会注册session。

 <?php
session_start(); if (isset($_POST['username'])) {
$username = $_POST['username'];
$password = $_POST['password']; if ($username == 'admin' && $password == 'admin') {
$_SESSION['username'] = $username;
echo "<a href='content.php'>进入网站</a>";
} else {
echo "-1";
}
}
?>
<html>
<body>
<form action="" method="post">
<input type="text" name="username" />
<input type="password" name="password" />
<input type="submit" name="submit" value="submit" />
</form>
</body>
</html>

下面是content.php,会验证session,用来当网站的内容页,登陆了才能看到正确的内容。

<?php
session_start();
if (isset($_SESSION['username'])) {
echo "login ok";
} else {
echo "not login";
}
?>

接下来先讲HttpURLConnection这个类,先使用这个类直接请求content.php页面,理所应当的返回了"-1"。如果先用这个类去请求login.php,并传递正确的参数,就会显示登陆成功,这个时候再去用这个类请求content.php,依然是返回"-1",很显然,HttpURLConnection并没有记录我们登陆的状态,或者说服务器认识刚刚登陆成功的人,但这次请求content.php的人它依然不认识。这就说明了HttpURLConnection的每一次请求都是独立的,都是一次新的请求,或者说每一次请求都是一个新的会话(session)。

然后我就用chrome去开我自己写的那个测试的网页,发现在同一个网站下,同一次会话中,有一个sessionid是不会变的。

就是上面这个东西,如果开着某个页面,无论如何刷新,或者跳转到这个服务器下的其他网站,这个SESSIONID的值都不会改变,但是如果关掉这个服务器下的所有页面,再重新打开这样的一个页面,这个SESSIONID的值就被重新生成了。

于是用HttpURLConnection的情况,第一次登陆login.php是一个SESSIONID,确实登陆成功了,服务器记住的是SESSIONID为A的情况(假设是A好了),但再去请求content.php的时候,SESSIONID就不是A了,服务器就认为你没有登陆,于是就显示了“-1”。问题搞明白了,那么只需要在HttpURLConnection请求的时候,给它加上SESSIONID这个头部就行了。最终代码如下:

public class NetHelper {

    /**
* SESSIONID
* */
private String sessionId = ""; /**
* 发送一条请求,将内容以字符串返回
* @param url 请求的地址
* @return 返回的内容
* */
public String request(String url) throws IOException {
URL uUrl = new URL(url);
HttpURLConnection huc = (HttpURLConnection) uUrl.openConnection();
huc.addRequestProperty("Cookie", sessionId); //为什么是“Cookie”,Chrome打开F12自己看看就明白了
huc.connect();
BufferedReader br = new BufferedReader(new InputStreamReader(huc.getInputStream()));
String data = "";
String line = "";
while ((line = br.readLine()) != null) {
data = data + line;
}
return data;
} /**
* 发送登陆请求,并将SESSIONID保存起来
* @param url 登陆请求的地址
* @return 返回的内容
* */
public String login(String url) throws IOException {
URL uUrl = new URL(url);
HttpURLConnection huc = (HttpURLConnection) uUrl.openConnection(); //设置请求方式
huc.setRequestMethod("POST"); //设置post参数
StringBuffer params = new StringBuffer();
params.append("username=").append("admin").append("&").append("password=").append("admin");
byte[] bytes = params.toString().getBytes();
huc.getOutputStream().write(bytes); huc.connect(); //从headers中取出来,并分割,为什么要分割,Chrome打开F12自己看看就明白了
String[] aaa = huc.getHeaderField("Set-Cookie").split(";");
sessionId = aaa[0]; BufferedReader br = new BufferedReader(new InputStreamReader(huc.getInputStream()));
String data = "";
String line = "";
while ((line = br.readLine()) != null) {
data = data + line;
}
return data;
}
}

接下来就是使用HttpClient,代码类似的,我做了相同的实验,结果就直接出来了,HttpClient会自动的管理Session,第二次请求不需要手动去设置Session就可以登录上。

public class NetClient {

    private HttpClient client = null; 

    public NetClient() {
client = new DefaultHttpClient();
} public String request(String url) throws ClientProtocolException, IOException {
HttpPost post = new HttpPost(url);
HttpResponse res = client.execute(post); BufferedReader br = new BufferedReader(new InputStreamReader(res.getEntity().getContent()));
String data = "";
String line = "";
while ((line = br.readLine()) != null) {
data = data + line;
}
return data;
} public String login(String url) throws ClientProtocolException, IOException {
HttpPost post = new HttpPost(url); //设置post参数的方式还真是不人性化啊……
ArrayList<NameValuePair> pa = new ArrayList<NameValuePair>();
pa.add( new BasicNameValuePair( "username", "admin"));
pa.add( new BasicNameValuePair( "password", "admin"));
post.setEntity( new UrlEncodedFormEntity(pa, "UTF-8")); HttpResponse res = client.execute(post); BufferedReader br = new BufferedReader(new InputStreamReader(res.getEntity().getContent()));
String data = "";
String line = "";
while ((line = br.readLine()) != null) {
data = data + line;
}
return data;
}
}

最后总结一下,Session验证的方式是在一次会话中,为每一个客户端都生成了一个SESSIONID,如果是成功登陆的,服务器端就会记录好,登陆成功的SESSIONID,如果登陆失败或者新的SESSIONID,都将无法验证登陆,这就是SESSION验证登陆的基本情况。

而HttpURLConnection和HttpClient这两个类都可以用来网络请求,但稍有不同,HttpuRLConnection每一次请求都是新的会话,如果需要去验证SESSIONID,就必须手动的去设置Header,HttpClient就能智能的管理Session,不需要手动设置,实际上HttpClint就类似于一个程序中的小浏览器。

最大的槽点我觉得就是这两个类设置post参数的方式都很2B一点都不方便……

另外HttpClient不能同时发送两次请求,如果一个请求还没有结束或者关闭,又马上开启另一个请求。就会报警告,截个图吧

所以我综合考虑了下,以后还是尽量都使用HttpURLConnection吧……

原文地址:http://www.cnblogs.com/kross/p/3615695.html

新浪微博:http://weibo.com/KrossFord

HttpURLConnection、HttpClient和Session的更多相关文章

  1. 大叔也说Xamarin~Android篇~为HttpClient共享Session,android与api的session共享机制

    回到目录 杂谈 在进行android进行开发时,我们的数据一般通过接口来获收,这里指的接口泛指web api,webservice,wcf,web应用程序等:它们做为服务端与数据库进行直接通讯,而AP ...

  2. [Android] HttpURLConnection & HttpClient & Socket

    Android的三种网络联接方式 1.标准Java接口:java.net.*提供相关的类//定义地址URL url = new URL("http://www.google.com" ...

  3. HttpURLConnection&HttpClient网络通信

    一:HttpURLConnection简介: 用于发送或者接受HTTP协议请求的类,获得的数据可以是任意类型和长度,这个类可以用于发送和接收流数据,其长度事先不知道. 使用这个类遵循一下模式: 获得一 ...

  4. OKHttp源码学习--HttpURLConnection HttpClient OKHttp Get and post Demo用法对比

    1.HttpURLConnection public class HttpURLConnectionGetAndPost { private String urlAddress = "xxx ...

  5. android httpUrlConnection HttpClient

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha httpUrlConnection    超文本传输协议统一资源定位器连接 http 超 ...

  6. httpClient 保持session

    import org.apache.commons.httpclient.Cookie; import org.apache.commons.httpclient.HttpClient; import ...

  7. crawler_基础之_java.net.HttpURLConnection 访问网络资源

    java访问网络资源 由底层到封装  为  scoket==> java.net.HttpURLConnection==>HttpClient 这次阐述先 java.net.HttpURL ...

  8. 框架--NoHttp和OkHttp哪个好用,Volley和NoHttp哪个好用?

    NoHttp和OkHttp哪个好用,Volley和NoHttp哪个好用? NoHttp 源码及Demo托管在Github欢迎大家Star: https://github.com/Y0LANDA/NoH ...

  9. Android网络请求心路历程

    HTTP请求&响应 既然说从入门级开始就说说Http请求包的结构.一次请求就是向目标服务器发送一串文本.什么样的文本?有下面结构的文本.HTTP请求包结构 例子: 1 2 3 4 5 6 7 ...

随机推荐

  1. 4710: [Jsoi2011]分特产

    4710: [Jsoi2011]分特产 链接 分析: 容斥原理+隔板法. 代码: #include<cstdio> #include<algorithm> #include&l ...

  2. 4008: [HNOI2015]亚瑟王

    4008: [HNOI2015]亚瑟王 链接 分析: 根据期望的线性性,直接求出每张牌出现的概率,最后乘以攻击力就是答案. 每张牌出现的概率只与它前面的牌有关,与后面的没有关系,于是按顺序考虑每张牌. ...

  3. Kubernetes学习之路(九)之kubernetes命令式快速创建应用

    1.使用命令kubectl run创建应用 语法: kubectl run NAME --image=image [--env="key=value"] [--port=port] ...

  4. Orz YYB!

    就是右边OrzYYB按钮的实现. 从这位dalao的博客蒯(mogai)的js代码. <script> function orzyyb(){ document.getElementById ...

  5. 关于selenium的智能等待页面加载的问题

    我们经常会碰到用selenium操作页面上某个元素的时候,需要等待页面加载完成后,才能操作, 否则页面上的元素不存在,会抛出异常. 或者碰到AJAX异步加载,我们需要等待元素加载完成后,才能操作. 首 ...

  6. centos安装及Xshell连接配置

    一.百度下载并安装VMware 二.下载centos 打开https://www.centos.org,点击“get centos now”,点击“DVD ISO”下载(也可以下滑点击“more do ...

  7. Unity优化方向——优化Unity游戏中的垃圾回收(译)

    介绍 当我们的游戏运行时,它使用内存来存储数据.当不再需要该数据时,存储该数据的内存将被释放,以便可以重用.垃圾是用来存储数据但不再使用的内存的术语.垃圾回收是该内存再次可用以进行重用的进程的名称. ...

  8. node安装和npm全局配置

    本文章环境 windows10 64位家庭版 Node10.15.3LTS 安装包下载 Node官网 安装node 点击安装文件, 一键安装, 注意安装位置和添加到环境变量(xx to PATH)选项 ...

  9. C语言学习之路之基础变量

    Hello,大家好,今天又和大家见面了!前两天,我看到了几款游戏引擎渲染效果的对比的视频,https://www.bilibili.com/video/av5113296?from=search&am ...

  10. CentOS7上部署ASP.Net Core 2.2应用

    前言 在CentOS7上部署ASP.Net Core应用是我的技术路线验证的一部分,下一个产品计划采用ASP.Net Boilerplate Framework开发.因此需要求提前进行一下技术验证,在 ...