Android模拟器通过http连接mysql数据库实现登录

前言

数据库大作业是用Android写了一个学生管理系统,后台是用的sqlite,相当于一个app每次安装都带着一个SQLITE数据库跑,但是这样并不是当今主流app的实现方式,在互联网时代,不联网是不行的(这里共享数据的联网)。
Android模拟器通过http连接mysql数据库实现登录_第1张图片
效果显示

连接服务器数据库的方式

1.通过java的JDBC连接服务器上的数据库/本地数据库

2.通过http连接服务器上的数据库

毫无疑问,第二种方式是常用的也是推荐的,因为http的方式可以保证传输数据的安全性,并且减轻服务器的压力。如果用jdbc你相当于直接连接的服务器上的数据库,第二种是你向服务器发送数据,服务器帮你验证。

如何通过http连接服务器上的数据库?

首先,你应该把app当成浏览器一样的存在,学过javaWeb中jsp的同学可能了解或使用过request、response对象在http请求中接收数据和发送数据,没错,app也是这样http连接的。

JSP中,你的步骤可能是这样的:

Android模拟器通过http连接mysql数据库实现登录_第2张图片
Login可以接受用户输入,提供表单给Servlet对象,Servlet通过接收到的request对象获取用户输入,最后进行逻辑处理。

APP中http连接服务器上mysql数据库的过程也大同小异:
Android模拟器通过http连接mysql数据库实现登录_第3张图片

你需要提前了解的准备事项

环境准备:

Tomacat服务器配置

mysql配置,其中新建一个数据库+一张用于存放账户信息的表。

代码实现

服务器端:

LoginServlet.java,“中转站”,用于处理Get请求/Post请求和返回数据。



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

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import loginDem.DBUtil;

/**
 * Servlet implementation class LoginServlet
 */
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    
    public LoginServlet() {
        super();
       
    }
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
				//接受客户端信息
				if(request!=null)
				{
					String username = "";
					
					username = request.getParameter("username");
					
					username = new String(username.getBytes("ISO-8859-1"),"UTF-8");
					
					String password = "";
					
					password =request.getParameter("password");
					
					password = new String(password.getBytes("ISO-8859-1"),"UTF-8");
				
					PrintWriter out = null;
					
					System.out.println(username+" "+password);
					
					if(DBUtil.isRight(username, password))
					{
						
						System.out.println("密码正确");
			            // 返回信息到客户端
			            response.setCharacterEncoding("UTF-8");
			            
			            response.setContentType("text/html");
			            
			            
			            out = response.getWriter();
			            
			            out.print("success");   
					}
					else
					{
							
						System.out.println("error");
						
					}
					out.flush();
					out.close();
			
				}
				else {
					System.out.println("request为空");
				}
				
	}

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		doGet(request, response);
	}

}

DBUtil.java,用于声明一些操作数据库的公共方法。

package loginDem;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/** 
* @author 作者 WuYueHang: 
* @version 创建时间:2019年6月22日 下午7:37:15 
* 类说明 
*/
public class DBUtil {
	public static void insertUser(String username, String password,int age ,String sex )
	{
		String sql = "insert into user values(?,?,?,?);";
		
		try {
			PreparedStatement statement = DBConnection.getPreparedStatement(sql);
			
			statement.setString(1, username);
			
			statement.setString(2, password);
			
			statement.setInt(3, age);
			
			statement.setString(4, sex);
			
			statement.executeUpdate();
			
		} catch (SQLException e) 
		{
			e.printStackTrace();
		}
	}
	public static boolean judgeIsExist(String username)
	{
		String sql = "select username  from user where username = ?";
		
		try {
			
			PreparedStatement statement = DBConnection.getPreparedStatement(sql);
			
			statement.setString(1, username);
			
			statement.executeQuery();
			
			ResultSet rs = statement.getResultSet();
			
			if(!rs.next())
			{
				return false;
			}
			else 
			{
				
				return true;
				
			}
		} catch (Exception e)
		{
			
			e.printStackTrace();
		}
		
		
		return false;
	}
	public static boolean isRight(String username,String password)
	{
		String sql = "select * from user where username = ?";
		
		try {
			
			PreparedStatement statement = DBConnection.getPreparedStatement(sql);
			
			statement.setString(1, username);
			
			statement.executeQuery();
			
			ResultSet rs = statement.getResultSet();
			
			//如果根本就不存在这个用户名
			if(!rs.next())
			{
				return false;
			}
			else 
			{
				//如果密码正确的话
				if(password.equals(rs.getString(2)))
				{
					return true;
				}
				else {
					
					return false;
				}
				
			}
		} 
		catch (Exception e)
		{
			
			e.printStackTrace();
		}
		
		return false;
	}
}

DBConnection.java 用于获得连接数据库的Connection对象,我在这里更进一步,通过传入sql语句获取PreparedStatement对象。

package loginDem;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;


