Android移动开发-使用HttpClient访问被保护资源的实现

来源:互联网 发布:linux arp命令详解 编辑:程序博客网 时间:2024/06/06 05:18

HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。

Android使用HttpClient发送请求、接收响应很简单,只要如下几步即可:
Step1:创建HttpClient对象;
Step2:如果需要发送GET请求,则创建HttpGet对象; 如果需要发送POST请求,则创建HttpPost对象;
Step3:如果需要发送请求参数,则可调用HttpGet、HttpPost共同的setParams(HttpParams params)方法来添加请求参数;对于HttpPost对象而言,也可以调用setEntity(HttpEntity entity)方法来设置请求参数;
Step4:调用HttpClient对象的execute(HttpUriRequest request)方法发送请求,执行该方法返回一个HttpResponse;
Step5:调用HttpResponse的getAllHeader()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。

为了通过HttpClient来访问被保护页面,程序Demo同样需要使用HttpClient来登录系统,只要应用程序使用同一个HttpClient发送请求,HttpClient就会自动维护与服务器之间的Session状态。也就是说,程序第一次使用HttpClient登录系统后,接下来使用HttpClient即可访问被保护页面了。

  • 注意:在现在的Android开发中Google已经不推荐使用HttpClient了,所以如果要想使用HttpClient开发的话,必须手动在AndroidStudio的libs文件下导入HttpClient的相关的jar包(所需的HttpClient相关jar包下载地址)。导入HttpClient的相关的jar包图文教程如下所示:

1、打开Project—>app—>libs,导入HttpClient的相关的jar包;

这里写图片描述

2、打开Project—>app—>build.gradle,在build.gradle里的dependencies {……}添加相关jar包的依赖项:
compile files(‘libs/httpclient-4.5.jar’)
compile files(‘libs/httpcore-4.4.1.jar’)

这里写图片描述

3、打开Project—>app—>build.gradle,在build.gradle里的android {……}添加相关jar包的配置:
packagingOptions {
exclude ‘META-INF/DEPENDENCIES’
exclude ‘META-INF/NOTICE’
exclude ‘META-INF/LICENSE’
exclude ‘META-INF/LICENSE.txt’
exclude ‘META-INF/NOTICE.txt’
}

引用块内容

  • layout/activity_main.xml界面布局代码如下:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:gravity="center_horizontal"        android:orientation="horizontal">        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:onClick="accessSecret"            android:text="访问页面" />        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:onClick="showLogin"            android:text="登录系统" />    </LinearLayout>    <TextView        android:id="@+id/response"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:background="#ffff"        android:gravity="top"        android:textColor="#f000"        android:textSize="16dp" /></LinearLayout>
  • layout/login.xml界面布局代码如下:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal">        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:width="90dp"            android:text="用户名" />        <EditText            android:id="@+id/name"            android:layout_width="match_parent"            android:layout_height="wrap_content" />    </LinearLayout>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal">        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:width="90dp"            android:text="密   码" />        <EditText            android:id="@+id/pass"            android:layout_width="match_parent"            android:layout_height="wrap_content" />    </LinearLayout></LinearLayout>
  • MainActivity.java逻辑代码如下:
