HttpClient 多次请求session保持同一个Session
Http 请求是我们最常用的一种请求方式。而我们客户端http请求最常用的也就是 HttpClient 。无状态(没用户识别,如:登录)的请求。我们可以直接 HttpClient 即可,有状态,特别是一直要保持状态,那就有点难度了。
接下来我模拟一下Java HttpClient
请求像浏览器请求一样保持 Session 回话。
Demo:请求工信部备案查询。(请勿用来做非法勾当)
一、根据分析,有几个问题要攻克。
二、根据问题,我们一个一个来攻克。
1>.来源Referer判断,这个easy。增加如下代码即可解决。
head.put("Referer", "当前URL");
2>.Host判断,也很简单。
head.put("Host", "www.miitbeian.gov.cn");
3>.验证码,稍微复杂,省略了一些验证。
public void getVcode(HttpServletRequest request,HttpServletResponse response) throws Exception{
//创建一个请求
HttpClient client = new HttpClient();
//设置字符集
client.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,"UTF-8");
//像浏览器一样请求
client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
//创建一个GET请求
GetMethod method = new GetMethod("http://www.miitbeian.gov.cn/getVerifyCode");
method.setRequestHeader("Connection","close");
//Host
method.setRequestHeader("Host", "www.miitbeian.gov.cn");
//Referer
method.setRequestHeader("Referer", "http://www.miitbeian.gov.cn/icp/publish/query/icpMemoInfo_showPage.action");
//User-Agent请求的浏览器 and 系统情况。
method.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0");
//cookie
method.setRequestHeader("Cookie",
"__jsluid=a24913af67d5180974c18523e24d08a0; JSESSIONID=YKxXWw1fRJCVSClWvv8brv2ZZrJsBVLgpQCjDxGnJHNbvSMKn021!-618727874");
//执行请求
client.executeMethod(method);
//获得返回的io
InputStream in = method.getResponseBodyAsStream();
//得到图片的二进制数据,以二进制封装得到数据,具有通用性
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
//创建一个Buffer字符串
byte[] buffer = new byte[1024];
//每次读取的字符串长度,如果为-1,代表全部读取完毕
int len = 0;
//使用一个输入流从buffer里把数据读取出来
while( (len=in.read(buffer)) != -1 ){
//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
//关闭输入流
in.close();
//把outStream里的数据写入内存
byte[] data = outStream.toByteArray();
ServletOutputStream out = response.getOutputStream();
out.write(data);
out.flush() ;
out.close();
}
4>.session一致问题,Session是存在哪,cookie,那就是把cookie保证一致,从第一次请求开始就带上。下面整体展示。
三、整体代码。
1>.HTML代码,简单看看。
<form role="search" class="navbar-form navbar-left" action="/request/post.shtml" method="post">
<div class="form-group">
<input type="text" placeholder="网址" name="domain" style="width: 245px;" class="form-control">
<input type="text" placeholder="验证码" name="code"class="form-control">
</div>
<div class="form-group">
<img id="yzm" src="https://www.sojson.com/request/getVcode.shtml"/>
</div>
<button class="btn btn-default" type="submit">Submit</button>
</form>
2>.Java代码。
package com.sojson.zhanzhang.controller;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.sojson.common.controller.BaseController;
import com.sojson.common.utils.VinuxPostMethod;
@Controller
@Scope(value="prototype")
@RequestMapping("request")
public class RequestSimulateController extends BaseController {
/**
* 页面跳转
* @return
*/
@RequestMapping(value="post",method=RequestMethod.GET)
public ModelAndView index(){
ModelAndView view = new ModelAndView("request/index");
return view;
}
/**
* 执行请求,去工信部网站获得备案信息。
* @param code 验证码
* @param domain 域名
* @param request
* @param response
* @return
*/
@RequestMapping(value="post",method=RequestMethod.POST)
public ModelAndView post(String code,String domain,HttpServletRequest request,HttpServletResponse response){
VinuxPostMethod post = new VinuxPostMethod("http://www.miitbeian.gov.cn/icp/publish/query/icpMemoInfo_searchExecute.action");
resultMap.put("certType", -1);
resultMap.put("condition",1 );
resultMap.put("mainUnitNature",-1 );
resultMap.put("siteDomain",domain);//域名
resultMap.put("verifyCode",code);//验证码
HashMap<String, String> head = new HashMap<String, String>();
head.put("Host", "www.miitbeian.gov.cn");
head.put("Referer", "http://www.miitbeian.gov.cn/publish/query/indexFirst.action");
head.put("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0");
head.put("Cookie",
"__jsluid=a24913af67d5180974c18523e24d08a0; JSESSIONID=YKxXWw1fRJCVSClWvv8brv2ZZrJsBVLgpQCjDxGnJHNbvSMKn021!-618727874");
//添加请求头
post.setHead(head);
//添加参数。
post.setParameter(resultMap);
//执行请求
Object result = post.executeMethod();
ModelAndView view = new ModelAndView("request/result");
//页面展示
view.addObject("result", result);
return view;
}
/**
* 获取验证码
* @param request
* @param response
* @throws Exception
*/
@RequestMapping("getVcode")
public void getVcode(HttpServletRequest request,HttpServletResponse response) throws Exception{
//创建一个请求
HttpClient client = new HttpClient();
//设置字符集
client.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,"UTF-8");
//像浏览器一样请求
client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
//创建一个GET请求
GetMethod method = new GetMethod("http://www.miitbeian.gov.cn/getVerifyCode");
method.setRequestHeader("Connection","close");
//Host
method.setRequestHeader("Host", "www.miitbeian.gov.cn");
//Referer
method.setRequestHeader("Referer", "http://www.miitbeian.gov.cn/icp/publish/query/icpMemoInfo_showPage.action");
//User-Agent请求的浏览器 and 系统情况。
method.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0");
//cookie
method.setRequestHeader("Cookie",
"__jsluid=a24913af67d5180974c18523e24d08a0; JSESSIONID=YKxXWw1fRJCVSClWvv8brv2ZZrJsBVLgpQCjDxGnJHNbvSMKn021!-618727874");
//执行请求
client.executeMethod(method);
//获得返回的io
InputStream in = method.getResponseBodyAsStream();
//得到图片的二进制数据,以二进制封装得到数据,具有通用性
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
//创建一个Buffer字符串
byte[] buffer = new byte[1024];
//每次读取的字符串长度,如果为-1,代表全部读取完毕
int len = 0;
//使用一个输入流从buffer里把数据读取出来
while( (len=in.read(buffer)) != -1 ){
//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
//关闭输入流
in.close();
//把outStream里的数据写入内存
byte[] data = outStream.toByteArray();
ServletOutputStream out = response.getOutputStream();
out.write(data);
out.flush() ;
out.close();
}
}
PS:下面我们看效果吧。
版权所属:SO JSON在线解析
原文地址:https://www.sojson.com/blog/17.html
转载时必须以链接形式注明原始出处及本声明。
本文主题:
如果本文对你有帮助,那么请你赞助我,让我更有激情的写下去,帮助更多的人。