认真学习安卓也有三四个月了,现在记录一下关于用户的各种操作。

1.安卓APP的实现:

先看一下展示动图吧!

首先是登录界面的xml---------activity_mian.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/activity_login"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><!--登录页面--><EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:inputType="textPersonName"android:ems="10"android:hint="用户名"android:textColorHint="#003399"android:id="@+id/login_edit_account"android:textSize="20dp"android:textColor="#003399"android:layout_margin="10dp"/><EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:inputType="textPersonName"android:ems="10"android:hint="密码"android:textColorHint="#003399"android:id="@+id/login_edit_pwd"android:textSize="20dp"android:textColor="#003399"android:layout_margin="10dp"/><Buttonandroid:text="登录"android:textSize="20dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/login_btn_login"android:layout_marginLeft="20dp"android:layout_marginRight="20dp"android:background="@color/lavender"/><Buttonandroid:text="注册"android:textSize="20dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:id="@+id/register"android:layout_marginLeft="20dp"android:layout_marginRight="20dp"android:background="@color/lavender"/><Buttonandroid:text="找回密码"android:textSize="20dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/forgetpassword"android:layout_marginTop="5dp"android:layout_marginLeft="20dp"android:layout_marginRight="20dp"android:background="@color/lavender"/>
</LinearLayout>

然后是Mainacticity.java

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.method.PasswordTransformationMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
//import com.example.administrator.loginclient.HttpsUtils.HTTPSTrustManager;
import com.example.administrator.loginclient.R;
import com.example.administrator.loginclient.RsaUtils.GenKeyFromString;
import com.example.administrator.loginclient.RsaUtils.MyConstant;
import com.example.administrator.loginclient.RsaUtils.RSAUtil;
import org.bouncycastle.util.encoders.Base64;
import org.json.JSONException;
import org.json.JSONObject;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Map;
/*** 登录*/public class MainActivity extends BaseActivity {public static RequestQueue queue;private static Context mContext;private static String afterencrypt;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);queue = Volley.newRequestQueue(getApplicationContext());mContext = this;final EditText AccountNumber = (EditText) findViewById(R.id.login_edit_account);//输入用户名final EditText Password = (EditText) findViewById(R.id.login_edit_pwd);//输入密码Password.setTransformationMethod(PasswordTransformationMethod.getInstance());//密码不可见Intent intent = getIntent();String username = intent.getStringExtra("username");String password = intent.getStringExtra("password");AccountNumber.setText(username);Password.setText(password);Button login = (Button) findViewById(R.id.login_btn_login);Button register = (Button) findViewById(R.id.register);Button forget_password = (Button) findViewById(R.id.forgetpassword);login.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {final String name = AccountNumber.getText().toString().trim();final String psw = Password.getText().toString().trim();//接下来是传输加密// 获取Rsa 工具类对象RSAUtil rsa = new RSAUtil();// 获取公钥RSAPublicKey pubKey = (RSAPublicKey) GenKeyFromString.getPubKey(MyConstant.pubKey1);// 使用公钥加密 数据byte[] enRsaByte_psw = new byte[0];byte[] enRsaBytes_user = new byte[0];try {enRsaByte_psw = rsa.encrypt(pubKey, psw.getBytes());//密码加密enRsaBytes_user = rsa.encrypt(pubKey, name.getBytes());//用户名加密} catch (Exception e) {e.printStackTrace();}/*** base64对byte数组进行编码,进过编码后得到String传输到对服务端解码得出byte数组。*/String enRsaStr_psw = new String(Base64.encode(enRsaByte_psw));//密码byte数组转成字符串String enRsaStr_user = new String(Base64.encode(enRsaBytes_user));//用户名byte数组转成字符串LoginRequest(enRsaStr_user,enRsaStr_psw);//提交登录表单Toast.makeText(mContext, "请稍等...", Toast.LENGTH_SHORT).show();}});//注册register.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, RegisterActivity.class);startActivity(intent);}});//忘记密码forget_password.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, ForgetPswActivity.class);startActivity(intent);}});}public static void LoginRequest(final String accountNumber, final String password) {//请求地址String url = "http://localhost:8083/MyFirstWebAPP/LoginServlet";String tag = "Login";//取得请求队列lRequestQueue requestQueue = queue;//防止重复请求,所以先取消tag标识的请求队列requestQueue.cancelAll(tag);//   HTTPSTrustManager.allowAllSSL();//允许所有https请求//创建StringRequest,定义字符串请求的请求方式为POST(省略第一个参数会默认为GET方式)final StringRequest request = new StringRequest(Request.Method.POST, url,new Response.Listener<String>() {@Overridepublic void onResponse(String response) {try {JSONObject jsonObject = (JSONObject) new JSONObject(response).get("params");String result = jsonObject.getString("Result");if (result.equals("TheUserDoesNotExist")) {Toast.makeText(mContext, "账户不存在", Toast.LENGTH_LONG).show();} else if (result.equals("PasswordError")) {//做自己的登录失败操作,如Toast提示Toast.makeText(mContext, "密码错误", Toast.LENGTH_LONG).show();} else if (result.equals("CorrectPassword")) {Toast.makeText(mContext, "登录成功", Toast.LENGTH_SHORT).show();Intent intent = new Intent(mContext, LoginSuccessActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//关掉所要到的界面中间的activityintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);mContext.startActivity(intent);}} catch (JSONException e) {//做自己的请求异常操作,如Toast提示(“无网络连接”等)Log.e("TAG", e.getMessage(), e);Toast.makeText(mContext, "无网络连接", Toast.LENGTH_LONG).show();}}}, new Response.ErrorListener() {@Overridepublic void onErrorResponse(VolleyError error) {//做自己的响应错误操作,如Toast提示(“请稍后重试”等)Log.e("TAG", error.getMessage(), error);Toast.makeText(mContext, "无网络连接", Toast.LENGTH_LONG).show();}}) {@Overrideprotected Map<String, String> getParams() throws AuthFailureError {Map<String, String> params = new HashMap<>();params.put("AccountNumber", accountNumber);params.put("Password", password);return params;}};//设置Tag标签request.setTag(tag);//将请求添加到队列中requestQueue.add(request);}
}

