学习服务器与数据库(4)

本系列的学习的资料主要来自衷水木先生的博客。本节将调通APP的注册功能与登录功能,实现简单的逻辑。

    很明显,想要 Android 和服务器进行交互,必然要使用到网络,为了解决后顾之忧,我们先下手为强,在 Manifest 文件中声明网络访问权限:

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

网络通信属于典型的耗时操作,开启新线程进行网络请求 。衷水木先生的博客中使用了AsyncTask机制,这是个封装过的后台任务类,相对于 Handler 更轻量,适用于简单的异步UI处理。但是由于需要对返回值进行判断,因此我们采用Handler的消息机制进行得到网络请求的结果。

(一)Android 和 Servlet 服务器通过 HTTP GET 模式进行交互

处理“注册”逻辑的Servlet:

RegisterServlet.java

package servlet;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;

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 com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;

/**
 * Servlet implementation class RegisterServlet
 */
@WebServlet(description = "用于注册的Servlet", urlPatterns = { "/RegisterServlet" })
public class RegisterServlet extends HttpServlet {  
    private static final long serialVersionUID = 1L;  
  
    /** 
     * Default constructor. 
     */  
    public RegisterServlet() {  
        LogUtil.log("RegisterServlet construct...");  
    }  
  
    @Override  
    protected void service(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        String method = request.getMethod();  
        if ("GET".equals(method)) {  
            LogUtil.log("请求方法:GET");  
            doGet(request, response);  
        } else if ("POST".equals(method)) {  
            LogUtil.log("请求方法:POST");  
            doPost(request, response);  
        } else {  
            LogUtil.log("请求方法分辨失败!");  
        }  
    }  
  
    /** 
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse 
     *      response) 
     */  
    protected void doGet(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        String code = "";  
        String message = "";  
  
        String account = request.getParameter("account");  
        String password = request.getParameter("password");  
        LogUtil.log(account + ";" + password);  
  
        Connection connect = DBUtil.getConnect();  
        try {  
            Statement statement = (Statement) connect.createStatement();  
            String sql = "select userAccount from " + DBUtil.Table_Account + " where userAccount='" + account + "'";  
            LogUtil.log(sql);  
            ResultSet result = statement.executeQuery(sql);  
            if (result.next()) { // 能查到该账号,说明已经注册过了  
                code = "100";  
                message = "Exit Account";  
            } else {  
                String sqlInsert = "insert into " + DBUtil.Table_Account + "(userAccount, userPassword) values('"  
                        + account + "', '" + password + "')";  
                LogUtil.log(sqlInsert);  
                if (statement.executeUpdate(sqlInsert) > 0) { // 否则进行注册逻辑,插入新账号密码到数据库  
                    code = "200";  
                    message = "Signup Success";  
                } else {  
                    code = "300";  
                    message = "Signup Failed";  
                }  
            }  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }  
  
        response.getWriter().append("code:").append(code).append(";message:").append(message);  
    }  
  
    /** 
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse 
     *      response) 
     */  
    protected void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
  
    }  
  
    @Override  
    public void destroy() {  
        LogUtil.log("RegisterServlet destory.");  
        super.destroy();  
    }  
}

处理“登录”逻辑的Servlet:

LoginServlet.java

package servlet;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;

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 com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;

/**
 * Servlet implementation class LoginServlet
 */
