Android+SpringBoot前后端分离实现登录注册
一、登录
1.界面设计
2.Android端
(1)布局文件(activity_login)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<include layout="@layout/main_title_bar"/>
<com.example.CircleImageView
android:id="@+id/iv_head"
android:layout_width="wrap_content"
android:layout_height="140dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:contentDescription="@null"
android:src="@drawable/logo1" />
<EditText
android:singleLine="true"
android:id="@+id/et_user_name"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:background="@drawable/zcan3"
android:layout_marginTop="35dp"
android:layout_marginLeft="35dp"
android:layout_marginRight="35dp"
android:drawableLeft="@drawable/yhm1"
android:paddingLeft="8dp"
android:drawablePadding="10dp"
android:hint="@string/name"
android:gravity="center_vertical"
android:textColorHint="#a3a3a3"
android:textColor="#000000"
android:textSize="14sp"/>
<EditText
android:singleLine="true"
android:id="@+id/et_pwd"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:background="@drawable/zcan3"
android:layout_marginTop="10dp"
android:layout_marginLeft="35dp"
android:layout_marginRight="35dp"
android:drawableLeft="@drawable/mm2"
android:paddingLeft="8dp"
android:drawablePadding="10dp"
android:inputType="textPassword"
android:hint="@string/pwd"
android:gravity="center_vertical"
android:textColorHint="#a3a3a3"
android:textColor="#000000"
android:textSize="14sp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="35dp"
android:layout_marginRight="35dp"
android:layout_marginTop="20dp"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="40dp"
android:background="@drawable/linearlayout" >
<EditText
android:id="@+id/et_phoneCodes"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="@null"
android:textColor="#000000"
android:textColorHint="#a3a3a3"
android:hint="请输入右侧验证码" />
</LinearLayout>
<ImageView
android:id="@+id/iv_showCode"
android:layout_width="100dp"
android:layout_marginLeft="10dp"
android:layout_height="match_parent" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginLeft="35dp"
android:orientation="horizontal">
<CheckBox
android:id="@+id/cb_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="记住密码"/>
</LinearLayout>
<Button
android:text="@string/login"
android:id="@+id/btn_login"
android:layout_gravity="center_horizontal"
android:layout_marginTop="15dp"
android:layout_marginLeft="35dp"
android:layout_marginRight="35dp"
android:textColor="@android:color/white"
android:textSize="20sp"
android:textStyle="bold"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:background="@drawable/register_selector"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="15dp"
android:layout_marginLeft="35dp"
android:layout_marginRight="35dp"
android:gravity="center_horizontal"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_register"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:padding="8dp"
android:text="@string/tv_register"
android:textSize="14sp"
android:textColor="@color/white"
android:background="@drawable/register_selector"/>
<TextView
android:id="@+id/tv_find_pwd"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:padding="8dp"
android:text="@string/find_pwd"
android:textSize="14sp"
android:textColor="@color/white"
android:background="@drawable/register_selector"/>
</LinearLayout>
</LinearLayout>
(2)java文件(LoginActivity)
package com.example.activity;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.preference.PreferenceManager;
import com.example.MainActivity;
import com.example.R;
import com.example.bean.User;
import com.example.utils.CodeUtils;
import com.example.utils.SharedPreferencesUtil;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;
import java.util.ArrayList;
import java.util.List;
import okhttp3.Call;
import okhttp3.OkHttpClient;
public class LoginActivity extends Activity {
private TextView tv_main_title;//标题
private TextView tv_back; //返回按钮
private TextView tv_register,tv_find_pwd;//立即注册、找回密码的控件
private Button btn_login; //登录按钮
private RelativeLayout rl_title_bar;//标题布局
private EditText et_user_name,et_pwd;//用户名、密码的控件
private String username,pwd,spPwd;//用户名、密码的控件的获取值
private CheckBox cb_box;
//验证码
private ImageView iv_showCode;
private EditText et_phoneCode;
//产生的验证码
private String realCode;
private List<User> userList = new ArrayList<>();
private SharedPreferencesUtil su;
OkHttpClient client = new OkHttpClient();
private SharedPreferences pref;
private SharedPreferences.Editor editor;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
//设置此界面为竖屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
init();
//验证码
reacode();
// getData();
}
//验证码
private void reacode() {
//将验证码用图片的形式显示出来
iv_showCode.setImageBitmap(CodeUtils.getInstance().createBitmap());
realCode =CodeUtils.getInstance().getCode();
}
private void init() {
// TODO Auto-generated method stub
tv_main_title = (TextView) findViewById(R.id.tv_main_title);
tv_main_title.setText("登录");
tv_back = ((TextView) findViewById(R.id.tv_back));
tv_register = (TextView) findViewById(R.id.tv_register);
tv_find_pwd = (TextView) findViewById(R.id.tv_find_pwd);
pref = PreferenceManager.getDefaultSharedPreferences(this);
su = SharedPreferencesUtil.getInstance(getApplicationContext());
btn_login = (Button) findViewById(R.id.btn_login);
et_user_name = (EditText) findViewById(R.id.et_user_name);
rl_title_bar = (RelativeLayout) findViewById(R.id.title_bar);
et_pwd = (EditText) findViewById(R.id.et_pwd);
cb_box = (CheckBox) findViewById(R.id.cb_box);
rl_title_bar.setBackgroundColor(Color.parseColor("#30b4ff"));
//验证码
et_phoneCode = (EditText) findViewById(R.id.et_phoneCodes);
iv_showCode = (ImageView) findViewById(R.id.iv_showCode);
boolean isremember = pref.getBoolean("cb_box", false);
if (isremember) {
//将账号和密码全部设置到文本框中
String phone = pref.getString("phone", "");
String password = pref.getString("password", "");
et_user_name.setText(phone);
et_pwd.setText(password);
cb_box.setChecked(true);
}
//图片验证码刷新
iv_showCode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
iv_showCode.setImageBitmap(CodeUtils.getInstance().createBitmap());
realCode = CodeUtils.getInstance().getCode();
}
});
//返回按钮的点击事件
tv_back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
LoginActivity.this.finish();
}
});
//立即注册控件的点击事件
tv_register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);
startActivityForResult(intent, 1);
}
});
//找回密码点击事件
tv_find_pwd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//跳转到找回密码界面(此界面暂时未创建)
Intent intent = new Intent(LoginActivity.this, FindPswActivity.class);
startActivityForResult(intent, 1);
}
});
//登录按钮点击事件
btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
username = et_user_name.getText().toString().trim();
pwd = et_pwd.getText().toString().trim();
OkHttpUtils
.get()
.url("http://192.168.119.1:8086/login")
.addParams("userId", username)
.addParams("password", pwd)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int i) {
}
@Override
public void onResponse(String response, int i) {
// if(response.equals("true"))
// Toast.makeText(MainActivity.this, "登录成功!", Toast.LENGTH_LONG).show();
// else
// Toast.makeText(MainActivity.this, "登录失败", Toast.LENGTH_LONG).show();
if (TextUtils.isEmpty(username)) {
Toast.makeText(LoginActivity.this, "请输入用户名", Toast.LENGTH_SHORT).show();
return;
} else if (TextUtils.isEmpty(pwd)) {
Toast.makeText(LoginActivity.this, "请输入密码", Toast.LENGTH_SHORT).show();
return;
} else if (response.equals("true")) {
String phoneCode = et_phoneCode.getText().toString();
if (phoneCode.equals(realCode)) {
Toast.makeText(LoginActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
//把登录状态和登录的用户名保存到SharedPreferences里面
saveLoginStatus(true,username);
// System.out.println("...............................................");
byOkHttp(username);
//登录成功后通过Intent把登录成功的状态传递到MainActivity.java中
Intent data = new Intent();
data.putExtra("status", true);
setResult(RESULT_OK, data);//setResult为OK,关闭当前页面
LoginActivity.this.finish();//在登录的时候,如果用户还没有注册则注册。注册成功后把注册成功后的用户名返回给前一个页面
startActivity(new Intent(LoginActivity.this, MainActivity.class));
editor = pref.edit();
if (cb_box.isChecked()) {
editor.putBoolean("cb_box", true);
editor.putString("phone", username);
editor.putString("password", pwd);
} else {
editor.clear();
}
editor.apply();
} else {
Toast.makeText(LoginActivity.this, phoneCode + "验证码错误", Toast.LENGTH_SHORT).show();
}
return;
} else if (!byOkHttpUtils(username) && !response.equals(true)) {
Toast.makeText(LoginActivity.this, "用户名或密码错误", Toast.LENGTH_SHORT).show();
return;
} else {
Toast.makeText(LoginActivity.this, "此用户不存在", Toast.LENGTH_SHORT).show();
}
}
});
// String md5Pwd=MD5Utils.MD5(pwd);
// spPwd=readPwd(username);
}
public Boolean byOkHttpUtils(String userId){
final Boolean[] flag = {false};
OkHttpUtils
.get()
.addParams("userId",userId)
// .addParams("userName",userName)
// .addParams("password",password)
.url("http://169.254.21.102:8086/register")
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int i) {
}
@Override
public void onResponse(String response, int i) {
if (response.equals("true")) {
flag[0] = true;
//Toast.makeText(RegisterActivity.this, "注册成功!", Toast.LENGTH_LONG).show();}
// else
//Toast.makeText(RegisterActivity.this, "注册失败,可能已存在当前账号", Toast.LENGTH_LONG).show();
}
//
// return response.equals("true");
//return return_value.equals("true")
}
});
return flag[0];
}
public void byOkHttp(String userId){
//创建OkHttpClient对象
OkHttpUtils
.get()
.url("http://169.254.21.102:8086/update")
.addParams("userId", userId)
// .addParams("status", String.valueOf(status))
.build();
if(userId!=null){
//从注册界面传递过来的用户名
//String username=data.getStringExtra("username");
System.out.println(true);
if(!TextUtils.isEmpty(username)){
et_user_name.setText(username);
//设置光标的位置上
et_user_name.setSelection(username.length());
}
}
//获取返回的json数据
//String return_value = response.body().toString();
// if(return_value.equals("true")){
// Toast.makeText(register.this, "注册成功!", Toast.LENGTH_LONG).show();
// }
// else {
// Toast.makeText(register.this, "注册失败,可能已存在当前账号邮箱", Toast.LENGTH_LONG).show();
// }
// return return_value.equals("true");
}
//从SharedPreferences中根据用户名读取密码
// private String readPwd(String username){
// SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE);
// return sp.getString(username,"");
// }
//保存登录状态和登录用户名到SharedPrefarences中
private void saveLoginStatus(boolean status,String username){
//loginInfo表示文件名
SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE);
SharedPreferences.Editor editor=sp.edit();//获取编辑器
editor.putBoolean("isLogin", status);
editor.putString("loginUserName", username);//存入登录时的用户名
editor.commit();//提交修改
}
// @Override
// protected void onActivityResult(int requestCode,int resultCode,
// Intent data){
// super.onActivityResult(requestCode, resultCode, data);
// if(data!=null){
// //从注册界面传递过来的用户名
// String username=data.getStringExtra("username");
// if(!TextUtils.isEmpty(username)){
// et_user_name.setText(username);
// //设置光标的位置上
// et_user_name.setSelection(username.length());
// }
// }
// }
});
}
}
这里注意要将接口地址改为你自己电脑的IPv4地址
下面给出找到IPv4地址的步骤
1.Win+R,输入ipconfig
2.找到以太网适配器,下面的IPv4就是你电脑的IP地址了
(3)User
package com.example.bean;
/**
*/
public class User {
private String uid;
private String username;
private String upassword;
private String uname;
public User(String uid, String username, String upassword, String uname) {
this.uid = uid;
this.username = username;
this.upassword = upassword;
this.uname = uname;
}
public User(String username, String upassword,String uname) {
this.username = username;
this.upassword = upassword;
this.uname = uname;
}
public User() {
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUpassword() {
return upassword;
}
public void setUpassword(String upassword) {
this.upassword = upassword;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
}
(4)CodeUtils
package com.example.utils;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import java.util.Random;
public class CodeUtils {
//随机码集
private static final char[] CHARS = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
};
private static CodeUtils mCodeUtils;
private int mPaddingLeft, mPaddingTop;
private StringBuilder mBuilder = new StringBuilder();
private Random mRandom = new Random();
//Default Settings
private static final int DEFAULT_CODE_LENGTH = 4;//验证码的长度 这里是4位
private static final int DEFAULT_FONT_SIZE = 60;//字体大小
private static final int DEFAULT_LINE_NUMBER = 3;//多少条干扰线
private static final int BASE_PADDING_LEFT = 20; //左边距
private static final int RANGE_PADDING_LEFT = 30;//左边距范围值
private static final int BASE_PADDING_TOP = 70;//上边距
private static final int RANGE_PADDING_TOP = 15;//上边距范围值
private static final int DEFAULT_WIDTH = 200;//默认宽度.图片的总宽
private static final int DEFAULT_HEIGHT = 100;//默认高度.图片的总高
private static final int DEFAULT_COLOR = Color.rgb(0xee, 0xee, 0xee);//默认背景颜色值
private String code;
public static CodeUtils getInstance() {
if (mCodeUtils == null) {
mCodeUtils = new CodeUtils();
}
return mCodeUtils;
}
//生成验证码图片
public Bitmap createBitmap() {
mPaddingLeft = 0; //每次生成验证码图片时初始化
mPaddingTop = 0;
Bitmap bitmap = Bitmap.createBitmap(DEFAULT_WIDTH, DEFAULT_HEIGHT, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
code = createCode();
canvas.drawARGB(0, 0, 0, 0);
canvas.drawColor(DEFAULT_COLOR);
Paint paint = new Paint();
paint.setTextSize(DEFAULT_FONT_SIZE);
for (int i = 0; i < code.length(); i++) {
randomTextStyle(paint);
randomPadding();
canvas.drawText(code.charAt(i) + "", mPaddingLeft, mPaddingTop, paint);
}
//干扰线
for (int i = 0; i < DEFAULT_LINE_NUMBER; i++) {
drawLine(canvas, paint);
}
canvas.save();//保存
canvas.restore();
return bitmap;
}
/**
* 得到图片中的验证码字符串
*
* @return
*/
public String getCode() {
return code;
}
//生成验证码
public String createCode() {
mBuilder.delete(0, mBuilder.length()); //使用之前首先清空内容
for (int i = 0; i < DEFAULT_CODE_LENGTH; i++) {
mBuilder.append(CHARS[mRandom.nextInt(CHARS.length)]);
}
return mBuilder.toString();
}
//生成干扰线
private void drawLine(Canvas canvas, Paint paint) {
int color = randomColor();
int startX = mRandom.nextInt(DEFAULT_WIDTH);
int startY = mRandom.nextInt(DEFAULT_HEIGHT);
int stopX = mRandom.nextInt(DEFAULT_WIDTH);
int stopY = mRandom.nextInt(DEFAULT_HEIGHT);
paint.setStrokeWidth(1);
paint.setColor(color);
canvas.drawLine(startX, startY, stopX, stopY, paint);
}
//随机颜色
private int randomColor() {
mBuilder.delete(0, mBuilder.length()); //使用之前首先清空内容
String haxString;
for (int i = 0; i < 3; i++) {
haxString = Integer.toHexString(mRandom.nextInt(0xEE));
if (haxString.length() == 1) {
haxString = "0" + haxString;
}
mBuilder.append(haxString);
}
return Color.parseColor("#" + mBuilder.toString());
}
//随机文本样式
private void randomTextStyle(Paint paint) {
int color = randomColor();
paint.setColor(color);
paint.setFakeBoldText(mRandom.nextBoolean()); //true为粗体,false为非粗体
float skewX = mRandom.nextInt(11) / 10;
skewX = mRandom.nextBoolean() ? skewX : -skewX;
paint.setTextSkewX(skewX); //float类型参数,负数表示右斜,整数左斜
paint.setUnderlineText(mRandom.nextBoolean()); //true为下划线,false为非下划线
paint.setStrikeThruText(mRandom.nextBoolean()); //true为删除线,false为非删除线
}
//随机间距
private void randomPadding() {
mPaddingLeft += BASE_PADDING_LEFT + mRandom.nextInt(RANGE_PADDING_LEFT);
mPaddingTop = BASE_PADDING_TOP + mRandom.nextInt(RANGE_PADDING_TOP);
}
}
(5)SharedPreferencesUtil
package com.example.utils;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
/**
* 状态保存工具类
*/
public class SharedPreferencesUtil {
private static final String TOKEN = "TOKEN";
// SharedPreferences是Android平台上一个轻量级的存储辅助类
private static SharedPreferences myPreferences;
private static SharedPreferences.Editor editor;
private static SharedPreferencesUtil mSharedPreferencesUtil;
private final Context context;
public SharedPreferencesUtil(Context context) {
this.context = context.getApplicationContext();
// 调用Context对象的getSharedPreferences()方法获得的SharedPreferences对象可以被同一应用程序下的其他组件共享.
myPreferences = this.context.getSharedPreferences("TAG", Context.MODE_PRIVATE);
editor = myPreferences.edit();
}
/**
* 单例实现
* @param context
* @return
*/
public static SharedPreferencesUtil getInstance(Context context) {
if(mSharedPreferencesUtil == null ) {
mSharedPreferencesUtil = new SharedPreferencesUtil(context);
}
return mSharedPreferencesUtil;
}
/**
* 设置值
* @param key
* @param value
*/
public void setValue(String key, String value) {
editor.putString(key, value);
editor.commit();
}
/**
* 清空
*/
public void clear() {
editor.clear();
editor.commit();
}
/**
* 获取值
* @param key
* @return
*/
public String getValue(String key) {
return myPreferences.getString(key, "");
}
/**
* 设置登陆状态(存入token)
* @param token
*/
public void toLogin(String token) {
setValue(TOKEN, token);
}
public boolean isLogin() {
String token = getValue(TOKEN);
Log.e("token", token);
if("".equals(token)) {
return false;
} else {
return true;
}
}
}
(6)需要导入的依赖
implementation 'com.squareup.okhttp3:okhttp:3.14.0'
implementation 'com.squareup.okhttp:okhttp:2.7.5'
implementation 'com.zhy:okhttputils:2.6.2'
(7)申请权限:在AndroidManifest.xml中加入以下代码
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
二、注册
1.界面设计
2.Android端
(1)布局文件(activity_register)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/activity_register"
android:orientation="vertical" >
<include layout="@layout/main_title_bar" />
<com.example.CircleImageView
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:contentDescription="@null"
android:src="@drawable/logo1" />
<EditText
android:singleLine="true"
android:id="@+id/et_user_name"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:background="@drawable/zcan3"
android:layout_marginTop="35dp"
android:layout_marginLeft="35dp"
android:layout_marginRight="35dp"
android:drawableLeft="@drawable/yhm1"
android:paddingLeft="8dp"
android:drawablePadding="10dp"
android:hint="@string/name"
android:gravity="center_vertical"
android:textColorHint="#a3a3a3"
android:textColor="#000000"
android:textSize="14sp"/>
<EditText
android:id="@+id/et_pwd"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:layout_marginLeft="35dp"
android:layout_marginRight="35dp"
android:background="@drawable/zcan3"
android:drawableLeft="@drawable/mm2"
android:drawablePadding="10dp"
android:gravity="center_vertical"
android:hint="@string/pwd"
android:inputType="textPassword"
android:paddingLeft="8dp"
android:singleLine="true"
android:textColor="#000000"
android:textColorHint="#a3a3a3"
android:textSize="14sp" />
<EditText
android:singleLine="true"
android:id="@+id/et_pwd_again"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:background="@drawable/zcan3"
android:layout_marginLeft="35dp"
android:layout_marginRight="35dp"
android:drawableLeft="@drawable/mm2"
android:paddingLeft="8dp"
android:drawablePadding="10dp"
android:inputType="textPassword"
android:hint="@string/pwd_again"
android:gravity="center_vertical"
android:textColorHint="#a3a3a3"
android:textColor="#000000"
android:textSize="14sp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="30dp"
android:background="@drawable/zcan3"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:text="中国+86"
android:textColor="#A2CD5A"
android:textSize="16sp" />
<View
android:layout_width="0.1dp"
android:layout_height="match_parent"
android:background="#FF7F00" />
<EditText
android:id="@+id/et_forgetPass_PhoneNum"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:background="@null"
android:digits="0123456789"
android:hint="请填入您的手机号"
android:inputType="number"
android:maxLength="11"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
<!-- <LinearLayout-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginLeft="15dp"-->
<!-- android:layout_marginRight="15dp"-->
<!-- android:layout_marginTop="20dp"-->
<!-- android:orientation="horizontal">-->
<!-- <LinearLayout-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="45dp"-->
<!-- android:background="@drawable/zcan3">-->
<!-- <EditText-->
<!-- android:id="@+id/et_phoneCodes"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- android:layout_marginLeft="10dp"-->
<!-- android:layout_marginRight="10dp"-->
<!-- android:background="@null"-->
<!-- android:hint="请输入右侧验证码" />-->
<!-- </LinearLayout>-->
<!-- <ImageView-->
<!-- android:id="@+id/image"-->
<!-- android:layout_width="100dp"-->
<!-- android:layout_height="match_parent"-->
<!-- android:layout_marginLeft="10dp" />-->
<!-- </LinearLayout>-->
<!-- <Button-->
<!-- android:id="@+id/but_forgetpass_toSetCodes"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_margin="35dp"-->
<!-- android:background="@drawable/register_selector"-->
<!-- android:text="获取验证码"-->
<!-- android:textColor="#fff" />-->
<Button
android:text="@string/btn_register"
android:id="@+id/btn_register"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp"
android:layout_marginLeft="35dp"
android:layout_marginRight="35dp"
android:textColor="@android:color/white"
android:textSize="20sp"
android:textStyle="bold"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:background="@drawable/register_selector"/>
</LinearLayout>
(2)java文件(RegisterActivity)
package com.example.activity;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.example.R;
import com.example.utils.MD5Utils;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;
import okhttp3.Call;
public class RegisterActivity extends Activity {
private TextView tv_main_title;//标题
private TextView tv_back; //返回按钮
private RelativeLayout rl_title_bar;//标题布局
private Button btn_register; //注册按钮
private EditText et_user_name,et_pwd,et_pwd_again;//用户名、密码、再次输入的密码的控件
private String username,pwd,pwd_again;//用户名、密码、再次输入的密码的控件的获取值
private Bitmap bitmap;
private String code;
//验证码
private ImageView iv_showCode;
private EditText et_phoneCode;
//产生的验证码
private String realCode;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
init();
// //验证码
// reacode();
// //获取需要展示图片验证码的ImageView
// final ImageView image = (ImageView) findViewById(R.id.image);
// //获取工具类生成的图片验证码对象
// bitmap = CodeUtils.getInstance().createBitmap();
// //获取当前图片验证码的对应内容用于校验
// code = CodeUtils.getInstance().getCode();
// image.setImageBitmap(bitmap);
// image.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View view) {
// bitmap = CodeUtils.getInstance().createBitmap();
// code = CodeUtils.getInstance().getCode();
// image.setImageBitmap(bitmap);
// Toast.makeText(RegisterActivity.this, code, Toast.LENGTH_SHORT).show();
// }
// });
}
//验证码
// private void reacode() {
//
// //将验证码用图片的形式显示出来
// iv_showCode.setImageBitmap(CodeUtils.getInstance().createBitmap());
// realCode =CodeUtils.getInstance().getCode();
// }
private void init() {
// TODO Auto-generated method stub
//从main_title_bar.xml页面布局中获取对应的UI控件
//抽取成员变量ctrl+alt+F
tv_main_title = (TextView) findViewById(R.id.tv_main_title);
tv_main_title.setText("注册");
tv_back = ((TextView) findViewById(R.id.tv_back));
rl_title_bar = (RelativeLayout) findViewById(R.id.title_bar);
// rl_title_bar.setBackgroundColor(Color.TRANSPARENT);
rl_title_bar.setBackgroundColor(Color.parseColor("#30b4ff"));
//从activity_register.xml页面布局中获取对应的UI控件
btn_register = (Button) findViewById(R.id.btn_register);
et_user_name = (EditText) findViewById(R.id.et_user_name);
et_pwd = (EditText) findViewById(R.id.et_pwd);
et_pwd_again = (EditText) findViewById(R.id.et_pwd_again);
//验证码
et_phoneCode = (EditText) findViewById(R.id.et_phoneCodes);
iv_showCode = (ImageView) findViewById(R.id.iv_showCode);
// //图片验证码刷新
// iv_showCode.setOnClickListener(new View.OnClickListener() {
//
// @Override
// public void onClick(View arg0) {
// // TODO Auto-generated method stub
// iv_showCode.setImageBitmap(CodeUtils.getInstance().createBitmap());
// realCode = CodeUtils.getInstance().getCode();
// }
// });
tv_back.setOnClickListener(new View.OnClickListener() {
@Override//关闭页面的点击事件
public void onClick(View view) {//设置按钮可以关闭当前页面
RegisterActivity.this.finish();
}
});
//注册按钮点击事件
btn_register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//点击后获取输入在响应控件中的字符串
getEditstring();
//判断字符串是否为空
if(TextUtils.isEmpty(username)){
Toast.makeText(RegisterActivity.this, "请输入用户名", Toast.LENGTH_SHORT).show();
return;
}else if (TextUtils.isEmpty(pwd)){
Toast.makeText(RegisterActivity.this, "请输入密码", Toast.LENGTH_SHORT).show();
return;
}else if (TextUtils.isEmpty(pwd_again)){
Toast.makeText(RegisterActivity.this, "请再次输入密码", Toast.LENGTH_SHORT).show();
return;
}else if (!pwd.equals(pwd_again)){
Toast.makeText(RegisterActivity.this, "两次输入的密码不一样", Toast.LENGTH_SHORT).show();
return;
} else if (byOkHttpUtils(username,username,pwd)){
Toast.makeText(RegisterActivity.this, "此用户已经存在", Toast.LENGTH_SHORT).show();
return;
}else {
Toast.makeText(RegisterActivity.this, "注册成功", Toast.LENGTH_SHORT).show();
//把用户名和密码保存到SharedPreferences里面
//byOkHttp(username,username,pwd);
saveRegisterInfo(username,pwd);
//注册成功后通过Intent把用户名传递到LoginActivity.java中
Intent data=new Intent();
data.putExtra("username",username);
setResult(RESULT_OK,data);//setResult为OK,关闭当前页面
RegisterActivity.this.finish();//在登录的时候,如果用户还没有注册则注册。注册成功后把注册成功后的用户名返回给前一个页面
}
}
});
}
private void saveRegisterInfo(String username, String pwd) {
String md5Pwd= MD5Utils.MD5(pwd);//把密码用MD5加密
//loginInfo是sp的文件名
SharedPreferences sp=getSharedPreferences("loginInfo",MODE_PRIVATE);//通过getSharedPreferences传入loginInfo注册登录相关的信息
SharedPreferences.Editor editor = sp.edit();//通过sp.edit()获取到sp的编辑器对象
//username作为key,密码作为value
editor.putString(username,md5Pwd);
editor.commit();//提交修改
}
/**
* 从SharedPreferences中读取输入的用户名,判断SharedPreferences中是否有用户名
* @return
*/
// private boolean isExistUserName(String username) {
// boolean has_userName=false;//表示是否有用户名
// SharedPreferences sp=getSharedPreferences("loginInfo",MODE_PRIVATE);
// String spPwd = sp.getString(username,""); //通过sp.getString传值用户名获取到密码
// if (!TextUtils.isEmpty(spPwd)){ //判断这个密码是否为空
// has_userName=true;//该用户是否保存了这一个密码
// }
// return has_userName;
// }
public Boolean byOkHttpUtils(String userId,String userName,String password){
final Boolean[] flag = {false};
OkHttpUtils
.get()
.addParams("userId",userId)
.addParams("userName",userName)
.addParams("password",password)
.url("http://192.168.119.1:8086/register")
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int i) {
}
@Override
public void onResponse(String response, int i) {
if (response.equals("true")) {
flag[0] = true;
//Toast.makeText(RegisterActivity.this, "注册成功!", Toast.LENGTH_LONG).show();}
// else
//Toast.makeText(RegisterActivity.this, "注册失败,可能已存在当前账号", Toast.LENGTH_LONG).show();
}
//
// return response.equals("true");
//return return_value.equals("true")
}
});
return flag[0];
}
// private void byOkHttp(String userId,String userName,String password){
// //创建OkHttpClient对象
// OkHttpClient okHttpClient = new OkHttpClient();
//
// //建立请求表单,添加上传服务器的参数
// RequestBody formBody = new FormEncodingBuilder()
// .add("userId", userId)
// .add("password", password)
// .add("userName",userName)
// .build();
//
// // 建立请求并绑定数据
// Request request = new Request.Builder()
// .url("http://169.254.21.102:8086/register")
// .post(formBody)
// .build();
//
//响应
// Response response = null;
// try {
// response = okHttpClient.newCall(request).execute();
// } catch (IOException e) {
// e.printStackTrace();
// }
//
// //获取返回的json数据
// String return_value = response.body().toString();
// if(return_value.equals("true")){
// Toast.makeText(RegisterActivity.this, "注册成功!", Toast.LENGTH_LONG).show();
// // return true;
// }
// else {
// Toast.makeText(RegisterActivity.this, "注册失败,可能已存在当前账号", Toast.LENGTH_LONG).show();
// // return false;
// }
//
// }
/**
* 获取控件中的字符串
*/
private void getEditstring() {
username=et_user_name.getText().toString().trim();
pwd = et_pwd.getText().toString();
pwd_again = et_pwd_again.getText().toString().trim();
}
}
这里注意也要将接口地址改为你自己电脑的IPv4地址
(3)MD5Utils
package com.example.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Utils {
/**
* md5加密的算法
* @param text
* @return
*/
public static String MD5(String text){
try {
MessageDigest digest = MessageDigest.getInstance("md5");
byte[] result = digest.digest(text.getBytes());
StringBuffer sb=new StringBuffer();
for (byte b:result){
int number =b & 0xff;
String hex=Integer.toHexString(number);
if (hex.length()==1){//如果0xff为一个字节
sb.append("0"+hex);
}else {
sb.append(hex);
}
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return "";//如果发生异常
}
}
}
三、数据库
1.数据库就是简单的一个user表
四、SpringBoot端
1.创建springboot项目
注意:在develorper toots,web,sql选中相应右边的选项一共7个
(1)项目基本结构
2.配置文件(pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>demo</description>
<properties>
<java.version>8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-jpa</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.project-lombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.Controller层(TestController)
package com.example.demo.controller;
import com.example.demo.repository.UserRepository;
import com.example.demo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
public class TestController {
@Autowired
private UserRepository userRepository;
// private JdbcTemplate jdbcTemplate;
@RequestMapping(value="/getUsers",method = RequestMethod.GET)
@ResponseBody
public List<User> findAll(){
List<User> userList = userRepository.findAll();
return userList;
}
@RequestMapping(value = "/register",method = RequestMethod.GET)
public boolean register(@RequestParam("userId") String userId,
@RequestParam("userName") String userName,
@RequestParam("password") String password){
try {
userRepository.register(userId,userName,password);
System.out.println("可以正常执行");
return true; //注册成功则返回true
} catch (Exception e) {
e.printStackTrace();
}return false;
}
@RequestMapping(value ="/login",method = RequestMethod.GET)
public boolean login(@RequestParam("userId") String userId,
@RequestParam("password") String password){
User user=null;
user = userRepository.login(userId,password);
//对比密码,相同则返回true,正常情况会加密解密,为求简单就不那么做了
if(user.getPassword().equals(password))
return true;
return false;
}
}
4.entity层(User)
package com.example.demo.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
String userId;
String userName;
String password;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
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;
}
}
5.mapper层(UserMapper)
package com.example.demo.mapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserMapper {
List<User> findAll();
void register(String userId, String userName,String password);
User login(String userId,String password);
// Boolean update(String userId,Boolean status);
}
6.UserRepositoryImpl
package com.example.demo.repository.Impl;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class UserRepositoryImpl implements UserRepository {
@Autowired
UserMapper userMapper;
@Override
public List<User> findAll() {
return userMapper.findAll();
}
@Override
public void register(String userId, String userName,String password) {
userMapper.register(userId, userName,password);
}
@Override
public User login(String userId, String password) {
return userMapper.login(userId,password);
}
// @Override
// public Boolean update(String userId,Boolean status){return userMapper.update(userId,status);}
}
7.repository层(UserRepository)
package com.example.demo.repository;
import com.example.demo.entity.User;
import java.util.List;
public interface UserRepository {
public List<User> findAll();
public void register(String userId,String userName,String password);
public User login(String userId,String password);
// public Boolean update(String userId,Boolean status);
}
8.UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
<select id="findAll" resultType="com.example.demo.entity.User">
select * from user
</select>
<insert id="register" parameterType="com.example.demo.entity.User">
insert USER values (#{userId},#{userName},#{password});
</insert>
<select id="login" parameterType="com.example.demo.entity.User" resultType="com.example.demo.entity.User">
select *from USER where userId=#{userId}
</select>
<!-- <update id="update" parameterType="com.example.demo.entity.User">-->
<!-- update USER set status=#{status}-->
<!-- where userId = #{userId}-->
<!-- </update>-->
<!-- ,userName=#{userName},password=#{password},-->
</mapper>
9.配置文件(application.properties)
#============ thymeleaf???? ?? start ==============
#????
server.port=8086
spring.thymeleaf.prefix=classpath:/pages/
#????
spring.thymeleaf.suffix=.html
#??
spring.thymeleaf.mode=LEGACYHTML5
#??
spring.thymeleaf.encoding=utf-8
#Servlet????
spring.thymeleaf.servlet.content-type=text/html
#???????,?????????????????
spring.thymeleaf.cache=false
#======================?????============================
#?????
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#????????
#spring.datasource.url=jdbc:mysql://localhost:3306/student?serverTimezone=GMT%2B8&verifyServerCertificate=false&useSSL=false
spring.datasource.url=jdbc:mysql://localhost:3307/testandorid?useUnicode=true&characterEncoding=UTF-8&useSSL=false
#???
spring.datasource.username=root
#??
spring.datasource.password=123456
#===================??Mybatis???=======================
#?????????
mybatis.mapper-locations=classpath:mapper/*.xml
1.注意:这里的数据库端口号和数据库改为你自己的
五、功能实现步骤
1.打开数据库
2.运行SpringBoot
3.运行Android
到这里一个简单的Android+SpringBoot前后端分离实现登录注册就结束了,希望能给你带来帮助和启发!有不懂的地方欢迎交流学习😊😊😊