package com.fukaimei.httpclienttest;import android.app.AlertDialog;import android.content.DialogInterface;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.NameValuePair;import org.apache.http.client.HttpClient;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.message.BasicNameValuePair;import org.apache.http.protocol.HTTP;import org.apache.http.util.EntityUtils;import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {    TextView response;    HttpClient httpClient;    Handler handler = new Handler() {        public void handleMessage(Message msg) {            if (msg.what == 0x123) {                // 使用response文本框显示服务器响应                response.append(msg.obj.toString() + "\n");            }        }    };    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // 创建DefaultHttpClient对象        httpClient = new DefaultHttpClient();        response = (TextView) findViewById(R.id.response);    }    public void accessSecret(View v) {        response.setText("");        new Thread() {            @Override            public void run() {                // 创建一个HttpGet对象                HttpGet get = new HttpGet("http://172.xx.xx.xxx:8080/fukaimei/secret.jsp");  // ①                try {                    // 发送GET请求                    HttpResponse httpResponse = httpClient.execute(get);  // ②                    HttpEntity entity = httpResponse.getEntity();                    if (entity != null) {                        // 读取服务器响应                        BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent()));                        String line = null;                        while ((line = br.readLine()) != null) {                            Message msg = new Message();                            msg.what = 0x123;                            msg.obj = line;                            handler.sendMessage(msg);                        }                    }                } catch (Exception e) {                    e.printStackTrace();                }            }        }.start();    }    public void showLogin(View v) {        // 加载登录界面        final View loginDialog = getLayoutInflater().inflate(R.layout.login, null);        // 使用对话框供用户登录系统        new AlertDialog.Builder(MainActivity.this).setTitle("登录系统").setView(loginDialog)                .setPositiveButton("登录", new DialogInterface.OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog, int which) {                        // 获取用户输入的用户名、密码                        final String name = ((EditText) loginDialog                                .findViewById(R.id.name)).getText().toString();                        final String pass = ((EditText) loginDialog.findViewById(R.id.pass)).getText().toString();                        new Thread() {                            @Override                            public void run() {                                try {                                    HttpPost post = new HttpPost("http://172.xx.xx.xxx:8080/fukaimei/login.jsp"); //③                                    // 如果传递参数个数比较多,可以对传递的参数进行封装                                    List<NameValuePair> params = new ArrayList<>();                                    params.add(new BasicNameValuePair("name", name));                                    params.add(new BasicNameValuePair("pass", pass));                                    // 设置请求参数                                    post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));                                    // 发送POST请求                                    HttpResponse response = httpClient.execute(post);  //④                                    // 如果服务器成功地返回响应                                    if (response.getStatusLine().getStatusCode() == 200) {                                        String msg = EntityUtils.toString(response.getEntity());                                        Looper.prepare();                                        // 提示登录成功                                        Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();                                        Looper.loop();                                    }                                } catch (Exception e) {                                    e.printStackTrace();                                }                            }                        }.start();                    }                }).setNegativeButton("取消", null).show();    }}

上面程序Demo的①、②号代码先创建了一个HTTPGet对象,接下来程序调用HttpClient的execute()方法发送GET请求;程序③、④号代码先创建了一个HttpPost对象,接下来程序调用了HttpClient的execute()方法发送POST请求。上面的GET请求用于获取服务器上的被保护页面,POST请求用于登录系统。

  • 注意:由于该程序需要访问互联网,因此还需要在清单文件AndroidManifest.xml文件中授权访问互联网的权限:
<!--  授权访问互联网-->    <uses-permission android:name="android.permission.INTERNET" />
  • Demo程序运行效果界面截图如下:

这里写图片描述

这里写图片描述

这里写图片描述

  • 服务器secret.jsp代码:
<%@ page contentType="text/html; charset=utf-8" language="java" errorPage="" %><%Object user = session.getAttribute("user");if(user != null && user.toString().trim().equals("XXX")) {%><!DOCTYPE html><html><head>    <meta name="author" content="XXX" />    <meta http-equiv="Content-Type" content="text/html; charset=GBK" />    <title> 安全资源 </title></head><body>    安全资源,只有登录用户<br/>    且用户名是crazyit.org才可访问该资源</body></html><% } else {    out.println("您没有被授权访问该页面"); }%>
  • 服务器login.jsp代码:
<%@ page contentType="text/html; charset=utf-8" language="java" errorPage="" %><%String name = request.getParameter("name");String pass = request.getParameter("pass");if (name.equals("XXX")    && pass.equals("XXX")) {    session.setAttribute("user" , name);    out.println("恭喜您,登录成功!");} else {    out.println("对不起,用户名、密码不符合!");}%>

Demo程序源码下载地址

阅读全文
1 0