Android通过Http连接MySql数据库(servlet服务器)

借鉴原文地址:http://www.cnblogs.com/yzxk/p/4749440.html


先看两个概念:

1.android连接数据库的方式有两种

       1.通过连接服务器,再由服务器读取数据库来实现数据的增删改查,这也是我们常用的方式。

       2.android直接连接数据库,这种方式非常耗手机内存,而且容易被反编译造成安全隐患,所以在实际项目中不推荐使用。

2.连接服务器方式: http通信 、 Socket通信

Http通信:GET方式、POST方式

GET方式和POST方式的区别:

前者通过Http消息实体发送数据给服务器,安全性高,数据传输大小没有限制,后者通过URL的查询字符串传递给服务器参数,以明文显示在浏览器地址栏,保密性差,最多传输2048个字符。但是GET请求并不是一无是处——GET请求大多用于查询(读取资源),效率高。POST请求用于注册、登录等安全性较高且向数据库中写入数据的操作。

除了POST和GET,http通信还有其他方式!请参见http请求的方法。


Http与Scoket区别:

简单理解:一个单向,一个双向。(具体了解,自行google)


开发环境部署:

程序结构:

android+servlet+service+mysql

仅供参考:能实现相关功能即可

操作系统:win10

数据库:mysql    数据库工具:Navicat for MySql

服务器:tomcat      服务器工具: eclipse

安卓端:genymotion虚拟机  安卓端工具:Android Studio


数据库设计:



服务器设计:

1、新建Web Project,命名为HelloWeb

2、项目结构图如下:

 LogLet类和RegLet类分别用于处理客户端的登陆和注册请求;Service类用于完成servlet对数据库的具体操作;DBManager类用于进行数据库基本操作;

 左侧是项目图,右侧是web.xml配置文件截图。

   

3、项目代码:

 DBManager.java

 <1> 单例模式构建DBManager对象;       

 <2> 定义数据库连接、关闭以及增删改查的基本操作,返回结果集。


package com.db;

import java.sql.*;

public class DBManager {

    // 数据库连接常量
    public static final String DRIVER = "com.mysql.jdbc.Driver";
    public static final String USER = "root";
    public static final String PASS = "root";
    public static final String URL = "jdbc:mysql://localhost:3306/test";

    // 静态成员,支持单态模式
    private static DBManager per = null;
    private Connection conn = null;
    private Statement stmt = null;

    // 单态模式-懒汉模式
    private DBManager() {
    }

    public static DBManager createInstance() {
        if (per == null) {
            per = new DBManager();
            per.initDB();
        }
        return per;
    }

