1. 程式人生 > >java 傳送POST、GET請求時,獲取請求的頭資訊Set-Cookie,請求攜帶Cookie

java 傳送POST、GET請求時,獲取請求的頭資訊Set-Cookie,請求攜帶Cookie

需求背景

1、前端在請求時遇到跨域請求,連續的請求之間需要攜帶上一次的Cookie,前端不便於實現。
2、所以需要後端實現Cookie的獲取與請求攜帶,實現請求服務的代理請求。

可行性分析

1、 cookie (儲存在使用者本地終端上的資料)

2、 瀏覽器怎麼處理cookie

  1. 伺服器向瀏覽器設定cookie (http請求Set-Cookie欄位)
    這裡寫圖片描述
  2. 瀏覽器向伺服器提交cookie(http請求Cookie欄位)
    這裡寫圖片描述

3、程式實現:通過http請求的資訊獲取Set-Cookie的資訊,然後再次提交時寫入Cookie資訊就可實現。

程式流程

  1. 獲取需要代理的地址以及引數和請求方式。
  2. 獲取儲存在Session中的Cookie資訊寫入http請求頭資訊(為空則不寫入),根據請求的資訊來發起http請求。
  3. 將獲取的http請求中的Set-Cookie的資訊獲取Cookie,並將它儲存到Session中。
  4. 返回代理的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();
        }
    }

}

總結

  1. 給出的程式碼示例時根據我的業務需求的程式碼,具體使用的就是方法類中的doGet與doPost方法。
  2. 在cookie的獲取與設定中請根據需要修改cookie的名稱以獲取正確的cookie。
  3. JSESSIONID 的cookie在我測試中並未獲取到,原因是我請求的介面並沒有返回對應的Set-Cookie。
  4. 貼出請求的頭資訊:
    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]