httpclient模拟登陆成功后在浏览器中打开登陆后的页面
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了httpclient模拟登陆成功后在浏览器中打开登陆后的页面相关的知识,希望对你有一定的参考价值。
服务器使用httpclient模拟登陆网站(如:CSDN)成功后,如何在浏览器中打开一个新的窗口显示登陆后的页面,最好给出相应的代码
现在功能是页面上一个按钮,点击以后再服务器上使用httpclient模拟网站登陆,然后再在浏览器上弹出新窗口显示登陆后的页面,要求新打开的页面中带有登陆信息并能正常操作
这段是初始化webDriver模拟浏览器的代码
public void initWebDriver()
BrowserVersion version = null;
browserVersion = browserVersion.toLowerCase();
if (browserVersion.equals("ff") || browserVersion.equals("ff3.6"))
// firefox3_6类型
version = BrowserVersion.FIREFOX_3_6;
else if (browserVersion.equals("ie8"))
// ie8类型
version = BrowserVersion.INTERNET_EXPLORER_8;
else if (browserVersion.equals("default"))
// 默认类型,一般为ie8
version = BrowserVersion.getDefault();
else
// 不支持的浏览器模拟类型,统一采用默认浏览器类型
LOG.error("unsupported browser version,will use default version");
version = BrowserVersion.getDefault();
// 初始化webdriver
driver = new HtmlUnitDriver(enableJs, version);
// 设置webdriver的等待加载网站完成的时间
driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
// 设置webdriver解析js里的最长等待时间
driver.manage().timeouts().setScriptTimeout(10, TimeUnit.SECONDS);
LOG.info("browser version:" + browserVersion);
LOG.info("enable javascript:" + enableJs);
java 模拟web登陆httpClient并保存cookie
场景:调用接口完成某项操作,但是接口是强登录的,需要cookie, 且cookie会过期;服务器会限制登录的次数,如果一个账号频繁登录,则在短时间内无法正常登录,因此无法做到每调用接口一次就登录一次,且这样的效率也会比较低;
方法: 采用httpClient获取cookie, 并在接口上加入cookie校验;
核心代码:
0. 需要加入的jar包
1 import org.apache.commons.lang.StringUtils; 2 import org.apache.commons.httpclient.HttpClient; 3 import org.apache.commons.httpclient.methods.GetMethod; 4 import org.apache.http.Header; 5 import org.apache.http.HttpResponse; 6 import org.apache.http.HttpStatus; 7 import org.apache.http.StatusLine; 8 import org.apache.http.client.CookieStore; 9 10 import org.apache.http.client.HttpClient; 11 import org.apache.http.client.methods.HttpGet; 12 import org.apache.commons.httpclient.methods.GetMethod; 13 14 import org.apache.http.client.methods.HttpPost; 15 16 import org.apache.http.cookie.Cookie; 17 import org.apache.http.impl.client.BasicCookieStore; 18 19 import org.apache.http.impl.client.HttpClients; 20 import org.apache.http.protocol.BasicHttpContext; 21 import org.apache.http.protocol.HttpContext;
需要导入pom.xml文件的依赖
1 <dependency> 2 <groupId>org.apache.httpcomponents</groupId> 3 <artifactId>httpclient</artifactId> 4 <version>4.5.5</version> 5 </dependency> 6 <dependency> 7 <groupId>commons-httpclient</groupId> 8 <artifactId>commons-httpclient</artifactId> 9 <version>3.1</version> 10 </dependency>
1. 获取cookie, 其中
getUrl(loginUrl, username, password); 是将url进行拼接,loginUrl 加上登陆需要的参数拼接为一个请求
public String getCookies(String username, String password) CookieStore cookieStore = new BasicCookieStore(); HttpContext localContext = new BasicHttpContext(); localContext.setAttribute(COOKIE_STORE, cookieStore); HttpClient client = HttpClients.createDefault(); String authUrl = getUrl(loginUrl, username, password); System.out.println("authUrl = " + authUrl); HttpPost post = new HttpPost(authUrl); try response = client.execute(post, localContext); StatusLine statusLine = response.getStatusLine(); int statusCode = statusLine.getStatusCode(); System.out.println("first execute code :" + statusCode); if(statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) Header firsRedirectHeader = response.getFirstHeader("location"); String firstRedirectUrl = firsRedirectHeader.getValue(); HttpGet get = new HttpGet(firstRedirectUrl); HttpResponse getResponse = client.execute(get, localContext); StatusLine statusLine2 = getResponse.getStatusLine(); int statusCode2 = statusLine2.getStatusCode(); System.out.println("second execute code :" + statusCode2); System.out.println("cookie :" + cookieStore.getCookies()); List<Cookie> cookieList = cookieStore.getCookies(); StringBuffer tmpCookie = new StringBuffer(); for(int i = 0 ; i < cookieList.size(); i++) tmpCookie.append(cookieList.get(i).getName()).append("="); tmpCookie.append(cookieList.get(i).getValue()).append(";"); tmpCookie.append("domain=").append(cookieList.get(i).getDomain()).append(";"); tmpCookie.append("path=").append(cookieList.get(i).getPath()).append(";"); get.releaseConnection(); return tmpCookie.toString(); catch (IOException e) e.printStackTrace(); finally if(post != null) post.releaseConnection(); return "-1";
2. 获取到有效的cookie, 因为第一步获取到cookie后,cookie在一段时间内可能会失效,因此为了后面接口中带入有效的cookie, 这里还需要该函数来获取真正有效的cookie;
public String getValidCookie(String cookie) if(cookie.contains("DICT_SESS")) return cookie; else Login login = new Login(); String validCookie = login.getCookies(username, password); return validCookie;
3. 真正执行接口的代码, for循环2次,第一次是去请求接口,如果接口返回的结果是403权限被拒绝,则需要调用login.getValidCookie()方法登录一次,获取真正的cookie.,然后进行第二次接口请求;
如果接口返回的结果是0, 则表示cookie依然有效,则直接返回true; 其中参数url是需要真正请求的接口;
1 public Boolean executeMethod(String url) 2 String result = "-1"; 3 for(int i = 0; i < 2; i++) 4 GetMethod getMethod = new GetMethod(url); 5 getMethod.setRequestHeader("cookie", cookie); 6 try 7 httpClient.executeMethod(getMethod); 8 System.out.println("method result = " + getMethod.getResponseBodyAsString()); 9 result = getMethod.getResponseBodyAsString(); 10 catch (IOException e) 11 e.printStackTrace(); 12 13 JSONObject obj = JSONObject.parseObject(result); 14 if ("0".equals(obj.get("err").toString())) 15 return true; 16 else if ("403".equals(obj.get("err").toString())) 17 cookie = login.getValidCookie(cookie); 18 continue; 19 else 20 return false; 21 22 23 return false; 24 25
4. 在类加载的时候先登录一次,保存cookie,且是全局变量;则在第3步更新cookie的时候,就可以更新该变量;
1 Login login = new Login();
2 private String cookie = login.getCookies(username, password);
3 HttpClient httpClient = new HttpClient();
总结: 第三步判断cookie失效重新请求的实现方法有点不太好,希望大家多多交流;
以上是关于httpclient模拟登陆成功后在浏览器中打开登陆后的页面的主要内容,如果未能解决你的问题,请参考以下文章