java 傳送POST、GET請求時,獲取請求的頭資訊Set-Cookie,請求攜帶Cookie
阿新 • • 發佈:2019-01-25
需求背景
1、前端在請求時遇到跨域請求,連續的請求之間需要攜帶上一次的Cookie,前端不便於實現。
2、所以需要後端實現Cookie的獲取與請求攜帶,實現請求服務的代理請求。
可行性分析
1、 cookie (儲存在使用者本地終端上的資料)
2、 瀏覽器怎麼處理cookie
- 伺服器向瀏覽器設定cookie (http請求Set-Cookie欄位)
- 瀏覽器向伺服器提交cookie(http請求Cookie欄位)
3、程式實現:通過http請求的資訊獲取Set-Cookie的資訊,然後再次提交時寫入Cookie資訊就可實現。
程式流程
- 獲取需要代理的地址以及引數和請求方式。
- 獲取儲存在Session中的Cookie資訊寫入http請求頭資訊(為空則不寫入),根據請求的資訊來發起http請求。
- 將獲取的http請求中的Set-Cookie的資訊獲取Cookie,並將它儲存到Session中。
- 返回代理的http請求返回的資料給前端。
( ps:步驟2是獲取上一次請求時步驟3設定的session )
程式程式碼
1、請求工具類(請根據需要自行修改cookie名稱)
package func;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang.StringUtils;
/**
* 用於請求url資料
* 每一次請求都要獲取Set-Cookie頭資訊然後在使用的時候拼接請求寫入Cookie
*
* Cookie verCode 用與第二次請求時攜帶
* Cookie JSESSIONID 用於請求代理的SessionId(當前請求不返回)
*
* @author yuyu
*
*/
public class UrlLib {
/**
* 獲取Set-Cookie 寫入session中,然後請求在頭資訊的時候寫入
*/
public static byte[] doGet(HttpServletRequest request, String url, Map<String,String> param) throws Exception{
//當傳入的url返回不為空的時候,讀取資料
InputStream input=null;
byte[] data = null;//提高字元資料的生成
if(StringUtils.isNotBlank(url)){
try{
//設定請求的頭資訊
URL urlInfo = new URL(url+'?'+getParam(param));
URLConnection connection = urlInfo.openConnection();
connection.addRequestProperty("Host", urlInfo.getHost());//設定頭資訊
connection.addRequestProperty("Connection", "keep-alive");
connection.addRequestProperty("Accept", "*/*");
connection.addRequestProperty("Cookie", getSessionIncookie(request));//設定獲取的cookie
connection.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64)");
connection.connect();
// 獲取所有響應頭欄位
getCookieToSession(request,connection);
//獲取請求回來的資訊
input = connection.getInputStream();//定義返回資料的格式
data = new byte[input.available()];
input.read(data);
}catch(Exception e){
throw new Exception("讀取Url資料失敗:"+url,e);
}finally {
try{
input.close();
}catch(Exception e){}
}
}
return data;
}
/**
* 獲取post請求
* @param request
* @param string
* @param param
* @return
*/
public static byte[] doPost(HttpServletRequest request, String url,
Map<String, String> param) throws Exception{
//當傳入的url返回不為空的時候,讀取資料
InputStream input=null;
PrintWriter out = null;
byte[] data = null;//提高字元資料的生成
if(StringUtils.isNotBlank(url)){
try{
//設定請求的頭資訊
URL urlInfo = new URL(url);
URLConnection connection = urlInfo.openConnection();
connection.addRequestProperty("Host", urlInfo.getHost());//設定頭資訊
connection.addRequestProperty("Connection", "keep-alive");
connection.addRequestProperty("Accept", "*/*");
connection.addRequestProperty("Cookie", getSessionIncookie(request));//設定獲取的cookie
connection.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64)");
// 傳送POST請求必須設定如下兩行
connection.setDoOutput(true);
connection.setDoInput(true);
// 獲取URLConnection物件對應的輸出流
out = new PrintWriter(connection.getOutputStream());
// 傳送請求引數
out.print(getParam(param));
// flush輸出流的緩衝
out.flush();
// 獲取所有響應頭欄位
getCookieToSession(request,connection);
//獲取請求回來的資訊
input = connection.getInputStream();//定義返回資料的格式
data = new byte[input.available()];
input.read(data);
}catch(Exception e){
throw new Exception("讀取Url資料失敗:"+url,e);
}finally {
try{
input.close();
}catch(Exception e){}
}
}
return data;
}
/**
* 獲取在session中儲存的cookie
* @param request
* @return
*/
private static String getSessionIncookie(HttpServletRequest request) {
String back="";
HttpSession session = request.getSession();
String verCode=(String) session.getAttribute("verCode");
String JSESSIONID=(String) session.getAttribute("JSESSIONID");
System.out.println(verCode);
System.out.println(JSESSIONID);
if(verCode!=null){
back=verCode;
}
if(JSESSIONID!=null){
if(!StringUtils.isEmpty(back)){
back+=" ";
}
back+=JSESSIONID;
}
System.out.println(back);
return back;
}
/**
* 將請求的頭資訊獲取到session中
* @param request
* @param connection
*/
private static void getCookieToSession(HttpServletRequest request,
URLConnection connection) {
Map<String, List<String>> map = connection.getHeaderFields();
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
HttpSession session = request.getSession();
List<String> cookie=map.get("Set-Cookie");
if(cookie!=null){
String verCode=getCookieBySet("verCode",cookie.get(0));
String JSESSIONID=getCookieBySet("JSESSIONID",cookie.get(0));
if(verCode!=null){
session.setAttribute("verCode",verCode);
}
if(JSESSIONID!=null){
session.setAttribute("JSESSIONID",JSESSIONID);
}
}
}
/**
* 獲取verCode=b5pcogZaFGikpAc1mQ+G5wOJGBWtXLsHafpf5wlgF5s=; Path=/SSODAO/; HttpOnly
* 的cookie資訊
*/
public static String getCookieBySet(String name,String set){
String regex=name+"=(.*?);";
Pattern pattern = Pattern.compile(regex);
Matcher matcher =pattern.matcher(set);
if(matcher.find()){
return matcher.group();
}
return null;
}
/**
* 將引數以 key=123&v=456 返回
* @param param
* @return
*/
public static String getParam(Map<String,String> param){
StringBuilder str=new StringBuilder();
int size=0;
for (Map.Entry<String, String> m :param.entrySet()) {
str.append(m.getKey());
str.append("=");
str.append(m.getValue());
if(size<param.size()-1){
str.append("&");
}
size++;
}
System.out.println(str.toString());
return str.toString();
}
}
2、代理程式(servlet)
package testLogin;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import func.UrlLib;
@SuppressWarnings("serial")
public class LoginUrl extends HttpServlet {
/**
* 代理請求資料
* 代理地址 http://127.0.0.1:8080/Test/servlet/
*
* 介面 TestOne
* 引數 Time (String)
*
* 介面 TestTow
* 介面 Code (String)
*
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String base="http://127.0.0.1:8080/Test/servlet/";
String url=request.getParameter("url");
System.out.println(url);
//第一次請求
if("TestOne".equals(url)){
String time=request.getParameter("Time");
Map<String,String> param= new HashMap<String, String>();
param.put("Time", time);
try {
//請求圖片
response.setContentType("image/jpeg");
OutputStream out = response.getOutputStream();
out.write(UrlLib.doGet(request, base+url, param));
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
//第二次請求
}else if("TestTow".equals(url)){
String code=request.getParameter("Code");
Map<String,String> param= new HashMap<String, String>();
param.put("Code", code);
try{
//請求文字
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.print(new String(UrlLib.doPost(request, base+url, param),"UTF-8"));
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}else{
//引數錯誤
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.print("引數錯誤");
out.flush();
out.close();
}
}
}
總結
- 給出的程式碼示例時根據我的業務需求的程式碼,具體使用的就是方法類中的doGet與doPost方法。
- 在cookie的獲取與設定中請根據需要修改cookie的名稱以獲取正確的cookie。
- JSESSIONID 的cookie在我測試中並未獲取到,原因是我請求的介面並沒有返回對應的Set-Cookie。
- 貼出請求的頭資訊:
null—>[HTTP/1.1 200]
Date—>[Mon, 22 Jan 2018 01:01:14 GMT]
Transfer-Encoding—>[chunked]
Expires—>[Thu, 01 Jan 1970 00:00:00 GMT]
Set-Cookie—>[verCode=+ifEGHWxioffSG6/7eQdmCwfRgLylaWmr0LOS0WCILM=; Path=/SSODAO/; HttpOnly]
Connection—>[close]
Content-Type—>[image/jpeg]
Cache-Control—>[no-cache]
Pragma—>[No-cache]