    // 加载驱动
    public void initDB() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 连接数据库,获取句柄+对象
    public void connectDB() {
        System.out.println("Connecting to database...");
        try {
            conn = DriverManager.getConnection(URL, USER, PASS);
            stmt = conn.createStatement();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        System.out.println("SqlManager:Connect to database successful.");
    }

    // 关闭数据库 关闭对象,释放句柄
    public void closeDB() {
        System.out.println("Close connection to database..");
        try {
            stmt.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        System.out.println("Close connection successful");
    }

    // 查询
    public ResultSet executeQuery(String sql) {
        ResultSet rs = null;
        try {
            rs = stmt.executeQuery(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return rs;
    }

    // 增添/删除/修改
    public int executeUpdate(String sql) {
        int ret = 0;
        try {
            ret = stmt.executeUpdate(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return ret;
    }
}

LogLet.java

  一个简单的Servlet,用于处理Http请求(get/post)。

package com.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.service.Service;

public class LogLet extends HttpServlet{

	private static final long serialVersionUID = 9036889586892331384L;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		//接受客户端信息
		String username = request.getParameter("username");
		username = new String(username.getBytes("ISO-8859-1"),"UTF-8");
		String password = request.getParameter("password");
		password = new String(password.getBytes("ISO-8859-1"),"UTF-8");
		System.out.println(username + ":" + password);
		
		//新建服务对象
		Service service = new Service();
		
		//验证处理
		boolean log = service.login(username, password);
		if( log ){
			System.out.println("log success");
			//request.getSession().setAttribute("username", username);
		}else{
			System.out.println("log fail");
		}
		
		//返回信息到客户端
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		if( log ){
			out.print("用户名:" + username);
			out.print("密码: " + password);
		}else{
			out.print("false");
		}
		out.flush();
		out.close();
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO 自动生成的方法存根

	}

}

RegLet.java

  一个简单的Servlet,用于处理Http请求(get/post)。

package com.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.service.Service;

public class RegLet extends HttpServlet{

	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO 自动生成的方法存根
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO 自动生成的方法存根
		//接受客户端信息
				String username = request.getParameter("username");
				username = new String(username.getBytes("ISO-8859-1"),"UTF-8");
				String password = request.getParameter("password");
				System.out.println(username + ":" + password);
				
				//新建服务对象
				Service service = new Service();
					
				//验证处理
				boolean reg = service.register(username, password);
				if( reg ){
					System.out.println("reg success");
					//request.getSession().setAttribute("username", username);
				}else{
					System.out.println("reg fail");
				}
					
				//返回信息到客户端
				response.setCharacterEncoding("UTF-8");
				response.setContentType("text/html");
				PrintWriter out = response.getWriter();
				if(reg){
					out.print("true");
				}else{
					out.print("false");
				}
				out.flush();
				out.close();
	}

}

客户端设计:

现在开始思考需要什么东西... 

 <1> 登陆和注册页面:布局文件

   login.xml , register.xml

 <2> 登陆和注册页面对应的Activity组件,在activity中进行具体操作

   login.java , register.java

 <3> 能够实现Http以get/post方式通信的类

   WebService.java , WebServicePost.java

 <4> 网络通信权限

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

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

项目结构和AndroidMainfest.xml:

界面(极为简陋,按个人自行喜好设定):

登陆界面:


注册界面:



在服务器端编程时我们了解到:服务器端接收客户端发送的信息,对信息进行一系列处理后,最终信息返回到客户端。

  首先要想的,就是获取信息并发送出去,然后接收信息并显示出来。

 (网络服务由于耗时问题,放在主线程很可能由于网络故障导致ANR;所以要开辟子线程留给http网络服务。当然不使用主线程也可以,只是不推荐)


代码:

Login.java 有两点需要注意

  第一个是在子线程中,不能更改主线程的页面值,这里用了handle解决。

  第二个是这里有get/post两种http请求方式,两个实现类,。

package android.zdd.com.consql;

import android.app.ProgressDialog;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.zdd.com.web.WebServiceGet;

public class Login extends AppCompatActivity implements View.OnClickListener{

    private EditText username;
    private EditText password;
    private Button login;
    private TextView info;
    private TextView register;
    //提示框
    private ProgressDialog dialog;
    //服务器返回的数据
    private String infoString;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        //初始化信息
        username = (EditText)findViewById(R.id.username);
        password = (EditText)findViewById(R.id.password);
        login = (Button)findViewById(R.id.btn_login);
        info = (TextView)findViewById(R.id.info);
        register = (TextView)findViewById(R.id.register);

        //设置按钮监听器
        login.setOnClickListener(this);
        register.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_login:
                //设置提示框
                dialog = new ProgressDialog(Login.this);
                dialog.setTitle("正在登陆");
                dialog.setMessage("请稍后");
                dialog.setCancelable(false);//设置可以通过back键取消
                dialog.show();

                //设置子线程,分别进行Get和Post传输数据
                new Thread(new MyThread()).start();

                break;
            case R.id.register:
                //跳转注册页面
                Intent intent = new Intent(Login.this,Register.class);
                startActivity(intent);
                break;
        }
    }

    public class MyThread implements Runnable{
        @Override
        public void run() {
            infoString = WebServiceGet.executeHttpGet(username.getText().toString(),password.getText().toString(),"LogLet");//获取服务器返回的数据

            //更新UI,使用runOnUiThread()方法
            showResponse(infoString);
        }
    }
    private void showResponse(final String response){
        runOnUiThread(new Runnable() {
            //更新UI
            @Override
            public void run() {
                if(response.equals("false")){
                    Toast.makeText(Login.this,"登陆失败!", Toast.LENGTH_SHORT).show();
                }else {
                    info.setText(response);
                }
                dialog.dismiss();
            }
        });
    }
}

Register.java

package android.zdd.com.consql;

import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.preference.DialogPreference;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.zdd.com.web.WebServiceGet;
import android.zdd.com.web.WebServicePost;

public class Register extends AppCompatActivity implements View.OnClickListener{

    private EditText regUserName;
    private EditText regPassWord;
    private Button btn_reg;

    ProgressDialog dialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        //修改标题栏title
        ActionBar ac = getSupportActionBar();
        ac.setTitle("注册");

        //初始化
        regUserName = (EditText)findViewById(R.id.regUserName);
        regPassWord = (EditText)findViewById(R.id.regPassWord);
        btn_reg = (Button)findViewById(R.id.btn_reg);

        btn_reg.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_reg:
                dialog = new ProgressDialog(Register.this);
                dialog.setTitle("正在注册");
                dialog.setMessage("请稍后");
                dialog.show();

                new Thread(new RegThread()).start();
                break;
        }
    }

