功能开发-登录注销
一、后台登录功能开发
1.1、需求分析
1.2、代码开发
1.2.1、创建实体类Employee与employee映射
package com.xxxit.reggie.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 员工实体类
* Serializable接口中一个成员函数或者成员变量也没有。那么这个接口的作用是什么呢。网上找了一些博客看过之后,知道这个接口的作用是实现序列化
* Java 序列化技术可以使你将一个对象的状态写入一个Byte 流里(系列化),并且可以从其它地方把该Byte 流里的数据读出来(反序列化)。
*/
@Data
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String username;
private String name;
private String password;
private String phone;
private String sex;
private String idNumber;//身份证号码
private Integer status; //1是启用,0是禁用
private LocalDateTime createTime;
private LocalDateTime updateTime;
@TableField(fill = FieldFill.INSERT)
private Long createUser;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
}
1.2.2、mybatis-plus
Day1-项目简介(3.2.3)MyBatis-plus配置
1.2.3、结果集R编写
package com.xxxit.reggie.common;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Data
public class R<T>{
private Integer code; // 编码 1是成功,其他数字是失败
private String msg; // 错误信息
private T data; // 数据
private Map map = new HashMap(); //动态数据
public static <T> R<T> success(T object) {
R<T> r = new R<T>();
r.data = object;
r.code = 1;
return r;
}
public static <T> R<T> error(String msg) {
R r = new R();
r.msg = msg;
r.code = 0;
return r;
}
public R<T> add(String key,Object value) {
this.map.put(key,value);
return this;
}
}
1.2.4、Mapper,Service,Controller编写
Mapper
package com.xxxit.reggie.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xxxit.reggie.entity.Employee;
import org.apache.ibatis.annotations.Mapper;
@Mapper //声明mapper代理开发
public interface EmployeeMapper extends BaseMapper<Employee> { //继承BaseMapper快速开发Dao层
}
Service接口
package com.xxxit.reggie.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xxxit.reggie.entity.Employee;
public interface EmployeeService extends IService<Employee> { //继承IService快速开发业务层,但是一般不用业务层都是自己写
}
Service实现类
package com.xxxit.reggie.service.Impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxxit.reggie.entity.Employee;
import com.xxxit.reggie.mapper.EmployeeMapper;
import com.xxxit.reggie.service.EmployeeService;
import org.springframework.stereotype.Service;
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {
}
Controller
package com.xxxit.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xxxit.reggie.common.R;
import com.xxxit.reggie.entity.Employee;
import com.xxxit.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired //自动装载
private EmployeeService employeeService;
/**
* 员工登录
* @param request
* @param employee
* @return
*/
@PostMapping("/login")
public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){
// 1.将页面提供password使用md5加密
String pwd = employee.getPassword();
pwd = DigestUtils.md5DigestAsHex(pwd.getBytes());
// 2.查询用户名是否存在数据库
// 相当于写了一个sql语句
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Employee::getUsername,employee.getUsername());
//查询
Employee e = employeeService.getOne(queryWrapper);
// 3.没有查询到,返回登录失败
if (e == null) {
return R.error("用户名不存在或密码错误,登录失败~");
}
// 4.密码错误,返回登录失败
if (!e.getPassword().equals(pwd)){
return R.error("用户名不存在或密码错误,登录失败~");
}
// 5.账号被停用
if (e.getStatus() != 1){
return R.error("账号已被停止使用");
}
// 6.登录成功,先存到Session
HttpSession session = request.getSession();
session.setAttribute("employee",e.getId());
return R.success(e);
}
}
1.2.5、测试
自行测试
二、后台注销功能开发
2.1、需求分析
2.2、controller编写
package com.xxxit.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xxxit.reggie.common.R;
import com.xxxit.reggie.entity.Employee;
import com.xxxit.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired //自动装载
private EmployeeService employeeService;
/**
* 员工登录
* @param request
* @param employee
* @return
*/
@PostMapping("/login")
public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){
// 1.将页面提供password使用md5加密
String pwd = employee.getPassword();
pwd = DigestUtils.md5DigestAsHex(pwd.getBytes());
// 2.查询用户名是否存在数据库
// 相当于写了一个sql语句
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Employee::getUsername,employee.getUsername());
//查询
Employee e = employeeService.getOne(queryWrapper);
// 3.没有查询到,返回登录失败
if (e == null) {
return R.error("用户名不存在或密码错误,登录失败~");
}
// 4.密码错误,返回登录失败
if (!e.getPassword().equals(pwd)){
return R.error("用户名不存在或密码错误,登录失败~");
}
// 5.账号被停用
if (e.getStatus() != 1){
return R.error("账号已被停止使用");
}
// 6.登录成功,先存到Session
HttpSession session = request.getSession();
session.setAttribute("employee",e.getId());
return R.success(e);
}
/**
* 员工注销
* @param request
* @return
*/
@PostMapping("/logout")
public R<String> logout(HttpServletRequest request){
//清理Session中保存的当前登录员工的id
HttpSession session = request.getSession();
session.removeAttribute("employee");
return R.success("退出成功");
}
}
2.3、测试
自行测试
三、完善登录功能
3.1、需求分析
3.2、代码实现
LoginCheckFilter
package com.xxxit.reggie.filter;
import com.alibaba.fastjson.JSON;
import com.xxxit.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 未登录过滤器
*/
@Slf4j
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
// 路劲匹配器,支持通配符,因为我们的String数组里面有通配符
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 1.获取本次请求的URI
String requestURI = request.getRequestURI();
log.info("获取本次请求的URI {}",requestURI);
// 2.判断本次请求是否需要处理
String[] uris = new String[]{"/employee/login","/employee/logout","/backend/**","/front/**"};
// 3.不需要处理直接放行
boolean b = checkURI(uris, requestURI);
if (b){
filterChain.doFilter(request,response);
return;
}
// 4、已经登录直接放行
if(request.getSession().getAttribute("employee") != null){
filterChain.doFilter(request,response);
return;
}
// 6.未登录跳转
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
return;
}
/**
* 检测URI是否不用过滤
* @param uris
* @param requestURI
* @return
*/
public boolean checkURI(String[] uris, String requestURI){
for (String s : uris) {
boolean match = PATH_MATCHER.match(s,requestURI);
if (match){
return true;
}
}
return false;
}
}
ReggieApplication
package com.xxxit.reggie;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@Slf4j
@SpringBootApplication
@ServletComponentScan
public class ReggieApplication {
public static void main(String[] args) {
SpringApplication.run(ReggieApplication.class, args);
log.info("项目启动成功");
}
}
注意:项目文件分布