日志分类:Java

HttpClient4.0对cookie的操作

2010年03月21日 9:31 下午  |  分类:Java
手机WAP中间件项目中一直存在一个问题是:如何使用虚拟浏览器模拟成多个客户端对网站进行操作。尤其是,面对需要用户登录才能访问的网站,虚拟浏览器如何能在用户第一次登录后,记住不同用户的cookie,进行后续取得权限的模拟操作,而不会每次操作都要登录并保证用户访问自己的页面。


还好通过google的帮助,发现Apache下的开源项目HttpClient可以很好的解决这个问题。周末学习了两天,并结合项目需求,自己动手写了个小实例。解决了虚拟浏览器中模拟form表单请求抓取用户登陆后sendRedirect页面内容以及保存cookie三个问题。关于如何模拟成多个浏览器进行登录,我现在初步打算为:保存每一个手机端登录的cookie,然后当手机端再次调用虚拟浏览器时,能够取出cookie封装到HttpClient实例中进行提交。不罗嗦,下面是实例的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package ouc.sei.common;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
 
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
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.params.CookiePolicy;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HTTP;
 
import com.sun.net.httpserver.HttpContext;
 
/**
 * 类封装了虚拟浏览器的一些基本操作
 * @author qsw-Myonlystar
 * 
 */
public class ClientOperate {
 
