安卓开发——如何获取网站的cookie,并将cookie发送到服务器端
一、思路
首先我创建两个活动,一个是MainActivity做主活动,另一个是WebActivity用来加载网页。网页加载完毕后,再回到主界面,通过WebViewClient内部的方法获得cookies。再通过正则表达式,将我们需要的字符串筛选出来。最终发送请求。
二、利用WebView加载网页,并获取cookie
思路:
①创建一个私有类MyWebViewClient,继承WebViewClient类
private class MyWebViewClient extends WebViewClient {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
webview.loadUrl(url);
return true;
}
public void onPageFinished(WebView view, String url) {
CookieManager cookieManager = CookieManager.getInstance();
String CookieStr = cookieManager.getCookie(url);
Log.e("song", "Cookies = " + CookieStr);
super.onPageFinished(view, url);
}
}
②再按钮点击事件中new一个MyWebViewClient的实例对象,然后调用对象中的onPageFinished方法
注:getCK是一个获取cookie的按钮对象
getCk.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(key!=null)
{
Toast.makeText(MainActivity.this,"请先登录京东", Toast.LENGTH_SHORT).show();
}
else
{
MyWebViewClient myweb=new MyWebViewClient();//创建实例对象
String url = "url";//url就是你登录的网站
myweb.onPageFinished(webView,url);//调用私有类的方法
}
}
});
三、用正则表达式从cookie中提取有用的字符串
1.首先你需要测试你的正则表达式正确与否,直接在网上搜索正则表达式测试工具。
2.在Java中使用正则表达式
创建pattern对象,执行查找,判断是否找到匹配的字符串,将匹配的字符串保存(有可能找到多个结果,用字符串数组保存)
String pattern = "(pt)(.*?)(;)";//创建pattern对象
Matcher matcher = Pattern.compile(pattern).matcher(CookieStr);//这里是临时的cookie,匹配cookie字符串
String[] numbers={"","",""};
int i=0;
while(matcher.find()) {
Log.e("match",matcher.group());
numbers[i]=matcher.group();
++i;
if(i>=3)break;//将结果都保存下来,就跳出循环
}
3.可以在获得cookie之后就进行筛选,结合如下
private class MyWebViewClient extends WebViewClient {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
public void onPageFinished(WebView view, String url) {
CookieManager cookieManager = CookieManager.getInstance();
String CookieStr = cookieManager.getCookie(url);
Log.e("sunzn", "Cookies = " + CookieStr);
String pattern = "(pt)(.*?)(;)";
Matcher matcher = Pattern.compile(pattern).matcher(CookieStr);//这里是临时的cookie
String[] numbers={"","",""};
int i=0;
while(matcher.find()) {
Log.e("match",matcher.group());
numbers[i]=matcher.group();
++i;
if(i>=3)break;
//display.setText(matcher.group());
}
key =numbers[0];
pin =numbers[1];
display.setText(key +"\n"+ pin);//将筛选后的结果显示到Textview,diaplay是一个Textview对象
super.onPageFinished(view, url);
}
}
四、把最终的字符串通过HttpURLConnection的POST方法发送到服务器
思路:
1.定义一个sendPostMessage方法,用来发送消息,参数是需要发送的字符串,编码方式,网址。(将方法定义成静态方法,无需要对象即可直接调用)
public static String sendPostMessage(String params,String encode,String address){
StringBuffer buffer = new StringBuffer();//创建缓冲区,当传输数据多的时候可以用
try {//把请求的主体写入正文!!
URL url = new URL(address);//创建URL对象
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(3000);
connection.setDoInput(true);//表示从服务器获取数据
connection.setDoOutput(true);//表示向服务器写数据
//获得上传信息的字节大小以及长度
connection.setRequestMethod("POST");
String method=connection.getRequestMethod();
//是否使用缓存
connection.setUseCaches(false);
//表示设置请求体的类型是文本类型
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
// connection.setRequestProperty("Content-Length", String.valueOf(mydata.length));
connection.connect(); //连接,不写也可以
//获得输出流,向服务器输出数据
PrintWriter pw = new PrintWriter(connection.getOutputStream());
pw.print(params);//用PrintWriter 对象可以直接写入字符串
pw.flush();
pw.close();
//获得服务器响应的结果和状态码
int responseCode = connection.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK){
//return changeInputeStream(connection.getInputStream(),encode);
return "connect success";
}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
2.发送请求的点击事件中调用sendPostMessage方法()。
注:由于发送网络请求是一个耗时的操作,所以通过在点击事件中创建子线程进行发送请求。(不能在子线程的run方法中放按钮的点击事件)
bsend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(){
@Override
public void run() {
String params;
params="XXXXXXX";
String result = sendPostMessage(params,"utf-8",url);
System.out.println("result->"+result);//输出发送消息成功后的响应
}
}.start();
}
});
五、使用HttpURLConnection发送请求的注意事项
1.如果请求没有发送成功应该怎么排查问题
①先判断发送的网址是否正确
②发送的字符串是否正确
③开发环境是否支持你使用的方法,该导的包是否导了
④有没有在AndroidManifest.xml文件声明开启网络权限
<uses-permission android:name="android.permission.INTERNET" />
⑤如果上述都没问题,就是代码逻辑问题。一步步Debug查看
2.使用HttpURLConnection发送请求的注意事项{
因为Android 6.0开始引入了对Https的推荐支持,与以往不同,Android 9.0的系统上面默认所有Http的请求都被阻止了。
解决办法:
①在res文件夹创建xml文件夹,然后在xml文件夹下创建network_security_config.xml文件
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
②在AndroidManifest.xml文件中声明以下两句
<application
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config"
</application>
3.测试post请求:在线测试网络请求
或者使用postman.