/**
* @author 作者 WuYueHang: 
* @version 创建时间:2019年6月22日 下午7:39:20 
* 类说明 
*/
public class DBConnection {
	public static PreparedStatement getPreparedStatement(String sql) {
		
		//temp是我的数据名称,大家可以替换为自己的数据库名称,再后是时区表示,不然会报异常
		String url = "jdbc:mysql://localhost:3306/temp?serverTimezone=GMT%2B8";
		
		//登录数据库的账号和密码
		String username = "root";
		
		String password = "123456";
		
		PreparedStatement statement = null;
		/////////////
		try {
			
		
		//反射加载jdbc的Driver类
		Class.forName("com.mysql.cj.jdbc.Driver");
		
		//通过DriverManager获取Connection对象
		Connection con = DriverManager.getConnection(url,username,password);
		
		//通过PrepardStatement 准备sql语句
		 statement= con.prepareStatement(sql);
		
	
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
		return statement;
	}
	
	
//	//用于调试,判断自己连接是否有问题
//	public static void main(String[] args)
//	{
//		PreparedStatement statement = getPreparedStatement("select * from offices" );
//		
//		ResultSet rs;
//		
//		int Count=0;
//		try {
//			rs = statement.executeQuery();
//			
//			
//			ResultSetMetaData rsmd = rs.getMetaData();
//			
//			Count= rsmd.getColumnCount();
//		} catch (SQLException e) {
//			
//			e.printStackTrace();
//		}
//		
//		
//		
//		System.out.println(Count);
//	}
}

最后我们需要打包成war包以部署项目到我们的Tomcat服务器上。

在eclipse中,右键项目名->导出->war file

从刚刚保存的路径中,复制war包到Tomacat的WebApp下。

客户端实现
WebServiceGet.java

package com.example.httpmysql;

import java.io.BufferedReader;

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{
            //声明我们Servlet的地址
            String Url = "http://10.0.2.2:8080/AndroidLoginDemo/" + address;

            String path = Url + "?username=" + username + "&password=" + password;
            try {
                URL url = new URL(path);

                connection = (HttpURLConnection)url.openConnection();

                //使用GET方式,因为我们是验证登录,是在取数据,效率更高一些
                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 "error";
    }

    //得到字节输入流,将字节输入流转化为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 "error";
    }
}

MainActivity.java

package com.example.httpmysql;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private EditText username;
    private TextInputLayout inputOne;
    private EditText password;
    private TextInputLayout inputTwo;
    private Button buttonLogin;
    private ProgressDialog dialog;

    private String infoString;


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

    private void initView() {
        username = (EditText) findViewById(R.id.username);
        inputOne = (TextInputLayout) findViewById(R.id.input_one);
        password = (EditText) findViewById(R.id.password);
        inputTwo = (TextInputLayout) findViewById(R.id.input_two);
        buttonLogin = (Button) findViewById(R.id.button_login);

        buttonLogin.setOnClickListener(this);
    }

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

                //设置子线程,分别进行Get和Post传输数据

                new Thread(new MyThread()).start();

                break;
        }
    }




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

            infoString = WebServiceGet.executeHttpGet(username.getText().toString(),password.getText().toString(),"LoginServlet");//获取服务器返回的数据
            dialog.dismiss();

          	//更新界面UI需要使用runOnUiThread方法
           runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if(infoString.equals("success"))
                    {
                        Toast.makeText(MainActivity.this,"登陆成功", Toast.LENGTH_SHORT).show();
                    }
                    else
                    {
                        Toast.makeText(MainActivity.this,"登陆失败", Toast.LENGTH_SHORT).show();
                    }

                }
            });
        }
    }

}


activity_main.xml,布局文件


<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <android.support.design.widget.TextInputLayout
            android:layout_marginTop="20dp"
            android:id="@+id/input_one"
            android:layout_width="match_parent"
            app:counterEnabled="true"
            app:counterMaxLength="10"


            android:hint="请输入您的账户"
            app:errorEnabled="true"

            android:layout_height="wrap_content">

            <EditText
                android:id="@+id/username"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:drawableStart="@drawable/ren"

                android:inputType="text" />
        android.support.design.widget.TextInputLayout>

        <android.support.design.widget.TextInputLayout
            android:id="@+id/input_two"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:focusable="true"
            android:layout_below="@+id/input_one"

            android:hint="请输入密码"

            android:focusableInTouchMode="true"
            android:gravity="center_vertical"
            app:counterEnabled="true"
            app:counterMaxLength="10"
            app:errorEnabled="true"
            app:passwordToggleEnabled="true"
            android:orientation="vertical">

            <EditText
                android:id="@+id/password"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:drawableStart="@drawable/mima"
                android:inputType="textPassword" />
        android.support.design.widget.TextInputLayout>

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/button_login"
            android:text="登录"/>



    LinearLayout>

LinearLayout>

注意:

1.在模拟器上运行时,地址要写http://10.0.2.2:8080/,这个地址是安卓内置的,而不是127.0.0.1:8080.

2.你需要在imanfest文件中声明权限

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

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

3.谷歌在高版本的安卓系统中,http不再被允许传输数据,而是推荐用https

在这里我们依旧使用http,并且提供暴力破解法:

在Aplication中添加如下一个属性

<application android:usesCleartextTraffic="true"/>

4.笔者这里的输入框使用了Design库的TextInputLayout,如果觉得好看的请移步我的另外一个博客:
TextlnputLayout使用及其属性

参考文章

你可能感兴趣的:(Android,数据库,JAVA)