接下来是加密算法:GenKeyFromString.java,使用非对称混合加密算法

import java.io.IOException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import Decoder.BASE64Decoder;
import Decoder.BASE64Encoder;/*** Key类型密钥 与 String类型密钥之间自由转换*/
public class GenKeyFromString {/*** 根据字符串类型的公钥生成  公钥key* @param pubKey   字符串类型的公钥* @return 公钥*/public static PublicKey getPubKey(String pubKey) {PublicKey publicKey = null;try {X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec(new BASE64Decoder().decodeBuffer(pubKey));// RSA对称加密算法java.security.KeyFactory keyFactory;keyFactory = java.security.KeyFactory.getInstance("RSA");// 取公钥匙对象publicKey = keyFactory.generatePublic(bobPubKeySpec);} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (InvalidKeySpecException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return publicKey;}/*** 根据String形式的私钥     生成私钥Key* @param priKey   字符串类型的私钥* @return*/public static PrivateKey getPrivateKey(String priKey) {PrivateKey privateKey = null;PKCS8EncodedKeySpec priPKCS8 = null;try {priPKCS8 = new PKCS8EncodedKeySpec(new BASE64Decoder().decodeBuffer(priKey));KeyFactory keyf = KeyFactory.getInstance("RSA");privateKey = keyf.generatePrivate(priPKCS8);} catch (IOException e) {e.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (InvalidKeySpecException e) {e.printStackTrace();}return privateKey;}/*** 根据Key转换成String类型** @param key*            密钥Key (公或私钥)* @return 密钥Key的String类型*/public static String getStringFromKey(Key key) {byte[] keyBytes = key.getEncoded();String key_String = (new BASE64Encoder()).encode(keyBytes);return key_String;}
}

密钥对:MyConstant.java

***  字符串类型的密钥对* Created by Administrator on 2020/4/29.*/public class MyConstant {/***  一对测试密钥   1:*  pubKey_String ---公钥*  pubKey_String ---私钥*/public static final String pubKey_String = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVRiDkEKXy/KBTe+UmkA+feq1zGWIgBxkgbz7aBJGb5+eMKKoiDRoEHzlGndwFKm4mQWNftuMOfNcogzYpGKSEfC7sqfBPDHsGPZixMWzL3J10zkMTWo6MDIXKKqMG1Pgeq1wENfJjcYSU/enYSZkg3rFTOaBSFId+rrPjPo7Y4wIDAQAB";public static final String priKey_String = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJVGIOQQpfL8oFN75SaQD596rXMZYiAHGSBvPtoEkZvn54woqiINGgQfOUad3AUqbiZBY1+24w581yiDNikYpIR8Luyp8E8MewY9mLExbMvcnXTOQxNajowMhcoqowbU+B6rXAQ18mNxhJT96dhJmSDesVM5oFIUh36us+M+jtjjAgMBAAECgYABtnxKIabF0wBD9Pf8KUsEmXPEDlaB55LyPFSMS+Ef2NlfUlgha+UQhwsxND6CEKqS5c0uG/se/2+4l0jXz+CTYBEh+USYB3gxcMKEo5XDFOGaM2Ncbc7FAKJIkYYN2DHmr4voSM5YkVibw5Lerw0kKdYyr0Xd0kmqTok3JLiLgQJBAOGZ1ao9oqWUzCKnpuTmXre8pZLmpWPhm6S1FU0vHjI0pZh/jusc8UXSRPnx1gLsgXq0ux30j968x/DmkESwxX8CQQCpY1+2p1aX2EzYO3UoTbBUTg7lCsopVNVf41xriek7XF1YyXOwEOSokp2SDQcRoKJ2PyPc2FJ/f54pigdsW0adAkAM8JTnydc9ZhZ7WmBhOrFuGnzoux/7ZaJWxSguoCg8OvbQk2hwJd3U4mWgbHWY/1XB4wHkivWBkhRpxd+6gOUjAkBH9qscS52zZzbGiwQsOk1Wk88qKdpXku4QDeUe3vmSuZwC85tNyu+KWrfM6/H74DYFbK/MzK7H8iz80uJye5jVAkAEqEB/LwlpXljFAxTID/SLZBb+bCIoV/kvg+2145F+CSSUjEWRhG/+OH0cQfqomfg36WrvHl0g/Xw06fg31HgK";/***  测试密钥  2:*  pubKey_String ---公钥*  pubKey_String ---私钥*/public static final String pubKey1 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCokTtKtoiIT8/4dmC3qd0l6m5LWSKkZTeWHbTi7yZ0zHc3Y9PEdHu9LtdzVMJ6z+6kD09bY0lK31gVBBGDqC0pUum9ObqY6HRLHcoHqAT90bpL7+B1ufbLt3S8lJlhTXY9TL4i9i5mI43FrHKxR+c8OAJs0gILzd1x7K+KnQ1pBQIDAQAB";public static final String priKey1 = "MIIBNgIBADANBgkqhkiG9w0BAQEFAASCASAwggEcAgEAAoGBAKiRO0q2iIhPz/h2YLep3SXqbktZIqRlN5YdtOLvJnTMdzdj08R0e70u13NUwnrP7qQPT1tjSUrfWBUEEYOoLSlS6b05upjodEsdygeoBP3Rukvv4HW59su3dLyUmWFNdj1MviL2LmYjjcWscrFH5zw4AmzSAgvN3XHsr4qdDWkFAgEAAoGAaRXg+LrCcvgOlr51nQnwK+rxx1dSGVpgRN1QHwkn2Dh/ObCqHBbh7RZ+ig+VDisCgpRozHghAOQrbS6UHJeDTvRWQhvjSkPUKtzT5sVXdpFrQRhOBP2ucxGubZtYNUitm3ilObsT1YZf0OB+Ozs19FJidCgHS88tPsB/W+ukowECAQACAQACAQACAQACAQA=";}

RSA工具类:RSAUtil.java

import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;/*** RSA 工具类。* 提供加密,解密,生成密钥对等方法。* 需要到http://www.bouncycastle.org下载bcprov-jdk14-123.jar。 RSA加密原理概述* RSA的安全性依赖于大数的分解,公钥和私钥都是两个大素数(大于100的十进制位)的函数。 据猜测,从一个密钥和密文推断出明文的难度等同于分解两个大素数的积* =================================================================== ** 1.选择两个大素数 p,q ,计算 n=p*q; 2.随机选择加密密钥 e ,要求 e 和 (p-1)*(q-1)互质 3.利用 Euclid* 算法计算解密密钥 d , 使其满足 e*d = 1(mod(p-1)*(q-1)) (其中 n,d 也要互质) 4:至此得出公钥为 (n,e) 私钥为* (n,d) ===================================================================* 加解密方法: 1.首先将要加密的信息 m(二进制表示) 分成等长的数据块 m1,m2,...,mi 块长 s(尽可能大) ,其中 2^s<n* 2:对应的密文是: ci = mi^e(mod n) 3:解密时作如下计算: mi = ci^d(mod n)* =================================================================== RSA速度* 由于进行的都是大数计算,使得RSA最快的情况也比DES慢上100倍,无论 是软件还是硬件实现。 速度一直是RSA的缺陷。一般来说只用于少量数据 加密。**/
public class RSAUtil {/*** 密钥对*/private KeyPair keyPair = null;/*** 初始化密钥对*/public RSAUtil() {try {this.keyPair = this.generateKeyPair();} catch (Exception e) {e.printStackTrace();}}/*** 生成密钥对** @return KeyPair* @throws Exception*/public KeyPair generateKeyPair() throws Exception {try {KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",new org.bouncycastle.jce.provider.BouncyCastleProvider());// 这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低final int KEY_SIZE = 1024;keyPairGen.initialize(KEY_SIZE, new SecureRandom());KeyPair keyPair = keyPairGen.genKeyPair();return keyPair;} catch (Exception e) {throw new Exception("生成密钥对失败");}}/*** 生成公钥** @param modulus* @param publicExponent* @return RSAPublicKey* @throws Exception*/private RSAPublicKey generateRSAPublicKey(byte[] modulus,byte[] publicExponent) throws Exception {KeyFactory keyFac = null;try {keyFac = KeyFactory.getInstance("RSA",new org.bouncycastle.jce.provider.BouncyCastleProvider());} catch (NoSuchAlgorithmException ex) {throw new Exception(ex.getMessage());}RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(modulus), new BigInteger(publicExponent));try {return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);} catch (InvalidKeySpecException ex) {throw new Exception(ex.getMessage());}}/*** 生成私钥** @param modulus* @param privateExponent* @return RSAPrivateKey* @throws Exception*/public RSAPrivateKey generateRSAPrivateKey(byte[] modulus,byte[] privateExponent) throws Exception {KeyFactory keyFac = null;try {keyFac = KeyFactory.getInstance("RSA",new org.bouncycastle.jce.provider.BouncyCastleProvider());} catch (NoSuchAlgorithmException ex) {throw new Exception(ex.getMessage());}RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(modulus), new BigInteger(privateExponent));try {return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);} catch (InvalidKeySpecException ex) {throw new Exception(ex.getMessage());}}/*** 获取公钥** @return* @throws Exception*/public RSAPublicKey getRSAPublicKey() throws Exception {// 获取公钥RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();// 获取公钥系数(字节数组形式)byte[] pubModBytes = pubKey.getModulus().toByteArray();// 返回公钥公用指数(字节数组形式)byte[] pubPubExpBytes = pubKey.getPublicExponent().toByteArray();// 生成公钥RSAPublicKey recoveryPubKey = this.generateRSAPublicKey(pubModBytes,pubPubExpBytes);return recoveryPubKey;}/*** 获取私钥** @return* @throws Exception*/public RSAPrivateKey getRSAPrivateKey() throws Exception {// 获取私钥RSAPrivateKey priKey = (RSAPrivateKey) keyPair.getPrivate();// 返回私钥系数(字节数组形式)byte[] priModBytes = priKey.getModulus().toByteArray();// 返回私钥专用指数(字节数组形式)byte[] priPriExpBytes = priKey.getPrivateExponent().toByteArray();// 生成私钥RSAPrivateKey recoveryPriKey = this.generateRSAPrivateKey(priModBytes,priPriExpBytes);return recoveryPriKey;}/*** 加密** @param key*            加密的密钥* @param data*            待加密的明文数据* @return 加密后的数据* @throws Exception*/public byte[] encrypt(Key key, byte[] data) throws Exception {try {Cipher cipher = Cipher.getInstance("RSA",new org.bouncycastle.jce.provider.BouncyCastleProvider());cipher.init(Cipher.ENCRYPT_MODE, key);// 获得加密块大小,如:加密前数据为128个byte,而key_size=1024 加密块大小为127// byte,加密后为128个byte;// 因此共有2个加密块,第一个127 byte第二个为1个byteint blockSize = cipher.getBlockSize();int outputSize = cipher.getOutputSize(data.length);// 获得加密块加密后块大小int leavedSize = data.length % blockSize;int blocksSize = leavedSize != 0 ? data.length / blockSize + 1: data.length / blockSize;byte[] raw = new byte[outputSize * blocksSize];int i = 0;while (data.length - i * blockSize > 0) {if (data.length - i * blockSize > blockSize)cipher.doFinal(data, i * blockSize, blockSize, raw, i* outputSize);elsecipher.doFinal(data, i * blockSize, data.length - i* blockSize, raw, i * outputSize);// 这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到ByteArrayOutputStream中// ,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了OutputSize所以只好用dofinal方法。i++;}return raw;} catch (Exception e) {throw new Exception(e.getMessage());}}/*** 解密** @param key*            解密的密钥* @param raw*            已经加密的数据* @return 解密后的明文* @throws Exception*/public byte[] decrypt(Key key, byte[] raw) throws Exception {try {Cipher cipher = Cipher.getInstance("RSA",new org.bouncycastle.jce.provider.BouncyCastleProvider());cipher.init(cipher.DECRYPT_MODE, key);int blockSize = cipher.getBlockSize();ByteArrayOutputStream bout = new ByteArrayOutputStream(64);int j = 0;while (raw.length - j * blockSize > 0) {bout.write(cipher.doFinal(raw, j * blockSize, blockSize));j++;}return bout.toByteArray();} catch (Exception e) {throw new Exception(e.getMessage());}}}

用到的依赖包:

 implementation files('libs/sun.misc.BASE64Decoder.jar')implementation 'com.android.volley:volley:1.1.1'

2.Tomcat服务器搭建:

下载xampp并安装,选择安装,网上有很多教程的,这个算是傻瓜式安装


建立数据库:要先下载数据化库可视化软件------MySQL-Front
安装完之后打开,点击new

server填localhost,port填3306

点击OK,进入这个界面:

由于已经存在这个相同名称数据了,所以我的OK点击不了

建好myfirstapp之后,建user表

在user表新建field--------UserName

Password和Email的建立方式和UserName的一模一样。这里就不做重复了。

双击user,点击 Data Browser

数据库到此就建完啦!

3.Servlet后端的编写:

我是用netbeans编写的,网上有安装教程的。
注意项目名称要和URL的一致, String url = “http://localhost:8083/MyFirstWebAPP/LoginServlet”;
我的项目名称是MyFirstWebAPP。以下是新建web项目的示范操作!

接下来新建web.xml

然后在项目里新建一个文件夹lib,以导入外部jar包 提取码:yoa9

添加jar包依赖

接下来是建包写代码啦!

撸代码啦-----------------------------------
在包里新建java类,DBManager.java

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;/*** 数据库管理类,提供连接数据库和拆解链接功能**/
public class DBManager extends HttpServlet {ServletConfig config;                             //定义一个ServletConfig对象private static String username;                   //定义的数据库用户名private static String password;                   //定义的数据库连接密码private static String url;                        //定义数据库连接URLprivate static Connection connection;             //定义连接@Overridepublic void init(ServletConfig config) throws ServletException {super.init(config);                                  //继承父类的init()方法this.config = config;                                //获取配置信息username = config.getInitParameter("DBUsername");    //获取数据库用户名password = config.getInitParameter("DBPassword");    //获取数据库连接密码url = config.getInitParameter("ConnectionURL");      //获取数据库连接URL}/*** 获得数据库连接对象** @return 数据库连接对象*/public static Connection getConnection() {try {Class.forName("com.mysql.jdbc.Driver").newInstance();connection = DriverManager.getConnection(url, username, password);} catch (ClassNotFoundException | InstantiationException| IllegalAccessException | SQLException ex) {Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);}return connection;}/*** 关闭所有的数据库连接资源** @param connection Connection 链接* @param statement Statement 资源* @param resultSet ResultSet 结果集合*/public static void closeAll(Connection connection, Statement statement,ResultSet resultSet) {try {if (resultSet != null) {resultSet.close();}if (statement != null) {statement.close();}if (connection != null) {connection.close();}} catch (SQLException ex) {Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);}}public static void closeTwo(Connection connection, Statement statement) {try {if (statement != null) {statement.close();}if (connection != null) {connection.close();}} catch (SQLException ex) {Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);}}
}

User.java

/**** @author Administrator*/
public class User {//用户姓名private String userName;//用户密码private String password;//用户邮箱,用于找回密码、修改密码private String email;private String loadtimes;//用户烧录总次数private String loadtimesAll;public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getEmail(){return email;}public void setEmail(String email){this.email=email;}}

UserDAO.java

/**** @author Administrator*/
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;public class UserDAO {/*** 查询给定用户名的用户的详细信息**/public static Boolean hasemail=false;public static User queryUser(String userName) {//获得数据库的连接对象Connection connection = DBManager.getConnection();PreparedStatement preparedStatement = null;ResultSet resultSet = null;//生成SQL代码StringBuilder sqlStatement = new StringBuilder();sqlStatement.append("SELECT * FROM user WHERE UserName=?");//设置数据库的字段值try {preparedStatement = connection.prepareStatement(sqlStatement.toString());preparedStatement.setString(1, userName);resultSet = preparedStatement.executeQuery();User user = new User();if (resultSet.next()) {user.setUserName(resultSet.getString("UserName"));user.setPassword(resultSet.getString("Password"));return user;} else {return null;}} catch (SQLException ex) {Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);return null;} finally {DBManager.closeAll(connection, preparedStatement, resultSet);}}/*** 注册用户** @param userName 给定的用户名* @param password* @param email* @return */public static Boolean registerUser(String userName,String password,String email){Boolean flag=false; if(!UserDAO.checkUserName(userName)){return false;//判断该用户是否存在,若存在,函数返回false}else if(!UserDAO.checkEmail(email)){hasemail=true; //邮箱被注册过return false;   //邮箱未被注册}//获得数据库的连接对象Connection connection = DBManager.getConnection();PreparedStatement preparedStatement = null;//生成SQL代码StringBuilder sqlStatement = new StringBuilder();sqlStatement.append("INSERT INTO user(UserName,Password,Email) VALUES(?,?,?)");//设置数据库的字段值try {preparedStatement = connection.prepareStatement(sqlStatement.toString());preparedStatement.setString(1, userName);preparedStatement.setString(2, password);preparedStatement.setString(3, email);int row = preparedStatement.executeUpdate(); if(row>0){flag=true;}else {return null;}} catch (SQLException ex) {Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);return null;} finally {DBManager.closeTwo(connection, preparedStatement);}return flag;}/**查询用户是否存在*@param userName 给定的用户名**/public static Boolean checkUserName(String userName) {Connection connection = DBManager.getConnection();PreparedStatement preparedStatement = null;ResultSet resultSet = null;//生成SQL代码StringBuilder sqlStatement = new StringBuilder();sqlStatement.append("SELECT * FROM user WHERE UserName=?");try {preparedStatement = connection.prepareStatement(sqlStatement.toString());preparedStatement.setString(1, userName);resultSet = preparedStatement.executeQuery();User user = new User();if (resultSet.next() == true) {return false;//用户已存在} else {return true;//该用户可用}} catch (SQLException ex) {Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);}return true;}/**查询邮箱是否存在*@param email 给定的用户名***/public static Boolean checkEmail(String email) {Connection connection = DBManager.getConnection();PreparedStatement preparedStatement = null;ResultSet resultSet = null;//生成SQL代码StringBuilder sqlStatement = new StringBuilder();sqlStatement.append("SELECT * FROM user WHERE Email=?");try {preparedStatement = connection.prepareStatement(sqlStatement.toString());preparedStatement.setString(1, email);resultSet = preparedStatement.executeQuery();User user = new User();if (resultSet.next() == true) {return false;//该邮箱已被注册过} else {return true;//该邮箱可用}} catch (SQLException ex) {Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);}return true;}/*** 验证用户名邮箱是否对应** @param userName* @return * */public static User queryEmail(String userName) {//获得数据库的连接对象Connection connection = DBManager.getConnection();PreparedStatement preparedStatement = null;ResultSet resultSet = null;//生成SQL代码StringBuilder sqlStatement = new StringBuilder();sqlStatement.append("SELECT * FROM user WHERE UserName=?");//设置数据库的字段值try {preparedStatement = connection.prepareStatement(sqlStatement.toString());preparedStatement.setString(1, userName);resultSet = preparedStatement.executeQuery();User user = new User();if (resultSet.next()) {user.setUserName(resultSet.getString("UserName"));user.setEmail(resultSet.getString("Email"));return user;} else {return null;}} catch (SQLException ex) {Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);return null;} finally {DBManager.closeAll(connection, preparedStatement, resultSet);}}/*** 通过邮箱查询密码* @param email* @return */public static User queryPasswordByEmail(String email) {//获得数据库的连接对象Connection connection = DBManager.getConnection();PreparedStatement preparedStatement = null;ResultSet resultSet = null;//生成SQL代码StringBuilder sqlStatement = new StringBuilder();sqlStatement.append("SELECT * FROM user WHERE Email=?");//设置数据库的字段值try {preparedStatement = connection.prepareStatement(sqlStatement.toString());preparedStatement.setString(1, email);resultSet = preparedStatement.executeQuery();User user = new User();if (resultSet.next()) {user.setEmail(resultSet.getString("Email"));user.setPassword(resultSet.getString("Password"));return user;} else {return null;}} catch (SQLException ex) {Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);return null;} finally {DBManager.closeAll(connection, preparedStatement, resultSet);}}/*** 通过用户查询邮箱* @param email* @return */public static User queryUserByEmail(String email) {//获得数据库的连接对象Connection connection = DBManager.getConnection();PreparedStatement preparedStatement = null;ResultSet resultSet = null;//生成SQL代码StringBuilder sqlStatement = new StringBuilder();sqlStatement.append("SELECT * FROM user WHERE Email=?");//设置数据库的字段值try {preparedStatement = connection.prepareStatement(sqlStatement.toString());preparedStatement.setString(1, email);resultSet = preparedStatement.executeQuery();User user = new User();if (resultSet.next()) {user.setEmail(resultSet.getString("Email"));user.setUserName(resultSet.getString("UserName"));user.setPassword(resultSet.getString("Password"));return user;} else {return null;}} catch (SQLException ex) {Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);return null;} finally {DBManager.closeAll(connection, preparedStatement, resultSet);}}/*** 更新密码* * @param password* @param email* @return */public static Boolean updatePassword(String password,String email){//获得数据库的连接对象Connection connection = DBManager.getConnection();PreparedStatement preparedStatement = null;//生成SQL代码StringBuilder sqlStatement = new StringBuilder();sqlStatement.append("UPDATE  user SET Password =? WHERE Email=?");//设置数据库的字段值try {preparedStatement = connection.prepareStatement(sqlStatement.toString());preparedStatement.setString(1, password);preparedStatement.setString(2, email);int row = preparedStatement.executeUpdate(); if(row>0){return true;}else {return null;}} catch (SQLException ex) {Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);return null;} finally {DBManager.closeTwo(connection, preparedStatement);}}
}
  接下来是LoginServlet.java,这里要注意,选择的是servlet而不是java!我这里只是示范如何建servlet

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import java.security.interfaces.RSAPrivateKey;
import net.jw.MyFirstWebAPP.RSAutil.GenKeyFromString;
import net.jw.MyFirstWebAPP.RSAutil.MyConstant;
import net.jw.MyFirstWebAPP.RSAutil.RSAUtil;
import net.jw.MyFirstWebAPP.User;
import net.jw.MyFirstWebAPP.UserDAO;
import org.bouncycastle.util.encoders.Base64;
/*** 登录验证Servlet** @author Administrator*/
public class LoginServlet extends HttpServlet {private static int verifyResult;@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应内容类型  response.setContentType("text/html;charset=utf-8");request.setCharacterEncoding("utf-8");response.setCharacterEncoding("utf-8");try (PrintWriter out = response.getWriter()) {//获得请求中传来的用户名和密码String accountNumber = request.getParameter("AccountNumber").trim();String password = request.getParameter("Password").trim();//加密后的密码byte[] bytereuser = Base64.decode(accountNumber);//用户名解密BASE64byte[] byterepsw = Base64.decode(password);//密码解密BASE64//  System.out.println(byteres);// System.out.println("字符串转成byte数组:"+new String(byteres));// 获取私钥    RSAUtil rsa = new RSAUtil();RSAPrivateKey priKey = (RSAPrivateKey) GenKeyFromString.getPrivateKey(MyConstant.priKey1);// 拿着私钥解用户名byte[] encRsaByteuser = rsa.decrypt(priKey,bytereuser);// 拿着私钥解密码byte[] encRsaBytepsw = rsa.decrypt(priKey,byterepsw);//  System.out.println("解密后==" + new String(encRsaBytes));//验证登录操作verifyResult = verifyLogin(new String(encRsaByteuser),new String(encRsaBytepsw));Map<String, String> params = new HashMap<>();JSONObject jsonObject = new JSONObject();if (verifyResult == -1) {params.put("Result", "TheUserDoesNotExist");//用户不存在} else if (verifyResult == 0){params.put("Result", "PasswordError");//密码错误}else if(verifyResult == 1){params.put("Result","CorrectPassword");//密码正确}jsonObject.put("params", params);out.write(jsonObject.toString());} catch (Exception ex) {Logger.getLogger(LoginServlet.class.getName()).log(Level.SEVERE, null, ex);}}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doPost(request, response);}/*** 验证用户名密码是否正确** @param userName* @param password*/private int verifyLogin(String userName, String password) {User user = UserDAO.queryUser(userName);boolean hasUser = false;boolean rightPass = false;//账户密码验证if(!UserDAO.checkUserName(userName)){hasUser = true;if(user.getPassword().equals(password)){rightPass = true;}}if(!hasUser) return -1;//无该用户else if(!rightPass) return 0;//有该用户,但是密码输入错误return 1;//有该用户,且密码输入正确}
}
  还有修改web.xml,如果包名和我的不同,记得修改成自己的。请仔细阅读web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"><servlet><servlet-name>LoginServlet</servlet-name><servlet-class>net.jw.MyFirstWebAPP.ServletPackage.LoginServlet</servlet-class></servlet><servlet-mapping><servlet-name>LoginServlet</servlet-name><url-pattern>/LoginServlet</url-pattern></servlet-mapping><session-config><session-timeout>30</session-timeout></session-config><servlet><servlet-name>DBManager</servlet-name><!-- 下面这行是DBManager这个类的定位,“包名”替换为你在前面创建的包名,区分大小写 --><servlet-class>net.jw.MyFirstWebAPP.DBManager</servlet-class><init-param><param-name>DBUsername</param-name><!-- 这里是数据库用户名,一般情况下是root,无需改变 --><param-value>root</param-value></init-param><init-param><param-name>DBPassword</param-name><!-- 下面这两个标签中间写你的数据库密码,如果没设置就什么也别写,空格也不能有 --><param-value/></init-param><init-param><param-name>ConnectionURL</param-name><!-- myfirstapp数据库的名字 --><param-value>jdbc:mysql://localhost:3306/myfirstapp?characterEncoding=utf8</param-value></init-param><!-- 下面这行很重要,指示服务器在启动时立即加载这个Servlet --><load-on-startup>0</load-on-startup></servlet>
</web-app>

好了,web项目到此就写完啦!最后把项目部署到Tomcat上!

修改Tomcat的servlet.xml,把端口号8080改成8083。
最后,在xampp的Tomcat点击start就可以测试APP啦!
需要注意的是,servlet如果有以下包导入错误:

import net.jw.MyFirstWebAPP.RSAutil.GenKeyFromString;
import net.jw.MyFirstWebAPP.RSAutil.MyConstant;
import net.jw.MyFirstWebAPP.RSAutil.RSAUtil;

就在项目里加上这三个类的代码即可,代码和上面的安卓端的是一模一样的。

参考文章:https://blog.csdn.net/Mr_Megamind/article/details/71404618

安卓APP注册登录+Tomcat服务器搭建+MySQL数据库建立+加密传输+servlet后端内容编写及部署到Tomcat服务器相关推荐

  1. 阿里云ECS服务器搭建Mysql数据库

    阿里云ECS服务器搭建Mysql数据库 一.服务器系统: Alibaba Cloud Linux 3.2104 LTS 64位 二.服务器文件夹创建 [说明]:由于服务器为新申请,故服务器为空白服务器 ...

  2. 记录--uniapp上如何实现安卓app微信登录功能(操作流程总结)

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 uniapp上如何实现安卓app微信登录功能?下面本篇文章给大家分享一下uniapp上实现安卓app微信登录的权限申请.开发的具体操作流程 ...

  3. APP注册登录那点事

    转载地址:http://www.woshipm.com/pd/206667.html?utm_source=tuicool APP注册登录那点事 2015/09/21 阅读 3.2万  评论 6 收藏 ...

  4. 云闪付持卡人认证信息失败_云闪付app注册登录常见问答

    云闪付app注册登录常见问答 1.如何注册成为云闪付App用户? 持卡人可通过以下方式注册成为云闪付APP用户: (1)通过持卡人服务网站(www.95516.com): (2)通过云闪付App. 通 ...

  5. 62 openEuler 22.03-LTS 搭建MySQL数据库服务器-管理数据库

    文章目录 62 openEuler 22.03-LTS 搭建MySQL数据库服务器-管理数据库 62.1 创建数据库 示例 62.2 查看数据库 示例 62.3 选择数据库 示例 62.4 删除数据库 ...

  6. Axure教程:一个通用的app注册/登录页

    今天给大家分享一套APP注册/登录界面模板,其中包括本机登录页面,短信验证登录页面,密码登录页面,人脸登录页面,微博.微信.QQ.支付宝登录页面,注册页面,用户协议和隐私条款.该原型使用简单,交互完善 ...

  7. 阿里云自动java和mysql数据库_阿里云服务器之基于Linux系统部署上线JavaWeb项目和连接MySQL数据库(从购买云服务器到发布JavaWeb项目全套详细流程)...

    阿里云服务器之基于Linux系统部署上线JavaWeb项目和连接MySQL数据库(从购买云服务器到发布JavaWeb项目全套详细流程) (仅此纪念人生第一篇学习博客) 前阵子接了一个小小的JavaWe ...

  8. 系统mysql数据库服务器,系统mysql数据库服务器

    系统mysql数据库服务器 内容精选 换一换 "数据导入"章节适用于MRS 3.x及后续版本.Loader是实现MRS与外部数据源如关系型数据库.SFTP服务器.FTP服务器之间交 ...

  9. 如何查看服务器数据库管理系统,怎么查看服务器的mysql数据库

    怎么查看服务器的mysql数据库 内容精选 换一换 PostgreSQL支持逻辑备份.您可使用pg_dump逻辑备份功能,导出备份文件,再通过psql导入到RDS中,实现将PostgreSQL的数据导 ...

最新文章

  1. 不知道什么时间收集的code
  2. 吴恩达家免费 NLP 课程重磅上线!110 个小视频教你做出聊天机器人,粉丝:我要让娃跟吴恩达姓!...
  3. Laravel 集成 JPush 极光推送指北
  4. Node 中文编码 我为什么哭了
  5. comparable和comparator比较
  6. 2015年传智播客java_2015年Java 8强势开始
  7. 海洋cms宝塔定时linux,海洋CMS使用计划任务实现自动采集/宝塔计划任务自动采集...
  8. 一个主机多显示器的操作方法
  9. 考研前夕 — 成人的世界里没有那么多童话
  10. 数据工程师的终极指南
  11. docker目录 /var/lib/docker/containers 日志清理
  12. oracle 10g 新特性中文笔记
  13. 计算机反复几次才能启动,电脑连续开机几次才能启动怎么办?
  14. mysql自定义函数-随机生成人员姓名
  15. AES加密和RSA加密详细原理及使用场景
  16. 【编程语言】Go 程序设计教程 / 禅与计算机程序设计艺术
  17. linux 常用命令-du统计文件、文件夹命令的使用详情
  18. filemanager简单应用
  19. 怎样让自我评价变成简历最出彩的地方?
  20. excel平均值公式_推荐一款多人同时编辑Excel表,自动生成汇总报表的软件给大家...

热门文章

  1. 华为手机微信与电脑连接到服务器失败怎么办,华为微信到电脑上找不到了怎么办...
  2. 我的未来,何去何从?
  3. Arduino库的接口:Ticker库
  4. Kong 网关 | Rate Limiting 限流
  5. 【中级计量经济学】Lecture 2 多重共线性
  6. 一个基于MFC的QQ机器人框架
  7. 基尔霍夫定律的验证与multisim仿真(附工程文件)
  8. 绝地求生2020服务器维护中,绝地求生2020最新维护公告几点开服?3月18日更新内容一览...
  9. Machine learning techniques to enable closed-loop control in anesthesia-笔记
  10. 【BJOI2019】勘破神机【数论】