跨服务存储传递HttpContext Cookies

本文介绍了一种通过HttpClient在客户端和服务端之间保持会话的方法。主要通过将Cookies转换为字符串参数来实现跨接口请求的会话统一,同时针对并发场景进行了优化。

场景:通过HttpClient向第三方服务平台发起接口请求,多个接口间Cookies有关联需要保持统一。

考虑到自己的接口服务存在并发,所以决定将Cookies转换成参数并返回给客户端,以便客户端进行下一个接口请求时保持会话统一。


1.首先从HttpClient请求返回的HttpContext中获取Cookies

BasicCookieStore cookie = (BasicCookieStore) httpContext.getAttribute("http.cookie-store");

String cookiesStr = JSONObject.toJSONString(cookie);
return cookiesStr;//通过JSONObject转成String字符串并作为参数传回客户端


2.客户端发起下一个接口请求时将之前传给客户端的cookiesStr作为参数传给后台服务

后台接口把客户端传递的cookiesStr转换成HttpContext进行第二次的HttpClient接口调用

HttpContext httpContext = new BasicHttpContext();
JSONObject jsonObject =JSONObject.parseObject(TC_CD);
JSONArray array=jsonObject.getJSONArray("cookies");
BasicCookieStore basicCookieStore =new BasicCookieStore();
for(int i=0;i<array.size();i++){
JSONObject cookieJson=array.getJSONObject(i);
BasicClientCookie cookie = new BasicClientCookie(cookieJson.getString("name"), cookieJson.getString("value"));
cookie.setDomain(cookieJson.getString("domain"));
cookie.setExpiryDate(new Date(Long.valueOf(cookieJson.getString("expiryDate"))));
cookie.setPath(cookieJson.getString("path"));
cookie.setSecure(Boolean.valueOf(cookieJson.getString("secure")));
cookie.setVersion(Integer.valueOf(cookieJson.getString("version")));
basicCookieStore.addCookie(cookie);
}
httpContext.setAttribute("http.cookie-store", basicCookieStore);
return httpContext;


正常情况下通过以上两步已可以保持会话统一。


之后不久莫名其妙的发现上面的形式不可以了,猜想是BasicClientCookie 设置的属性不全引起的,所以改变了HttpContext 与String字符串之间的转换


1.HttpContext转String

BasicCookieStore basicCookieStore  =(BasicCookieStore) httpContext.getAttribute("http.cookie-store");
ByteOutputStream outputStream = new ByteOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(outputStream);
oos.writeObject(basicCookieStore);
oos.close();
byte[] osByte = outputStream.getBytes();
String cookiesStr = Base64.encodeBase64String(osByte);
String zipCookiesStr = ZipStrUtil.zip(cookiesStr);
return zipCookiesStr;


2.String转HttpContext

String unzipCookiesStr = ZipStrUtil.unzip(cookiesStr);
HttpContext httpContext = new BasicHttpContext();
ByteArrayInputStream baInputStream = new ByteArrayInputStream(Base64.decodeBase64(unzipCookiesStr));
ObjectInputStream oInputStream = new ObjectInputStream(baInputStream);
BasicCookieStore cookies = (BasicCookieStore) oInputStream.readObject();
oInputStream.close();
httpContext.setAttribute("http.cookie-store", cookies);
return httpContext;


其中用到了一个压缩工具类ZipStrUtil.java


package com.ai.atp.httpclient.util.common;
 
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

 public class ZipStrUtil {

     /**
      * 使用gzip进行压缩
      */
     public static String gzip(String primStr) {
         if (primStr == null || primStr.length() == 0) {
             return primStr;
         }
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         GZIPOutputStream gzip=null;
         try {
             gzip = new GZIPOutputStream(out);
             gzip.write(primStr.getBytes());
         } catch (IOException e) {
             e.printStackTrace();
         }finally{
             if(gzip!=null){
                 try {
                     gzip.close();
                 } catch (IOException e) {
                     e.printStackTrace();
                 }
             }
         }
         return new sun.misc.BASE64Encoder().encode(out.toByteArray());
     }

     /**
      *
      * <p>Description:使用gzip进行解压缩</p>
      * @param compressedStr
      * @return
      */
     public static String gunzip(String compressedStr){
         if(compressedStr==null){
             return null;
         }
         ByteArrayOutputStream out= new ByteArrayOutputStream();
         ByteArrayInputStream in=null;
         GZIPInputStream ginzip=null;
         byte[] compressed=null;
         String decompressed = null;
         try {
             compressed = new sun.misc.BASE64Decoder().decodeBuffer(compressedStr);
             in=new ByteArrayInputStream(compressed);
             ginzip=new GZIPInputStream(in);
             byte[] buffer = new byte[1024];
             int offset = -1;
             while ((offset = ginzip.read(buffer)) != -1) {
                 out.write(buffer, 0, offset);
             }
             decompressed=out.toString();
         } catch (IOException e) {
             e.printStackTrace();
         } finally {
             if (ginzip != null) {
                 try {
                     ginzip.close();
                 } catch (IOException e) {
                 }
             }
             if (in != null) {
                 try {
                     in.close();
                 } catch (IOException e) {
                 }
             }
             if (out != null) {
                 try {
                     out.close();
                 } catch (IOException e) {
                 }
             }
         }
         return decompressed;
     }

     /**
      * 使用zip进行压缩
      * @param str 压缩前的文本
      * @return 返回压缩后的文本
      */
     public static final String zip(String str) {
         if (str == null)
             return null;
         byte[] compressed;
         ByteArrayOutputStream out = null;
         ZipOutputStream zout = null;
         String compressedStr = null;
         try {
             out = new ByteArrayOutputStream();
             zout = new ZipOutputStream(out);
             zout.putNextEntry(new ZipEntry("0"));
             zout.write(str.getBytes());
             zout.closeEntry();
             compressed = out.toByteArray();
             compressedStr = new sun.misc.BASE64Encoder().encodeBuffer(compressed);
         } catch (IOException e) {
             compressed = null;
         } finally {
             if (zout != null) {
                 try {
                     zout.close();
                 } catch (IOException e) {
                 }
             }
             if (out != null) {
                 try {
                     out.close();
                 } catch (IOException e) {
                 }
             }
         }
         return compressedStr;
     }

     /**
      * 使用zip进行解压缩
      * @param compressed 压缩后的文本
      * @return 解压后的字符串
      */
     public static final String unzip(String compressedStr) {
         if (compressedStr == null) {
             return null;
         }
         ByteArrayOutputStream out = null;
         ByteArrayInputStream in = null;
         ZipInputStream zin = null;
         String decompressed = null;
         try {
             byte[] compressed = new sun.misc.BASE64Decoder().decodeBuffer(compressedStr);
             out = new ByteArrayOutputStream();
             in = new ByteArrayInputStream(compressed);
             zin = new ZipInputStream(in);
             zin.getNextEntry();
             byte[] buffer = new byte[1024];
             int offset = -1;
             while ((offset = zin.read(buffer)) != -1) {
                 out.write(buffer, 0, offset);
             }
             decompressed = out.toString();
         } catch (IOException e) {
             decompressed = null;
         } finally {
             if (zin != null) {
                 try {
                     zin.close();
                 } catch (IOException e) {
                 }
             }
             if (in != null) {
                 try {
                     in.close();
                 } catch (IOException e) {
                 }
             }
             if (out != null) {
                 try {
                     out.close();
                 } catch (IOException e) {
                 }
             }
         }
         return decompressed;
     }
 
 }
 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值