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

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

之前的预备知识:

本次将带来前后端分离的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");
        }
    }

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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mind_programmonkey

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值