	/**
	 * 处理一个实体
	 * 
	 * @param entity
	 */
	public StringBuffer processEntity(HttpEntity entity,String encodType) {
		StringBuffer sb = new StringBuffer();
		InputStreamReader iReader = null;
		try {
			// 从消息实体中获取输入流对象
			InputStream inputStream = entity.getContent();
			iReader = new InputStreamReader(inputStream,encodType);
			BufferedReader reader = new BufferedReader(iReader);
			String line = null;
			// 用reader.ready()是不行的,这是用来判断此流是否已准备好被读取
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\r\n");
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				iReader.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return sb;
 
	}
 
	/**
	 * 判断服务器页面是否重定向
	 * 
	 * @param statuscode
	 *            response中的状态码
	 * @return
	 */
	public static boolean ifRedirect(int statusCode) {
		boolean flag = false;
		if ((statusCode == HttpStatus.SC_MOVED_PERMANENTLY)
				|| (statusCode == HttpStatus.SC_MOVED_TEMPORARILY)
				|| (statusCode == HttpStatus.SC_SEE_OTHER)
				|| (statusCode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
			flag = true;
		}
 
		return flag;
	}
	/**
	 * 打印服务器返回的状态
	 * @param response
	 */
	public void printResponseStatus(HttpResponse response){
		System.out.println("-----------服务器返回状态------------------------");
		System.out.println(response.getStatusLine()); // 服务器返回状态
		System.out.println("-----------服务器返回状态------------------------");
	}
	/**
	 * 打印返回的头部信息
	 * @param response
	 */
	public void printAllHeaders(HttpResponse response){
 
		System.out.println("-----------返回的HTTP头信息------------------------");
		Header[] headers = response.getAllHeaders(); // 返回的HTTP头信息
		for (int i = 0; i < headers.length; i++) {
			System.out.println(headers[i]);
 
		}
		System.out.println("-------------返回的HTTP头信息----------------");	
	}
	/**
	 * 打印cookie信息
	 * @param httpclient
	 */
	public void printCookie(DefaultHttpClient httpclient){
		 System.out.println("Initial set of cookies:");  
	        List<Cookie> cookies = httpclient.getCookieStore().getCookies();  
	        if (cookies.isEmpty()) {  
	            System.out.println("None");  
	        } else {  
	            for (int i = 0; i < cookies.size(); i++) {  
	                System.out.println("- " + cookies.get(i).toString());  
	            }  
	        } 
 
	}
 
}
?Download Test.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package ouc.sei.common;
 
import java.util.ArrayList;
import java.util.List;
 
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
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.params.CookiePolicy;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HTTP;
/**
 * 类作用是测试虚拟浏览器保存cookie值,并抓取跳转后的页面源码。
 * @author qsw-Myonlystar 
 *
 */
public class Test {
	/**
	 * @param args
	 * @throws Exception
	 */
	public final static void main(String[] args) throws Exception {
		HttpGet httpget = null;
		CookieStore cookieStore=null;
		ClientOperate oper=new ClientOperate();
		DefaultHttpClient httpclient = new DefaultHttpClient();
		// 设置cookie的兼容性,这一行必须要加,否则服务器无法获取登陆状态
		HttpClientParams.setCookiePolicy(httpclient.getParams(),
				CookiePolicy.BROWSER_COMPATIBILITY);
 
		HttpPost httpost = new HttpPost("http://222.195.150.224:8080/SEI/login.jsp");	
		// 设置参数的集合
		List<NameValuePair> nvps = new ArrayList<NameValuePair>();
		// 设置参数,格式是name:value
		nvps.add(new BasicNameValuePair("username", "kelly"));
		nvps.add(new BasicNameValuePair("password", "*****"));
 
		// 对参数实体进行格式转换
		UrlEncodedFormEntity urlEntity = new UrlEncodedFormEntity(nvps,
				HTTP.UTF_8);
		// 设置实体
		httpost.setEntity(urlEntity);
		HttpResponse response = httpclient.execute(httpost);
		//获取cookie
		cookieStore=httpclient.getCookieStore();
		BasicHttpContext localContext = new BasicHttpContext();
		localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
		//httpost.abort();
		oper.printAllHeaders(response);
		oper.printCookie(httpclient);
		oper.printResponseStatus(response);
		// httpclient = new DefaultHttpClient();
		String newUrl = response.getLastHeader("Location").getValue();
		System.out.println("转向的页面是:"+newUrl);
		httpclient = new DefaultHttpClient();
		httpget = new HttpGet(newUrl);
		HttpResponse responses = httpclient.execute(httpget,localContext);
		// 从响应中获取消息实体,如果有的话
		HttpEntity entity = responses.getEntity();
		// 处理消息实体中的内容
		try {
			StringBuffer sb = oper.processEntity(entity,"gbk");
			System.out.println(sb);
		} catch (RuntimeException ex) {
			// 终止执行请求
			httpost.abort();
			throw ex;
		}
		// 释放连接
		httpclient.getConnectionManager().shutdown();
	}
 
 
}

我使用的http版本是4.0,还需要引用的jar包为:commons-codec-1.4.jar commons-logging-1.1.1.jar httpcore-4.0.1.jar httpmime-4.0.1.jar。


PS:我今天终于知道了原来做一个外挂这么简单。

如何去除html代码中标签的属性

2010年03月10日 8:55 下午  |  分类:Java

项目的需要,正则表达式可以完成,只需要将<(\w*)\s[^>]*>替换为<$1>就可以了。

如何在eclipse中使用微软雅黑字体

2010年01月31日 8:51 下午  |  分类:Java
明天就要回家了,暂时离开这片我奋斗的战场。晚上把自己完成的一个数据结构跟sky交接了一下。闲暇之余,小师弟对我的eclipse里的字体很感兴趣,就给他捣鼓了一个,在这里也把怎样把微软雅黑字体添加的eclipse里的方法,贴出来,有兴趣的朋友可以看一下:


网上有很多适合编程者使用的等宽字体,我比较喜欢Consolas字体,它在vista和win7中是自带的,xp中需要安装相应的字体包,在eclipse中使用的方法如下:

(1).首先到微软官网上下载Consolas字体包(下载地址网上一搜一大把),然后复制到控制面板–>字体中。

(2).下载eclipse-code-highlight-consolas-fonts.epf。(下载地址同上)。

(3).启动eclipse,然后选择 File -> Import -> General -> Preferences 再选择下载好的.epf,按着提示一路下一步即可

(4).然后在eclipse工具栏中选择windows–>perferences–>General–>Appearance–>Colars and Fonts–>Basic–>Test Font,在字体中选择你安装的Consolas字体即可。

效果图如下:

微软雅黑

微软雅黑

java构造链表

2010年01月27日 9:23 下午  |  分类:Java
项目需求,需要自己构造链表。节点用来存储每个电话号码的相关信息。主链表用来串联不同的电话号码节点,如果接收到相同的电话号码,将它挂到主链表中相同节点的下方,同时后进入的位于主链表中。链表的构造如下图所示:

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 
package ouc.sei.LinkedList;
 
/**
 * @author qsw-Myonlystar 2010-1-27上午09:28:44
 * 类作用是定义节点类
 */
public class ListNode {
	String phoneNum;  //电话号码,主键 
	String data;
    ListNode right; //右节点
    ListNode left; //左节点
    ListNode sub; //子节点
 
    ListNode(String phoneNum) {
    	this(phoneNum,null,null,null,null);
    }  
 
    /**
     * 构造函数
     * @param phoneNum
     * @param left
     * @param right
     * @param sub
     */
    ListNode(String phoneNum,String data,ListNode right,ListNode left,ListNode sub) {  
        this.phoneNum=phoneNum;
    	this.data=data;
        this.right=right;
        this.left=left;
        this.sub=sub;
    }  
}

全文阅读 »

dom4j对xml的一些基本操作

2009年12月23日 8:13 下午  |  分类:Java, XML

一.Document对象相关

1.读取XML文件,获得document对象.

SAXReader reader = new SAXReader();
Document   document = reader.read(new File("input.xml"));

2.解析XML形式的文本,得到document对象.

String text = "";
Document document = DocumentHelper.parseText(text);

3.主动创建document对象.

Document document = DocumentHelper.createDocument();
Element root = document.addElement("members");// 创建根节点

全文阅读 »

Java创建线程池

2009年10月28日 8:03 下午  |  分类:Java

Telecom的项目马上就要进入压力测试的阶段了。根据Doctor Y的要求,把其中的监听线程修改为线程池。这样程序在初始化的时候就会创建一个大小为100容量的线程池,主程序负责socket监听,对于每一个socket请求,唤醒相应的线程进行处理,操作结束后,则释放线程,以备调用。
线程池部分程序分为两部分,一个是ThreadPoolManager.java专门负责线程池的初始化,以及对线程的调度。SimpleThread类专门负责线程相关的业务操作。这样我们在主程序中,就可以通过ThreadPoolManager对线程池进行管理,通过SimpleThread完成相关的业务操作。

线程的调度主要是通过wait()和notify()两个函数配套使用的,wait()使线程进入阻塞状态,notify()作用是唤醒相应线程,使其处于可执行的状态。
以下是两个类的相关的业务代码:

全文阅读 »

如何将大批量jar文件加入环境变量classpath中

2009年09月1日 9:01 上午  |  分类:Java

做java程序员,有时不可避免的要把大量的jar文件加入环境变量classpath中,比如,最近做的一个webservice项目,需要将axis2中lib下所有的jar文件加入环境变量中,如果手动一个一个加入,确实够麻烦,现在把方法简单总结下:

1、在运行中输入cmd,进入dos环境下,进入axis2/lib目录下,如:我的路径是:C:\axis2-1.4.1\lib

全文阅读 »

理解session

2009年07月25日 7:33 下午  |  分类:Java

Session["userID"]这条语句对做b/s的再简单不过,后台可以得到session中属性‘userid’的值,然后进行相关的操作。2009年7月25日晚上7点24分之前,我也从未对这条语句怀疑过,只是25分时,我突然发现了一个问题,对于几千个用户同时在线的b/s系统,session中用的都是userId,怎么不同的人会得到不同的信息,为什么我在session.setAttribute时,不会覆盖别人的。上网查了查,终于明白其中的含义,如下:

全文阅读 »

Pages: 1 2 3 Next