java 发送POST、GET请求时,获取请求的头信息Set-Cookie,请求携带Cookie

需求背景

一、前端在请求时遇到跨域请求,连续的请求之间须要携带上一次的Cookie,前端不便于实现。
二、因此须要后端实现Cookie的获取与请求携带,实现请求服务的代理请求。html

可行性分析

一、 cookie (储存在用户本地终端上的数据)前端

Cookie 是在 HTTP 协议下,服务器或脚本能够维护客户工做站上信息的一种方式。Cookie 是由 Web 服务器保存在用户浏览器(客户端)上的小文本文件,它能够包含有关用户的信息。不管什么时候用户连接到服务器,Web 站点均可以访问 Cookie 信息。——百度百科java

二、 浏览器怎么处理cookieweb

  1. 服务器向浏览器设置cookie (http请求Set-Cookie字段)
    这里写图片描述
  2. 浏览器向服务器提交cookie(http请求Cookie字段)
    这里写图片描述

三、程序实现:经过http请求的信息获取Set-Cookie的信息,而后再次提交时写入Cookie信息就可实现。apache

程序流程

  1. 获取须要代理的地址以及参数和请求方式。
  2. 获取保存在Session中的Cookie信息写入http请求头信息(为空则不写入),根据请求的信息来发起http请求。
  3. 将获取的http请求中的Set-Cookie的信息获取Cookie,并将它保存到Session中。
  4. 返回代理的http请求返回的数据给前端。
    ( ps:步骤2是获取上一次请求时步骤3设置的session )

程序代码

一、请求工具类(请根据须要自行修改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();
    }

}

二、代理程序(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]