@WebServlet(description = "用于登录的Servlet", urlPatterns = { "/LoginServlet" })
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public LoginServlet() {
		super();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		String code = "";
		String message = "";

		
		String account = request.getParameter("account");
		String password = request.getParameter("password");
		LogUtil.log(account + ";" + password);

		Connection connect = DBUtil.getConnect();
		try {
			Statement statement = (Statement) connect.createStatement();
			String sql = "select userAccount from " + DBUtil.Table_Account + " where userAccount='" + account
					+ "' and userPassword='" + password + "'";
			LogUtil.log(sql);
			ResultSet result = statement.executeQuery(sql);
			if (result.next()) { // 能查到该账号,说明已经注册过了
				code = "200";
				message = "Login Success";
			} else {

				code = "100";
				message = "Login Failed,Wrong password or unsigned account";
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

		response.getWriter().append("code:").append(code).append(";message:").append(message);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		LogUtil.log("不支持POST方法");
	}

}
接下来是Android客户端的代码:

常量类

Constant.java

package edu.hdu.lyy.model;

public class Constant {
    public static String URL = "http://192.168.0.139:8080/TeachingServer/"; // IP地址请改为你自己的IP

    public static String URL_Register = URL + "RegisterServlet";
    public static String URL_Login = URL + "LoginServlet";
}

NetWork.java

package edu.hdu.lyy.adapter;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

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;

/**
 * Created by wch on 2018/3/24.
 */

public class NetWork {
    private Handler handler;
    private String url;

    public NetWork(Handler h, String u)
    {
        handler = h;
        url = u;
    }

    public void GetMessage(final String account, final String password)
    {
        new Thread(new Runnable() {
            @Override
            public void run() {
                String UrlStr = url + "?account=" + account + "&password=" + password;

                Log.w("Log", "GetMessage Thread" + UrlStr);
                HttpURLConnection connection = null;
                StringBuilder response = new StringBuilder();
                try {
                    URL url = new URL(UrlStr); // 声明一个URL,注意如果用百度首页实验,请使用https开头,否则获取不到返回报文
                    connection = (HttpURLConnection) url.openConnection(); // 打开该URL连接
                    connection.setRequestMethod("GET"); // 设置请求方法,“POST或GET”,我们这里用GET,在说到POST的时候再用POST
                    connection.setConnectTimeout(80000); // 设置连接建立的超时时间
                    connection.setReadTimeout(80000); // 设置网络报文收发超时时间
                    InputStream in = connection.getInputStream();  // 通过连接的输入流获取下发报文,然后就是Java的流处理
                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line);
                    }

                    Message msg = new Message();
                    msg.what = 1;
                    msg.obj = response;
                    handler.sendMessage(msg);
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

注册界面的代码,与之前的注册界面代码相比,主要修改了login函数并增加了loginHandler:

LoginActivity.java

package edu.hdu.lyy.activity;

/**
 * Created by wch on 2018/3/18.
 */

import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import android.content.Intent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import edu.hdu.lyy.adapter.NetWork;
import edu.hdu.lyy.teaching.R;

import static edu.hdu.lyy.model.Constant.URL_Login;
import static edu.hdu.lyy.model.Constant.URL_Register;


public class LoginActivity extends AppCompatActivity {
    private static final String TAG = "LoginActivity";
    private static final int REQUEST_SIGNUP = 0;

    EditText emailText;
    EditText passwordText;
    Button loginButton;
    TextView signupLink;
    ProgressDialog progressDialog;

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

        emailText = (EditText)findViewById(R.id.input_email);
        passwordText = (EditText)findViewById(R.id.input_password);
        loginButton = (Button)findViewById(R.id.btn_login);
        signupLink = (TextView)findViewById(R.id.link_signup);

        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                login();
            }
        });

        signupLink.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // Start the Signup activity
                Intent intent = new Intent(getApplicationContext(), SignupActivity.class);
                startActivityForResult(intent, REQUEST_SIGNUP);
            }
        });
    }



    public void login() {
        Log.d(TAG, "Login");

        if (!validate()) {
            onLoginFailed();
            return;
        }
        loginButton.setEnabled(false);

        progressDialog = new ProgressDialog(LoginActivity.this,
                R.style.AppTheme_Dark_Dialog);
        progressDialog.setIndeterminate(true);
        progressDialog.setMessage("Authenticating...");
        progressDialog.show();

        String email = emailText.getText().toString();
        String password = passwordText.getText().toString();

        // TODO: Implement your own authentication logic here.
        NetWork network = new NetWork(loginHandler, URL_Login);
        network.GetMessage(email, password);            //problem
    }

    private Handler loginHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            String retStr, retCode;
            if (msg.what == 1) {
                progressDialog.dismiss();
                loginButton.setEnabled(true);

                retStr = msg.obj.toString();
                retCode = retStr.substring(retStr.indexOf("code:") + 5, retStr.indexOf(";message"));

                if(retCode.equals("200"))
                    onLoginSuccess();
                else
                    onLoginFailed();
            }
        }

    };

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_SIGNUP) {
            if (resultCode == RESULT_OK) {
                // TODO: Implement successful signup logic here
                // By default we just finish the Activity and log them in automatically
                Intent intent = new Intent(this, HomeActivity.class);
                startActivity(intent);
                this.finish();
            }
        }
    }

    @Override
    public void onBackPressed() {
        // disable going back to the MainActivity
        moveTaskToBack(true);
    }

    public void onLoginSuccess() {
        Intent intent = new Intent(this, HomeActivity.class);
        startActivity(intent);
        finish();
    }

    public void onLoginFailed() {
        Toast.makeText(getBaseContext(), "Login failed", Toast.LENGTH_LONG).show();
    }

    public boolean validate() {
        boolean valid = true;

        String email = emailText.getText().toString();
        String password = passwordText.getText().toString();

        if (email.isEmpty() || !android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
            emailText.setError("enter a valid email address");
            valid = false;
        } else {
            emailText.setError(null);
        }

        if (password.isEmpty() || password.length() < 4 || password.length() > 10) {
            passwordText.setError("between 4 and 10 alphanumeric characters");
            valid = false;
        } else {
            passwordText.setError(null);
        }

        return valid;
    }
}