    public class RegThread implements Runnable{
        @Override
        public void run() {

            //获取服务器返回数据
            //String RegRet = WebServiceGet.executeHttpGet(regUserName.getText().toString(),regPassWord.getText().toString(),"RegLet");
            String RegRet = WebServicePost.executeHttpPost(regUserName.getText().toString(),regPassWord.getText().toString(),"RegLet");

            //更新UI,界面处理
            showReq(RegRet);
        }
    }
    private void showReq(final String RegRet){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if(RegRet.equals("true")){
                    dialog.dismiss();
                    AlertDialog.Builder builder = new AlertDialog.Builder(Register.this);
                    builder.setTitle("注册信息");
                    builder.setMessage("注册成功");
                    builder.setCancelable(false);
                    builder.setPositiveButton("OK",new DialogInterface.OnClickListener(){
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            Intent intent = new Intent(Register.this,Login.class);
                            startActivity(intent);
                        }
                    });
                    builder.show();
                }else{
                    dialog.dismiss();
                    AlertDialog.Builder builder = new AlertDialog.Builder(Register.this);
                    builder.setTitle("注册信息");
                    builder.setMessage("注册失败");
                    builder.setCancelable(false);
                    builder.setPositiveButton("OK",new DialogInterface.OnClickListener(){
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            Intent intent = new Intent(Register.this,Login.class);
                            startActivity(intent);
                        }
                    });
                    builder.show();
                }
            }
        });
    }
}

WebServiceGet.java  (Get实现) 

  这里的IP是你的服务器IP,就是你电脑的IP,cmd -> ipconfig查看本机IP地址。

import android.util.Log;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * 使用get方法获取Http服务器数据
 */

public class WebServiceGet {

    public static String executeHttpGet(String username,String password,String address){
        HttpURLConnection connection = null;
        InputStream in = null;

        try{
            String Url = "http://169.254.58.31:8080/HelloWeb/" + address;
            String path = Url + "?username=" + username + "&password=" + password;
            try {
                URL url = new URL(path);
                connection = (HttpURLConnection)url.openConnection();
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(10000);//建立连接超时
                connection.setReadTimeout(8000);//传递数据超时

                in = connection.getInputStream();
                return parseInfo(in);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //意外退出时,连接关闭保护
            if(connection != null){
                connection.disconnect();
            }
            if(in != null){
                try{
                    in.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    //得到字节输入流,将字节输入流转化为String类型
    public static String parseInfo(InputStream inputStream){
        BufferedReader reader = null;
        String line = "";
        StringBuilder response = new StringBuilder();

        try {
            reader = new BufferedReader(new InputStreamReader(inputStream));
            while((line = reader.readLine()) != null){
                response.append(line);
            }
            return response.toString();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(reader != null){
                try{
                    reader.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

WebServicePost.java  (Post实现) 

  这里的IP是你的服务器IP,就是你电脑的IP,cmd -> ipconfig查看本机IP地址。


package android.zdd.com.web;

import android.util.Log;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;

/**
 * 使用Post方法获取Http服务器数据
 */

public class WebServicePost {

     public static String executeHttpPost(String username,String password,String address){
        HttpURLConnection connection = null;
        InputStream in = null;

        try{
            String Url = "http://169.254.58.31:8080/HelloWeb/" + address;
            try {
                URL url = new URL(Url);
                connection = (HttpURLConnection)url.openConnection();

                connection.setDoInput(true);
                connection.setDoOutput(true);
                connection.setRequestMethod("POST");
                connection.setReadTimeout(8000);//传递数据超时

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

                connection.connect();

                DataOutputStream out = new DataOutputStream(connection.getOutputStream());
                String data = "username=" + URLEncoder.encode(username,"UTF-8") + "&password=" + URLEncoder.encode(password,"UTF-8");
                out.writeBytes(data);
                out.flush();
                out.close();

                int resultCode = connection.getResponseCode();
                if(HttpURLConnection.HTTP_OK == resultCode) {
                    in = connection.getInputStream();
                    return parseInfo(in);
                }
                return null;
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //意外退出时,连接关闭保护
            if(connection != null){
                connection.disconnect();
            }
            if(in != null){
                try{
                    in.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
    //得到字节输入流,将字节输入流转化为String类型
    public static String parseInfo(InputStream inputStream){
        BufferedReader reader = null;
        String line = "";
        StringBuilder response = new StringBuilder();

        try {
            reader = new BufferedReader(new InputStreamReader(inputStream));
            while((line = reader.readLine()) != null){
                Log.d("RegisterActivity",line);
                response.append(line);
            }
            Log.d("RegisterActivity","response.toString():"+response.toString());
            return response.toString();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(reader != null){
                try{
                    reader.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

运行效果:

略。。。经测试可以成功,记得服务器本地附上mysql-jdbc.jar包

  • 32
    点赞
  • 260
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值