• 周六. 10 月 5th, 2024

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

【开发篇】10分钟快速上手spring boot+react登录前后端分离

King Wang

1 月 3, 2022

【开发篇】10分钟快速上手spring boot+react登录前后端分离

之前的预备知识:

  • 10分钟快速上手git与github
  • 10分钟快速上手springboot
  • 10分钟快速springboot+react前后端分离
  • 10分钟快速上手springboot+mybatis增删改查

本次将带来前后端分离的spring boot+react的登录demo。

接下来,让我们在学习的海洋中畅游吧!!!

一、前后端分离

1.1 前后端分离

在前后端不分离的应用模式中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控制前端的显示,前端与后端耦合度很高。

1.2 前后端分离

在前后端分离的应用模式中,后端仅返回前端所需的数据,不再渲染HTML页面,不再控制前端的效果。至于前端用户看到的效果,从后端请求的数据如何加载到前后端中,都有前端自己决定,网页有网页的处理方法,但无论哪种前端,所需的数据基本相同,后端仅需开发一套逻辑对外提供数据即可。

二、后端设计

2.1 数据库表设计

2.2 技术

  • spring boot
  • mybatis

2.3 项目结构

1.entity

package com.lcz.login.entity;
/**
* @author : codingchao
* @date : 2020-08-16 14:02
* @Description:
**/
public class User {
private int id;
private String username;
private String password;
public User(String username, String password) {
this.username = username;
this.password = password;
}
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;
}
}
package com.lcz.login.entity;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* @author : codingchao
* @date : 2020-08-16 14:15
* @Description:
**/
public class Result<T> {
// 错误码
private Integer code;
// 提示信息
private String msg;
// 具体内容
private T data;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}

2.mapper

package com.lcz.login.mapper;
/**
* @author : codingchao
* @date : 2020-08-16 14:04
* @Description:
**/
import com.lcz.login.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
@Mapper
public interface UserMapper {
// 通过账户名来查询密码
User findUserByName(String username);
}

3.service

package com.lcz.login.service;
import com.lcz.login.entity.User;
import com.lcz.login.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author : codingchao
* @date : 2020-08-16 14:07
* @Description:
**/
public interface UserSerice {
public User findUserByName(String name);
}

4.service/impl

package com.lcz.login.service.impl;
import com.lcz.login.entity.Result;
import com.lcz.login.entity.User;
import com.lcz.login.mapper.UserMapper;
import com.lcz.login.service.UserSerice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author : codingchao
* @date : 2020-08-16 14:09
* @Description:
**/
@Service
public class UserServiceImpl implements UserSerice {
@Autowired
private UserMapper userMapper;
@Override
public User findUserByName(String name) {
User user = userMapper.findUserByName(name);
return user;
}
}

5.controller

package com.lcz.login.controller;
import com.lcz.login.entity.Result;
import com.lcz.login.entity.User;
import com.lcz.login.service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author : codingchao
* @date : 2020-08-16 14:10
* @Description:
**/
@RestController
@RequestMapping(value="/crud",method = {RequestMethod.GET,RequestMethod.POST})
public class UserController {
@Autowired
private UserServiceImpl userService;
@PostMapping("/listUserByName")
public Result<User> findUserByName(@RequestParam("username")String username,
@RequestParam("password")String password){
User user = userService.findUserByName(username);
Result result = new Result();
if (user.getPassword().equals(password)){
result.setCode(0);
result.setMsg("成功");
result.setData(user);
}else{
result.setCode(-1);
result.setMsg("失败");
result.setData("");
}
return result;
}
}

6.resource/mapper/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.lcz.login.mapper.UserMapper">
<resultMap id="result" type="com.lcz.login.entity.User">
<result property="username" column="username"/>
<result property="password" column="password"/>
</resultMap>
<select id="findUserByName" resultMap="result">
SELECT * FROM user where username=#{username}
</select>
</mapper>

其余的配置,可参考[开发篇]10分钟快速上手spring
boot+mybatis增删改查

三、前端设计

前端在一个bootstrap开源框架上进行操作的。

3.1 技术

  • React
  • Bootstrap
  • font-awesome

3.2 功能实现

登录界面输入账号密码->发送请求到后端进行验证->验证成功进入主页->选择退出账号->回到登录页面

3.3 重要技术

1.跨域请求

  • 前端的端口在localhost:3000
  • 后端的端口在localhost:8081

属于跨域请求,本次在前端通过http-proxy-middleware模块来实现跨域请求

在src下新建setupProxy.js

// 跨域请求
const {createProxyMiddleware} = require('http-proxy-middleware');
module.exports = function (app) {
app.use(createProxyMiddleware('/listUserByName', {target: 'http://localhost:8081/crud/', changeOrigin: true}))
}

2.LocalStoage存取

//localstorage读取
setStorage(name,data){
let dataType = typeof data;
// json
if(dataType === 'object'){
window.localStorage.setItem(name,JSON.stringify(data));
}else if( ['number','string','boolean'].indexOf(dataType) >=0 ){
window.localStorage.setItem(name,data);
}else{
alert("该类型不能用于本地存储");
}
}
getStorage(name){
let data = window.localStorage.getItem(name);
if(data){
return JSON.parse(data);
}else{
return '';
}
}
removeStorage(name){
window.localStorage.removeItem(name);
}

3.登录

  • 表单验证在前端,看账号和密码是否为空以及是否满足要求
  • 回车提交表单请求
  • 登录成功之后将用户存入localstorage
  • 主页界面读取localstorage的信息并显示用户名
request(param) {
return new Promise((resolve, reject) => {
$.ajax({
type: param.type || 'get',
url: param.url || '',
dataType: param.dataType || 'json',
data: param.data || null,
success: res => {
resolve(res);
},
error: err => {
resolve(err);
}
})
})
}
 onSubmit = () => {
let loginInfo = {
username: this.state.username,
password: this.state.password,
redirect : '/'
};
// 表单验证
let checkResult = _mm.checkLoginInfo(loginInfo);
// console.log(checkResult);
if (checkResult.status) {
_mm.request({
type : 'post',
url: '/listUserByName',
data:{
username: this.state.username,
password: this.state.password
}
}).then((res) => {
if(res.code==-1){
_mm.errorTips("账号密码错误");
}else if(res.code==0){
_mm.setStorage('userInfo',res);
this.props.history.push(this.state.redirect);
}
}, (errMsg) => {
console.log(errMsg);
})
} else {
_mm.errorTips(checkResult.msg);
}
}

4.退出

  • 点击退出,删除localstorage中的信息
  • 游览器获得不到localstorage信息,则进入登录界面
// 这是退出登录
onLogout = () => {
_mm.removeStorage('userInfo');
window.location.href = ("/login");
}
// 验证是否有登录信息
componentWillMount(){
if(_mm.getStorage("userInfo") == ''){
window.location.href = ("/login");
}
}

好了,本次学习的旅程,到此结束!!!

发表回复