簡介:    

在前些天寫的專案中用到了Android與Apache伺服器的資料互動,即“通過HttpClient的方式向伺服器傳送請求,伺服器的Servlet接收並執行資料處理(從資料庫中提取資料),最後返回給Android平臺,平臺解析”的過程。

配置:

伺服器:Apache Tomcat v8.0

    語言版本:Java 1.8.0_66

    編譯環境:Eclipse

                    Android Studio

    呼叫jar包:httpclient-4.2.5,httpcore-4.2.4 //HttpClient父類

                     gson-2.2.4 //封裝,解析json資料

                     mysql-connector-java-5.1.37-bin //用於連線Mysql資料庫

伺服器搭建:

Eclipse新建動態Web專案(Dynamic Web Project)並且在專案中構建簡單的登陸頁面,用於測試資料庫連線性,程式碼如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form id="from" action="Login" method="post">
<table>
<tr><td>使用者名稱</td><td><input type="text" name="ID"></td></tr>
<tr><td>密碼</td><td><input type="text" name="PW"></td></tr>
<tr><td colspan="2" align="center"><input type="submit"  value="登陸"></td></tr>
</table>
</form>
</body>
</html>

    前段頁面構建完成,下面來搭建伺服器,在Java Resources下的src資料夾中新建com.DBTool包,用作資料池來連線資料庫,在包中建立DBUtil類實現功能,程式碼如下:

package com.DBTool;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.*;

public class DBUtil {
	private static String url="jdbc:mysql://localhost:3306/demodatabase";
	private static String driverClass="com.mysql.jdbc.Driver";
	private static String username="root";
	private static String password="root";
	private static Connection conn;
	//裝載驅動
	static{
		try{
			Class.forName(driverClass);
		}
		catch(ClassNotFoundException e){
			e.printStackTrace();
		}
	}
	//獲取資料庫連線
	public static Connection getConnection(){
		try{
			conn=DriverManager.getConnection(url,username,password);
		}
		catch(SQLException e){
			e.printStackTrace();
		}
		return conn;
	}
	//建立資料庫連線
	public static void main(String[] args){
		Connection conn=DBUtil.getConnection();
		if(conn==null){
			System.out.println("資料庫連線失敗!");
		}
		}
	//關閉資料庫連線
	public static void Clse(){
		if(conn!=null){
			try{
				conn.close();
			}
			catch(SQLException e){
				e.printStackTrace();
			}
		}
	}
	}

    在Java Resources下的src資料夾中新建com.Servlet包,用於存放Servlet檔案,也就是用來實現功能的伺服器檔案,在包中建立Login類,此為Servlet類。

    此時在Login類中會自動生成doGet和doPost兩種方法,我們對doPost方法中的程式碼進行刪改和新增,來實現登陸功能:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	String ID = request.getParameter("ID"); //用於接收前段輸入的ID值,此處引數須和input控制元件的name值一致
        String PW= request.getParameter("PW");//用於接收前段輸入的PW值,此處引數須和input控制元件的name值一致
        boolean type=false;//用於判斷賬號和密碼是否與資料庫中查詢結果一致
        response.setContentType("text/html; charset=UTF-8");
        PrintWriter out = response.getWriter();
        try
        {
        	Connection con=DBUtil.getConnection();
        	Statement stmt=con.createStatement();
		String sql="select * from demodatabase.demotable where uid="+ID+" and pwd="+PW;
		ResultSet rs=stmt.executeQuery(sql);
		    while(rs.next())
		    {
		    	type=true;
		    }
        }
        catch(Exception ex)
        {
        	ex.printStackTrace();
        }
        finally
        {
        	DBUtil.Close();
        	out.print(type);
        	out.flush();
        	out.close();
        }
}
    最後,在WebContent下的WEB-INF資料夾下加入xml檔案來連線servlet與jsp前端:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:web="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <servlet>
    <servlet-name>Login</servlet-name>
    <servlet-class>com.Servlet.Login</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>Login</servlet-name>
    <url-pattern>/Login</url-pattern>
  </servlet-mapping>
</web-app>

   執行伺服器,測試是否成功搭建


    返回值為true,證明伺服器工作流程正確,然後開始進行Android平臺的作業。

Android平臺登入模組:

    開啟Android Studio,新建空專案(Blank Activity),隨便布個局,搭建登入介面:

    (佈局程式碼在Demo裡)


    開啟MainActivity,開始編輯功能程式碼,在這之前需要先在lib資料夾中加入第三方jar包httpclient-4.2.5和httpcore-4.2.4,並且Add As Library。

   在onCreate方法中開始加入程式碼:

        1.獲取登入按鈕,加入監聽事件,在監聽事件中獲取所輸入的賬號和密碼,呼叫SendByHttpClient方法處理:

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button=(Button)findViewById(R.id.Login);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EditText uid=(EditText)findViewById(R.id.username);
                EditText pwd=(EditText)findViewById(R.id.password);
                String id=uid.getText().toString().trim();
                String pw=pwd.getText().toString().trim();
                SendByHttpClient(id,pw);
            }
        });
    }

  在onCreate方法外編寫SendByHttpClient方法,其中包含id和pw兩個String變數:

public void SendByHttpClient(final String id, final String pw){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    HttpClient httpclient=new DefaultHttpClient();
                    HttpPost httpPost=new HttpPost("http://192.168.191.1:8080/HttpClientDemo/Login");//伺服器地址,指向Servlet
                    List<NameValuePair> params=new ArrayList<NameValuePair>();//將id和pw裝入list
                    params.add(new BasicNameValuePair("ID",id));
                    params.add(new BasicNameValuePair("PW",pw));
                    final UrlEncodedFormEntity entity=new UrlEncodedFormEntity(params,"utf-8");//以UTF-8格式傳送
                    httpPost.setEntity(entity);
                    HttpResponse httpResponse= httpclient.execute(httpPost);
                    if(httpResponse.getStatusLine().getStatusCode()==200)//在200毫秒之內接收到返回值
                    {
                        HttpEntity entity1=httpResponse.getEntity();
                        String response=EntityUtils.toString(entity1, "utf-8");//以UTF-8格式解析
                        Message message=new Message();
                        message.what=USER_LOGIN;
                        message.obj=response;
                        handler.sendMessage(message);使用Message傳遞訊息給執行緒
                    }
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
    編寫執行緒,Message接收值,並給予顯示:
public static final int SHOW_RESPONSE=1;
    public Handler handler=new Handler() {
        public void handleMessage(Message msg)
        {
            switch (msg.what){
                case SHOW_RESPONSE:
                    String response=(String)msg.obj;
                    Toast.makeText(MainActivity.this, response, Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
            }
        }
    };

     最後在AndroidManifest.xml中加入 允許連線網路 的程式碼:

<uses-permission android:name="android.permission.INTERNET" />

   結束戰鬥,測試結果:



注:

            1.PO主採用的是真機除錯,也就是伺服器所在的計算機開wifi,用手機去連線,然後在http那裡填寫的是無線區域網介面卡的ip地址即可。

               查詢方法:在CMD中輸入ipconfig即可檢視

         2.完成程式碼後如果在Build時遇到報錯問題有可能是因為多個jar包同時指向一個log檔案所致,

               可以在Gradele Scripts裡的build.gradle(Module:app)中,找到buildTypes方法的下方新增以下程式碼解決:

packagingOptions {
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }


          最後,附上Demo的下載連結:http://download.csdn.net/detail/qq_14923661/9391639