本来有点不太想写这篇文章,原因是写了这个,就感觉WEB应用怎么都可以自己写代码访问内部的资源信息!不过出于技术本身的我还是考虑些点点东西,而且即使我不写,这玩意也有,呵呵,前面一篇文章我提及到双方要约定token来进行认证交互等等,如果你想访问某个网站内部的资源,而且是需要登录的,但是又想通过本地程序直接蹦进去,怎么蹦呢?
办法不是没有,其实httpclient就是模拟一个浏览器的功能,而登录的动作其实就是获取到你的cookie,而httpclient本身有记录cookie的功能,所以这并不难。
也就是说,你要用httpclient来模拟一个网站的登录,然后后续的操作;那么你只需要到那个网站的登录页面中找到用户名和密码的标签的name值,以及其action的目标地址,将其在本地开始进行模拟,标签,并类似于上一篇文章中编写用户名和密码并向action的目标地址发起的post操作(注意这里的POST应该是绝对路径,而不是页面看到的相对路径),此时你就能获取到你的cookie了;
那么登录OK了,cookie获取到了,如何保存cookie呢?其实你根本不用保存,因为httpclient已经帮你保存了,接下来所有的动作,只需要你使用同一个httpclient对象,它们的cookie就是一致的,可以通过同一个httpclient对象发起多次POST或GET请求,这个时候内部想要请求什么就请求什么了。
貌似本文就结束了,要这么简单,我也不会专门抽出来写了,其实上述方法只能适合于一般的普通网站,如果网站的认证方法是https的,也就是你看到它的登录界面是https开头的,那就不行了因为协议不一样了,不过也是有办法的,这也是本文需要阐述的重点,要做这个工作,httpcleint请换成4以上的版本,对应到的包有:commons-httpclient-4.1.3.jar以及httpclient-4.1.2.jar两个包不是一样的内容,在这里这两个包都需要(注意一下代码为非U盾认证方式,U盾认证需要其他的代码来支持)。
加上了这两个包后,在程序开始部分import的内容应该包含:
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
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.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
如果你有什么包引入不进来,说明你找的包还不对。
public class HttpsTest1 {
/**
* SSL部分的处理
* @param httpClient
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
private static void securityProcess(DefaultHttpClient httpClient)
throws NoSuchAlgorithmException, KeyManagementException {
TrustManager easyTrustManager = new X509TrustManager() {
public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException {}
public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException {}
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
};
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, new TrustManager[]{easyTrustManager}, null);
SSLSocketFactory sf = new SSLSocketFactory(sslcontext);
Scheme sch = new Scheme("https", 443, sf);
httpClient.getConnectionManager().getSchemeRegistry().register(sch);
}
/**
* 处理登录
* @param httpClient
* @throws UnsupportedEncodingException
* @throws IOException
* @throws ClientProtocolException
*/
private static void login(DefaultHttpClient httpClient)
throws UnsupportedEncodingException, IOException,ClientProtocolException {
HttpPost httppost = new HttpPost("https://www.xxx.xxx.com/login/");//这是用户名和密码提交的目标路径
List<NameValuePair> params=new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("id",MyUserInfo.USER_NAME));//写入用户名
params.add(new BasicNameValuePair("pass_word",MyUserInfo.PASSWORD));//写入密码
httppost.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8));
HttpResponse response = httpClient.execute(httppost);
HttpEntity entity = response.getEntity();
String content = EntityUtils.toString(entity);
System.out.println(content);
}
public static void main(String[] args) throws Exception {
DefaultHttpClient httpClient = new DefaultHttpClient();
try {
securityProcess(httpClient);
login(httpClient);
//以下是你要请求其他的URL
HttpGet get = new HttpGet("http://www.xxx.xxx.com/xxx/xxx");
HttpResponse response2 = httpClient.execute(get);
System.out.println(EntityUtils.toString(response2.getEntity()));
}finally {
httpClient.getConnectionManager().shutdown();
}
}
}
OK。代码细节上我不想多说,不过这段代码去请求一个https的登录是绝对没有问题的,可以将相应的URL换成自己系统的,再试一试!虽然是这个功能,不过,我个人还是不建议这样做,这样做太张扬了,这里仅仅为简单探讨下,可以用它写点程序实现远程系统的本地自动化处理步骤。
另外验证码需要一些解析程序,相对较为复杂,而且可能解析会有问题,对这类问题我也不想研究太多,呵呵,本文说提及的这个程序也和验证码无关。