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

安卓+后端 专栏收录该内容
11 篇文章 0 订阅

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

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">
    <!--
    登录页面
    -->
    <EditText
        android: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"/>
    <EditText
        android: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"/>
    <Button
        android: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"/>
    <Button
        android: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"/>
    <Button
        android: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;
    @Override
    protected 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() {
            @Override
            public 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() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, RegisterActivity.class);
                startActivity(intent);
            }
        });
        //忘记密码
        forget_password.setOnClickListener(new View.OnClickListener() {
            @Override
            public 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";
        //取得请求队列l
        RequestQueue 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>() {
                    @Override
                    public 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);//关掉所要到的界面中间的activity
                                intent.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() {
            @Override
            public void onErrorResponse(VolleyError error) {
                //做自己的响应错误操作,如Toast提示(“请稍后重试”等)
                Log.e("TAG", error.getMessage(), error);
                Toast.makeText(mContext, "无网络连接", Toast.LENGTH_LONG).show();
            }
        }) {
            @Override
            protected 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个byte
            int 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);
                else
                    cipher.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;                        //定义数据库连接URL
    private static Connection connection;             //定义连接

    @Override
    public 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;
    @Override
    protected 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);//用户名解密BASE64
            byte[] 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);
           
        }
    }

    @Override
    protected 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

  • 5
    点赞
  • 28
    评论
  • 22
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值