前言
前端是安卓开发,后端运用springboot+mybatis搭起的一个项目
登录注册主要是利用Java的http请求,返回json数据格式,也可以自定义返回类型,存在本地的数据库
一 springboot+mybatis的搭建
登录注册接口
package com.ghc.controller;
import com.ghc.service.LoginService;
import com.ghc.util.R;
import com.ghc.util.StringTool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
public class LoginController {
@Autowired
LoginService loginService;
@PostMapping("/login")
public R login(@RequestParam(value = "login_name")String user,@RequestParam(value = "pwd")String password ){
if(StringTool.isEmpty(user,password)){
return R.error("账号或者密码为空");
}
else {
return loginService.doLogin(user,password);
}
}
@RequestMapping("register")
public R register(String user, String pwd, String role){
if(StringTool.isEmpty(user,pwd,role)){
return R.error("注册信息含有空字符");
}
else {
return loginService.Register(user,pwd,role);
}
}
}
登录注册接口实现类
package com.ghc.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ghc.dao.TSysRoleDao;
import com.ghc.dao.TSysUserDao;
import com.ghc.dao.TSysUserRoleDao;
import com.ghc.dao.impl.TSysUserDaoImpl;
import com.ghc.entity.TSysUser;
import com.ghc.entity.TSysUserRole;
import com.ghc.entity.token;
import com.ghc.mapper.TCourseMapper;
import com.ghc.service.LoginService;
import com.ghc.util.JWTUtil;
import com.ghc.util.R;
import com.ghc.util.StringTool;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class LoginServiceImpl implements LoginService {
QueryWrapper queryWrapper=new QueryWrapper();
@Autowired
TSysUserDao tSysUserDao;
@Autowired
TSysRoleDao tSysRoleDao;
@Autowired
TSysUserRoleDao tSysUserRoleDao;
/*登录*/
@Override
public R doLogin(String user, String password) {
List loginname=tSysUserDao.getColumn("login_name");
for(int i=0;i<loginname.size();i++){
if(loginname.get(i).toString().equals(user)){
queryWrapper.eq("login_name",user);
Map tSysUser=tSysUserDao.getMap(queryWrapper);
if(tSysUser.get("password").equals(StringTool.getMD5(password))){
Map map=new HashMap();
map.put("user",user);
map.put("pwd",password);
String tokenString=JWTUtil.jwt(map);
token token=new token();
token.setToken(tokenString);
List list=new ArrayList();
list.add(token);
System.out.println(R.restResult(0,list,"登录成功"));
return R.restResult(0,token,"登录成功");
}
else {
return R.error("密码错误");
}
}
return R.error("用户名不存在");
}
return R.restResult(500,null,"系统错误");
}
/*注册*/
@Transactional(isolation=Isolation.REPEATABLE_READ,
propagation = Propagation.REQUIRED
)
@Override
public R Register(String user, String password, String role) {
try {
queryWrapper.eq("login_name",user);
//用户名唯一,判断用户名登录名是否重复
if(tSysUserDao.list(queryWrapper).size()==0){
//登录名不在数据库
queryWrapper.clear();
queryWrapper.eq("name",role);
Map role1= tSysRoleDao.getMap(queryWrapper);
if(role1.size()==0){
//未查得角色名
return R.error("未查得角色名");
}else {
TSysUser tSysUser=new TSysUser();
tSysUser.setLoginName(user);
tSysUser.setPassword(StringTool.getMD5(password));
tSysUserDao.save(tSysUser);
queryWrapper.clear();
queryWrapper.eq("login_name",user);
TSysUserRole tSysUserRole=new TSysUserRole();
tSysUserRole.setUserId((int)tSysUserDao.getMap(queryWrapper).get("id"));
queryWrapper.clear();
queryWrapper.eq("name",role);
tSysUserRole.setRoleId((Integer) role1.get("id"));
tSysUserRoleDao.save(tSysUserRole);
return R.ok("注册成功");
}
}
else {
return R.error("用户名已存在");
}
}catch (Exception e){
e.printStackTrace();
return R.error("服务器出错");
}
}
}
二、android登录功能实现
页面实现,这里主要用到线性布局,TextView组件,EditText组件,以及Button主键以及权重,小编在这多句嘴哈,权重主要解决屏幕适配的问题,众所周知手机的屏幕尺寸大小不一,因此利用权重来解决适配的问题,但还有其他的办法,对小编来说目前就使用权重 android:layout_weight=“8”,界面的美观全靠自己的审美设计来定的,所以界面的美观,全靠大家的知识面,来完成更炫酷的界面
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.login.Login"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="登录"
android:textColor="#000000"
android:textSize="40sp"></TextView>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:gravity="center"
android:text="欢迎来到登录页面"
android:textColor="#000000"
android:textSize="25dp"></TextView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:orientation="horizontal">
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="手机号:"
android:textSize="20sp" />
<EditText
android:id="@+id/phone"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="8"
android:ems="10"
android:hint="请输入你的手机号"
android:inputType="textPersonName" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="密码:"
android:textSize="20sp"
/>
<EditText
android:id="@+id/password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="8"
android:ems="10"
android:hint="请输入你的密码"
android:inputType="textPassword" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:orientation="vertical">
<Button
android:id="@+id/log_but"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/circular_moment"
android:text="登录"
android:textColor="#ffffff"
android:textSize="20dp" />
<Button
android:id="@+id/register"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="@drawable/circular_moment"
android:text="注册"
android:textColor="#ffffff"
android:textSize="20dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
shape资源转载
圆矩:制作
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- rectangle表示为矩形 -->
<!-- 填充的颜色 -->
<solid android:color="#03A9F4" />
<!-- 边框的颜色和粗细 -->
<stroke
android:width="1dp"
android:color="#989898"
/>
<!-- android:radius 圆角的半径 -->
<corners
android:radius="20dp"
/>
</shape>
三、登录功能实现分析:
根据项目要求,我们需要从后端取数据来匹配进行登录认证,因此,大家会想到我们怎么测呢?用什么来发起网络请求和响应呢?拿到数据又该怎么用呢?刚刚接触的伙伴是不是都跟我的想法,差不多呢?
现在,我就根据自己在实际操作中的想法一一给大家分析。
怎么测试?我们可以通过Postman这款工具来实现测试。
以上就是接口所给的参数,通过测试,会返回json键值对,并且大家要分清自己的什么是json对象,什么是json数组, { }这种形式的就是对象 [ ] 这个款式的就是数组 一般我遇到对象 就是一个JSONObject解析 遇到数组就JSONArray
首先,我们要在 AndroidManifest.xml添加网络权限
<uses-permission android:name="android.permission.INTERNET" />
其次,初始化组件对象
private EditText phone;//账号
private EditText password;//密码
private Button loginBut;//登录
private Button registerBut;//注册
根据自己运用的组件来,然后我们需要找到组件组件对应的ID,也可以理解为赋值
phone = findViewById(R.id.phone);
password = findViewById(R.id.password);
loginBut = findViewById(R.id.log_but);
registerBut = findViewById(R.id.register);
接下来,我们要做一件有意义的事情,完成登录事件处理,以下来完成登录事件监听,就是可以理解为当点击登录按钮的时候,要发生些什么有趣的事件,比如跳转页面,获取其他的根据项目需求而来。
loginBut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
由于,用户登录的时候,咱们需要向服务器发起请求,因此我们又需要用到okHttp,这些个东西都是开源的也可以自己去官网下载,也可以去build.gradle 添加,来进行缓存
implementation 'com.squareup.okhttp3:okhttp:3.4.1'
接下来,我们就要做这个事件的核心,就是把数据转换为json键值对来提交到服务器进行匹配,配对成功了,那就登录成功:
Login完成代码
package com.fall.project.ui.login;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import com.fall.project.R;
import com.fall.project.ui.Index.Index;
import com.fall.project.ui.register.Register;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class Login extends AppCompatActivity {
private EditText phone;//账号
private EditText password;//密码
private Button loginBut;//登录
private Button registerBut;//注册
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
//隐藏标题栏
ActionBar actionBar = getSupportActionBar();
actionBar.hide();
//赋值
phone = findViewById(R.id.phone);
password = findViewById(R.id.password);
loginBut = findViewById(R.id.log_but);
registerBut = findViewById(R.id.register);
//登录点击事件
loginBut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (phone.getText().toString().equals("")){
Toast.makeText(Login.this,"手机号不能为空",Toast.LENGTH_SHORT).show();
return;
}
if (password.getText().toString().equals("")){
Toast.makeText(Login.this,"密码不能为空",Toast.LENGTH_SHORT).show();
return;
}
//开启线程发起网络请求
new Thread(new Runnable() {
@Override
public void run() {
MediaType JSON=MediaType.parse("application/json;charset=utf-8");
JSONObject json=new JSONObject();//创建一个json键值对
try {
json.put("phone",phone.getText());//输入框输入的数据
json.put("password",password.getText());
} catch (JSONException e) {
e.printStackTrace();
}
//拿到OkHttpClient对象
OkHttpClient client=new OkHttpClient();
RequestBody requestBody=RequestBody.create(JSON,String.valueOf(json));
Request request=new Request.Builder()
.url("http://150.158.117.228:8000/login")
.post(requestBody)//因为项目要求是post请求,因此我们要遵循规则,post请,默认或者 .get 就是get请求
.build();
try {
Response response=client.newCall(request).execute();
String responseData=response.body().string();
Log.e( "run: TAG",responseData );
//解析 json
String code=new JSONObject(responseData).getString("code");
if (code.equals("200")){
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(Login.this,"登录成功",Toast.LENGTH_SHORT).show();
}
});
JSONObject dataJson=new JSONObject(responseData).getJSONObject("data");
SharedPreferences.Editor editor=getSharedPreferences("users",MODE_PRIVATE).edit();
//通过SharedPreferences 把服务器返回的数据进行存储,以便于后期使用
editor.putString("nickName",dataJson.getString("nickName"));
editor.putString("phone",dataJson.getString("phone"));
editor.putString("age",dataJson.getString("age"));
editor.putString("gender",dataJson.getString("gender"));
editor.putString("balance",dataJson.getString("balance"));
editor.commit();//提交
Intent intent=new Intent(Login.this, Index.class);
startActivity(intent);
}
} catch (IOException | JSONException e) {
e.printStackTrace();
}
}
}).start();
}
});
//注册点击事件
registerBut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent registerIntent = new Intent(Login.this, Register.class);
startActivity(registerIntent);
}
});
}
}
由于登录和注册思路一样,我在这直接上代码
注册 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.register.Register"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20dp"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="注册"
android:textColor="#000000"
android:textSize="40sp"></TextView>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:gravity="center"
android:text="欢迎来到注册页面"
android:textColor="#000000"
android:textSize="25dp"></TextView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="100dp"
android:padding="10dp"
>
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="昵称:"
android:textSize="20sp" />
<EditText
android:id="@+id/nickName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="8"
android:ems="10"
android:inputType="text" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="手机号:"
android:textSize="20sp" />
<EditText
android:id="@+id/rephone"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="8"
android:ems="10"
android:inputType="number" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:id="@+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="年龄:"
android:textSize="20sp"
/>
<EditText
android:id="@+id/age"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="8"
android:ems="10"
android:inputType="number" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="性别:"
android:textSize="20sp"
/>
<EditText
android:id="@+id/gender"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="8"
android:ems="10"
android:inputType="text" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="密码:"
android:textSize="20sp"
/>
<EditText
android:id="@+id/repassword"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="8"
android:ems="10"
android:inputType="textPassword" />
</LinearLayout>
<Button
android:id="@+id/register"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:background="@drawable/circular_moment"
android:text="立即注册"
android:textColor="#ffffff"
android:textSize="20dp" />
<TextView
android:id="@+id/text_fh"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="已有账号,返回登录"
android:textColor="#F44336"
android:textSize="20dp"></TextView>
</LinearLayout>
</LinearLayout>
完整主方法代码如下:
package com.fall.project.ui.register;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import com.fall.project.R;
import com.fall.project.ui.login.Login;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class Register extends AppCompatActivity {
private EditText nickName;//昵称
private EditText phone;//手机号
private EditText age;//年龄
private EditText gender;//性别
private EditText password;//密码
private Button registerBut;//立即注册
private TextView loginTtV;//返回登录
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.register);
//隐藏标题栏
ActionBar actionBar = getSupportActionBar();
actionBar.hide();
nickName = (EditText) findViewById(R.id.nickName);
phone = (EditText) findViewById(R.id.rephone);
age = (EditText) findViewById(R.id.age);
gender = (EditText) findViewById(R.id.gender);
password = (EditText) findViewById(R.id.repassword);
registerBut = (Button) findViewById(R.id.register);
loginTtV = (TextView) findViewById(R.id.text_fh);
//注册事件处理
registerBut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (nickName.getText().toString().equals("")) {
Toast.makeText(Register.this, "用户昵称不能为空", Toast.LENGTH_SHORT).show();
return;
}
if (phone.getText().toString().equals("")) {
Toast.makeText(Register.this, "用户手机号不能为空", Toast.LENGTH_SHORT).show();
return;
}
if (age.getText().toString().equals("")) {
Toast.makeText(Register.this, "用户年龄不能为空", Toast.LENGTH_SHORT).show();
return;
}
if (gender.getText().toString().equals("")) {
Toast.makeText(Register.this, "用户性别不能为空", Toast.LENGTH_SHORT).show();
return;
}
if (password.getText().toString().equals("")) {
Toast.makeText(Register.this, "用户密码不能为空", Toast.LENGTH_SHORT).show();
return;
}
//开启线程发起网络请求 ,并且请求仅限于子线程发起。
new Thread(new Runnable() {
@Override
public void run() {
MediaType JSON = MediaType.parse("application/json;charset=utf-8");
JSONObject json = new JSONObject();
try {
json.put("phone", phone.getText());
json.put("password", password.getText());
json.put("nickName", nickName.getText());
json.put("age", age.getText());
json.put("gender", gender.getText());
} catch (JSONException e) {
e.printStackTrace();
}
//拿到OkHttpClient对象
OkHttpClient client = new OkHttpClient();
//创建一个RequestBody(参数1:数据类型 参数2:传递的json串)
RequestBody requestBody = RequestBody.create(JSON, String.valueOf(json));
//3.构建request,将FormBody作为post方法的参数传入
Request request = new Request.Builder()
.url("http://150.158.117.228:8000/reg")
.post(requestBody)
.build();
try {
Response response = client.newCall(request).execute();
String responseData = response.body().string();
Log.e("run: TAG", responseData);
String code = new JSONObject(responseData).getString("code");
if (code.equals("200")) {
//runOnUiThread(new Runnable()从子线程跳入主线程
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(Register.this, "注册成功", Toast.LENGTH_SHORT).show();
}
});
Intent intent = new Intent(Register.this, Login.class);
startActivity(intent);
}
} catch (IOException | JSONException e) {
e.printStackTrace();
}
}
}).start();
}
});
//返回事件处理
loginTtV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent registerIntent = new Intent(Register.this, Login.class);
startActivity(registerIntent);
}
});
}
}
总结
登录,注册功能运用到的知识点,也就是 okhttp 发起网卡请求和响应,以及json的提交和取值, 通过SharedPreferences 把服务器返回的数据进行本地存取.