登录界面的代码,与之前的登录界面代码相比,主要修改了signup函数并增加了signupHandler:

SignupActivity.java

package edu.hdu.lyy.activity;

/**
 * Created by wch on 2018/3/18.
 */

import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import edu.hdu.lyy.adapter.NetWork;
import edu.hdu.lyy.teaching.R;

import static edu.hdu.lyy.model.Constant.URL_Register;


public class SignupActivity extends AppCompatActivity {
    private static final String TAG = "SignupActivity";

    EditText nameText;
    EditText emailText;
    EditText passwordText;
    Button signupButton;
    TextView loginLink;
    ProgressDialog progressDialog;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_signup);

        nameText = (EditText) findViewById(R.id.input_name);
        emailText = (EditText) findViewById(R.id.input_email);
        passwordText = (EditText) findViewById(R.id.input_password);
        signupButton = (Button) findViewById(R.id.btn_signup);
        loginLink = (TextView) findViewById(R.id.link_login);



        signupButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                signup();
            }
        });

        loginLink.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Finish the registration screen and return to the Login activity
                finish();
            }
        });
    }

    private Handler signupHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            String retStr, retCode;
            if (msg.what == 1) {
                signupButton.setEnabled(true);
                progressDialog.dismiss();

                retStr = msg.obj.toString();
                retCode = retStr.substring(retStr.indexOf("code:") + 5, retStr.indexOf(";message"));

                if(retCode.equals("200"))
                    onSignupSuccess();
                else
                    onSignupFailed();
            }
        }
    };

    public void signup() {
        Log.d(TAG, "Signup");

        if (!validate()) {
            onSignupFailed();
            return;
        }

        signupButton.setEnabled(false);

        progressDialog = new ProgressDialog(SignupActivity.this,
                R.style.AppTheme_Dark_Dialog);
        progressDialog.setIndeterminate(true);
        progressDialog.setMessage("Creating Account...");
        progressDialog.show();

        String name = nameText.getText().toString();
        String email = emailText.getText().toString();
        String password = passwordText.getText().toString();

        // TODO: Implement your own signup logic here.
        NetWork network = new NetWork(signupHandler, URL_Register);
        network.GetMessage(email, password);
    }

    public void onSignupSuccess() {
        setResult(RESULT_OK, null);
        finish();
    }

    public void onSignupFailed() {
        Toast.makeText(getBaseContext(), "Login failed", Toast.LENGTH_LONG).show();
    }

    public boolean validate() {
        boolean valid = true;

        String name = nameText.getText().toString();
        String email = emailText.getText().toString();
        String password = passwordText.getText().toString();

        if (name.isEmpty() || name.length() < 3) {
            nameText.setError("at least 3 characters");
            valid = false;
        } else {
            nameText.setError(null);
        }

        if (email.isEmpty() || !android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
            emailText.setError("enter a valid email address");
            valid = false;
        } else {
            emailText.setError(null);
        }

        if (password.isEmpty() || password.length() < 4 || password.length() > 10) {
            passwordText.setError("between 4 and 10 alphanumeric characters");
            valid = false;
        } else {
            passwordText.setError(null);
        }
        return valid;
    }
}

编译后进行注册,注册成功后程序将进入主页界面,再退出测试登录逻辑。

就这样就完事了,其实篇幅不短,内容却不多。到此GET方式的交互就完成了,同理,POST交互也是依葫芦画瓢。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值