Android自定义携带Cookie的POST请求

原创 2015年11月17日 20:30:13

发送请求

第一步当然是首先了解POST请求的整个流程是什么样的,我们简单列出步骤,如下:

  1. 设置参数
  2. 设置请求链接
  3. 获得返回值

一般来说,我们使用POST请求,大致如上的三个步骤。我们可以有如下的框架性的代码:

/**
 * 发送请求
 * @param context
 * @param baseUrl
 * @param params
 * @param handler
 * @return
 * @throws Exception
 */
public static boolean sendPOSTRequest(Context context,String baseUrl, HashMap<String, String> params, Handler handler) throws Exception{

    mContext = context;

    // 设置参数
    byte[] entity = onParams(params);

    // 设置请求链接
    HttpURLConnection conn = onSetConn(context, baseUrl, entity);

    // 得到返回值
    int responseCode = conn.getResponseCode();

    if (HttpURLConnection.HTTP_OK == responseCode) {
        saveRequestResult(context, handler, conn);
    } else {
        Message msg = new Message();
        msg.what = UpsHttpConstant.REQUEST_CODE_FAILED;
        msg.obj = "Post wrong!";
        handler.sendMessage(msg);
    }

    if(conn!=null){
        conn.disconnect();
    }
    return false;
}

这里可以看到,我们将一个异常抛出给调用者,中间是一些网络请求链接的过程信息。接下来,我们会逐步解析如上的一些封装的方法。

加密参数

我们在上面的代码中,可以看到这样的一句代码,如下:

// 设置参数
byte[] entity = onParams(params);

这里,如果我们使用了参数加密,那么可以在onParams() 这个方法中进行操作,我们这里没有使用加密操作,代码如下:

/**
 * 参数拼接
 * @return
 * @throws UnsupportedEncodingException
 */
private static byte[] onParams(HashMap<String, String> params) throws UnsupportedEncodingException {
    if (params == null || params.isEmpty()){
        params = new HashMap<>();
    }
    // 添加必须携带的参数信息
    params.put("phone", getPhone());
    params.put("password", getPassword());

    //StringBuilder是用来组拼请求参数
    StringBuilder sb = new StringBuilder();
    if(params != null && params.size() != 0){
        for (Map.Entry<String, String> entry : params.entrySet()) {
            sb.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "utf-8"));
            sb.append("&");
        }
        sb.deleteCharAt(sb.length()-1);
    }
    return sb.toString().getBytes();
}

如果我们在这里使用加密,过程比较简单,就不再赘述。

设置请求链接

我们在框架代码中,有这样一句,是表示对链接进行设置:

// 设置请求链接
HttpURLConnection conn = onSetConn(context, baseUrl, entity);

如果对网络请求比较熟悉的同学,应该知道三次握手,四次挥手 这样一个概念,那么我们的onSetConn() 实际上就是来实现这样一个过程,不过当中有很多代码已经被封装,我们在使用的时候,一般只用调用暴露出来的API即可。代码如下:

/**
 * 设置请求链接
 * @param context
 * @param baseUrl
 * @param entity
 * @return
 * @throws IOException
 */
private static HttpURLConnection onSetConn(Context context, String baseUrl, byte[] entity) throws IOException {
    URL url = new URL(baseUrl);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setConnectTimeout(UpsHttpConstant.CONNECT_TIME_OUT);
    // 设置以POST方式
    conn.setRequestMethod(UpsHttpConstant.REQUEST_METHOD_POST);
    //要向外输出数据,要设置这个
    conn.setDoOutput(true);
    // 1、POST请求这个一定要设置
    conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    conn.setRequestProperty("Content-Length", entity.length + "");
    // 2、添加cookie信息
    String temp_cookie = SharePerUtils.get(context,"cookie","");
    Log.e("test_cookie","temp_cookie is " + temp_cookie);
    if (!TextUtils.isEmpty(temp_cookie)){
        conn.setRequestProperty("cookie",temp_cookie);
    }
    // 3、参数信息
    OutputStream out = conn.getOutputStream();
    //写入参数值
    out.write(entity);
    //刷新、关闭
    out.flush();
    out.close();
    return conn;
}

在这里,我们需要注意两个点,一个是请求的设置,另一个是设置cookie,这也是写这篇文章的目的所在。注意这里:

conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

这句代码是表示设置返回值的类型,如果后面的方式不对,我们可能无法获取得到正确的值,这句代码记得不要写错了application/x-www-form-urlencoded,部分同学可能会写成application/json 可能无法获取得到正确的结果,不妨改成如上代码试试看。

注意:SharePerUtils 是对SharedPreferences 存储的封装。

存储Cookie

好了,这里也是一个关键点,如何获取从服务器返回结果中的cookie值?我们可以尝试使用fiddler 抓包看一下我们的链接返回值,会发现Set-Cookie 这样的关键字,没错,这就是我们返回的cookie值。那么,代码又该如何写呢,如下:

/**
 * 存储返回值
 * @param context
 * @param handler
 * @param connection
 * @throws IOException
 */
