您的位置:首页 > 移动开发 > Android开发

Android自定义携带Cookie的POST请求

2015-11-17 20:30 274 查看

发送请求

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

设置参数

设置请求链接

获得返回值

一般来说,我们使用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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android cookie 框架