admin管理员组文章数量:1597400
认真学习安卓也有三四个月了,现在记录一下关于用户的各种操作。
1.安卓APP的实现:
先看一下展示动图吧!
首先是登录界面的xml---------activity_mian.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android/apk/res/android"
xmlns:tools="http://schemas.android/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下载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/xml/ns/javaee" xmlns:xsi="http://www.w3/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun/xml/ns/javaee http://java.sun/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/Mr_Megamind/article/details/71404618
版权声明:本文标题:安卓APP注册登录+Tomcat服务器搭建+MySQL数据库建立+加密传输+servlet后端内容编写及部署到Tomcat服务器 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1728282002a1151908.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论