private static void saveRequestResult(Context context, Handler handler, HttpURLConnection connection) throws IOException {
    //获取cookie
    Map<String,List<String>> map = connection.getHeaderFields();
    Set<String> set = map.keySet();
    for (Iterator iterator = set.iterator(); iterator.hasNext();) {
        String key = (String) iterator.next();
        // 截取 Cookie
        if ("Set-Cookie".equals(key)) {
            List<String> list = map.get(key);
            StringBuilder builder = new StringBuilder();
            builder.append(list.get(0));
            String firstCookie = builder.toString().split(";")[0];
            SharePerUtils.put(context,"cookie",firstCookie);
            Log.e("test_cookie","save firstcookie is " + firstCookie);
        }
    }

    // 得到返回值
    String result = getResultString(connection.getInputStream(),"UTF-8");
}

结果字符串

上文我们说到了如何获取cookie值,而cookie值是不会直接在返回的字符串中的,比如我们返回一个json串,那么cookie是不会直接存在这里的。上文我们已经获取得到了cookie,那么如何获取返回的json串呢?实际上这里就是一个数据流的读取操作,代码如下:

/**
 * 获得结果字符串
 * @param inputStream
 * @param encode 编码形式U8
 * @return
 */
private static String getResultString(InputStream inputStream, String encode) {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    byte[] data = new byte[1024];
    int len = 0;
    String result = "";
    if (inputStream != null) {
        try {
            while ((len = inputStream.read(data)) != -1) {
                outputStream.write(data, 0, len);
            }
            result = new String(outputStream.toByteArray(), encode);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return result;
}

模拟发送带cookies的http请求的两种方法

如果想发送带cookies的请求,有两种方式,一种使用工具,一种使用java代码,干货如下:使用工具使用的工具是postman和Postman Interceptor使用谷歌浏览器的扩展程序下载(需要...
  • starryninglong
  • starryninglong
  • 2017年03月05日 16:54
  • 4739

跨域Ajax请求时是否带Cookie的设置

1. 无关Cookie跨域Ajax请求客户端以 Jquery 的 ajax 为例:$.ajax({ url : 'http://remote.domain.com/corsreques...
  • wzl002
  • wzl002
  • 2016年05月18日 10:19
  • 24959

Android Volley 的post请求自定义 和 volley 的cookies 使用

android的网络请求有很多第三方框架,其中volley由于其高的定制性、稳定性以及速度快得到了大家广泛的使用以及研究,这里我只是说一下我对这个框架下post请求使用的心得体会。 一.cookie...
  • ZHU260824
  • ZHU260824
  • 2015年10月30日 12:19
  • 392

自定义Filter来解决web项目的乱码问题,包括get和post请求

  • 2014年08月01日 15:11
  • 3KB
  • 下载

使用HttpWebRequest发送自定义POST请求

  • 2013年09月06日 17:19
  • 22KB
  • 下载

针对 android端模拟教务系统登陆,主要针对抓包过程,post,get请求,和解析网页和cookie(一)

针对 android端模拟教务系统登陆,主要针对抓包过程,post,get请求,和解析网页和cookie(一)2016年8月31日00:03:40 本人android新手,就读于安阳师范学院,最近在...
  • qq_28817739
  • qq_28817739
  • 2016年08月30日 22:53
  • 1019

针对 android端模拟教务系统登陆,主要针对抓包过程,post,get请求,和解析网页和cookie(二)

针对 android端模拟教务系统登陆,主要针对抓包过程,post,get请求,和解析网页和cookie(二)2016年8月31日09:55:41 在第一篇中我们已经实现了 抓包过程 和 模拟登陆...
  • qq_28817739
  • qq_28817739
  • 2016年08月31日 10:08
  • 579

Android 自定义View的post(Runnable)方法非100%执行的原因和处理方法解析

最近在写一个需求,需要在view.post(Runnable)方法当中进行一些操作。但是实际使用中(特定场景)发现并不靠谱。得到的现象是: 如果调用了view的post(Runnable)方法,该...
  • Xavier__S
  • Xavier__S
  • 2015年12月11日 10:56
  • 4303

Android网络通信框架Volley——自定义Request(Get、Post、文件上传)

只是想说,自己太懒了。太久没更新博客。今后有时间就要来总结下。 年初的时候,写过一篇博客,Android网络通信框架Volley初体验,这篇可真的是初体验。。。可以当作对volley初步认识,但是在实...
  • u013705351
  • u013705351
  • 2014年12月04日 16:00
  • 1852

JMeter模拟请求发送,并带上自定义Header,参数,Cookie

上篇安装好了JMeter,接下来看下使用方面,由于用的还不深入,这边介绍下基本使用。JMeter中,左侧浏览器,我们可以添加各种配置。根节点表示这次的测试计划,保存下来是个单独的jmx文件。 ...
  • difffate
  • difffate
  • 2017年06月18日 23:49
  • 3998
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android自定义携带Cookie的POST请求
举报原因:
原因补充:

(最多只允许输入30个字)