Http Basic Authentication 新手版

先讲原理:

通俗的讲,登录一个需要basic authentication 的url,首次需要账号和密码,然后才能进入,不是首次的一段时间内,不需要密码也可以进入了。

那么用Http 机制来讲的话就是,首先发送一个带有账号和密码的resquest,并且这个账号密码需要base64加密,发送给登录页,返回一个response和cookie,然后用这个cookie直接去做登录。还有其他方法,但是我用这种方法。


注意几个地方:

1是用post还是用get方法发请求。

2不同jar包不要混用

3和看到的登录情况不一样,我这个是先找登录页面去做一次登录,返回来的去其他的url取数据,区分登录页面和真实内容的url,不是同一个url。

4jar包都是org.apche.http开头的

		
			org.apache.httpcomponents
			httpclient
			4.5.1
		


import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

public class XOIAccess {
	private String loginUrl;
	private String userName;
	private String password;

	private String authCookie;

	private Date authCookieExpired = null;

	public XOIAccess(String loginUrl, String username, String password) {
		this.loginUrl = loginUrl;
		this.userName = username;
		this.password = password;
	}

	public void doLogin() throws Exception {
		if (!isExpired())
			return;
		//首先加密 还有基于另外jar包的加密,是一个basic64加密
		CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
		credentialsProvider.setCredentials(AuthScope.ANY,
				new UsernamePasswordCredentials(this.userName, this.password));
		//把加密账号密码加载到httClient里 
		CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultCredentialsProvider(credentialsProvider)
				.build();
		
		//给登录页发送请求 这里头有账号密码的 
		HttpGet httpGet = new HttpGet(this.loginUrl);
		HttpResponse response = httpClient.execute(httpGet);
		//这时候response就是有要拿到的内容,可对response各种操作,这里用的是org.apache.http.HttpResponse;
		//那么其实这一步我是拿http头cookie,这个头的name就是"Set-Cookie",还有其他头,命名都是固定的。
		Header cookieHeader = response.getFirstHeader("Set-Cookie");
		if (cookieHeader != null) {
			this.authCookie = cookieHeader.getValue();
			//这些是对cookie的时间进行一个操作,保存时间,下次进页面的时候用来判断
			int start = this.authCookie.indexOf("expires=");
			if (start >= 0) {
				String expires = this.authCookie.substring(start);
				start = expires.indexOf("=");
				int end = expires.indexOf(";");
				if (start >= 0 && end > 0 && end > start + 1) {
					expires = expires.substring(start + 1, end).trim();
					DateFormat df = new SimpleDateFormat("E, dd-MMM-yyyy HH:mm:ss z");
					this.authCookieExpired = df.parse(expires);
				}
			}
			if (this.authCookieExpired == null) {
				throw new Exception("invalid auth cookie:" + this.authCookie);
			}
		} else {
			throw new Exception("Login exception. LoginUrl:" + this.loginUrl + ",username:" + this.userName);
		}
	}

	public String getXmlData(String url) throws Exception {
		doLogin();
		//CloseableHttpClient Httpclient 是一样的,有点区别
		CloseableHttpClient httpclient = HttpClientBuilder.create().build();
		//这次把cookie加入头发送出去
		//setHeader 和 addHeader 有区别,因为不用名下的Header是一个数组,set是重置,add是往后头添加
		HttpGet httpget = new HttpGet(url);
		httpget.setHeader("Cookie", this.authCookie);
		try {
			HttpResponse response = httpclient.execute(httpget);
			//这里获取下编码格式
			String encoding = "utf-8";
			Header encodingHeader = response.getFirstHeader("Content-Encoding");
			if(encodingHeader!=null){
				encoding = encodingHeader.getValue();
			}
			//把刚才的格式取出来,转化成一个string
			String xml = EntityUtils.toString(response.getEntity(),encoding);
			
			Header errorCodeHeader = response.getFirstHeader("X-XOI-ErrorCode");
			if(errorCodeHeader!=null){
				String errorCode = errorCodeHeader.getValue();
				if(errorCode.trim()!="40401"){
					throw new Exception("Fail to get data. url:" + url +",error: \n" + xml);
				}else{
					return "";
				}
			}
		
			return xml;
		} finally {
			httpget.releaseConnection();
		}
	}

	private Boolean isExpired() throws Exception {
		//这里是判断当前时间是否过期
		if (this.authCookieExpired == null)
			return true;
		Calendar utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("GTM"));
		utcCalendar.set(Calendar.MINUTE, 5);
		Date utcNow = utcCalendar.getTime();
		if (this.authCookieExpired.after(utcNow))
			return false;

		return true;
	}

	public static void main(String[] args) throws Exception {
		String urlLogin ="";
		String urlContent = "";
		String username = "";
		String password = "";
		XOIAccess xoiAccess = new XOIAccess(urlLogin,username, password);  //构造
		
		String data = xoiAccess.getXmlData(urlContent);  //调用getdata方法 里头会有调用dologin方法
		System.out.println("data:\n" + data);
		
	}
}		
 
  
 
  
 
  
 
  
 
  
 
  


//这里是判断当前时间是否过期

你可能感兴趣的:(JAVA)