目录
一、完善登录功能
1、问题分析:
用户此时如果直接访问主页地址也是可以访问的,所以应该做到登录后才能访问,而直接访问主页使其跳转到登录页面
2、解决方案:
使用过滤器或者拦截器,判断用户是否已经完成登录,如果未完成则跳转到登录页面
3、代码实现:
处理逻辑
第五步时候查看前端代码并分析
package com.itheima.reggie.filter;
import com.alibaba.fastjson.JSON;
import com.itheima.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;
/**
* 检查用户是否完成登录
*/
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
//路径匹配器,支持通配符
//在当前的作用域中创建了一个名为PATH_MATCHER的常量,并将其赋值为AntPathMatcher类的一个新实例。
//是Spring框架中的一个工具类,用于匹配和操作Ant样式的路径模式。它可以用于实现路径匹配、路径变量提取等功能
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("拦截到请求:{}",requestURI);
//定义不需要处理的路径
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"front/**"
};
//2、判断本次请求是否需要处理
boolean check = check(urls, requestURI);
//3、如果不需要处理,则直接放行
if(check){
log.info("本次请求{}不需要处理",requestURI);
// 放行
filterChain.doFilter(request,response);
return;
}
//4、判断登录状态,如果已登录,则直接放行
if(request.getSession().getAttribute("employee")!=null){
log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("employee"));
// 放行
filterChain.doFilter(request,response);
return;
}
log.info("用户未登录");
// 5、如果未登录则返回登录结果(分析前端代码)通过输出流方式向客户端响应数据
// response.getWriter()返回的是一个字符输出流(PrintWriter),
// 通过调用其write()方法可以将字符串写入到HTTP响应的输出流中。
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
return;
}
/**
* 路径匹配,检查本次请求是否需要放行
* @param urls
* @param requestURI
* @return
*/
public boolean check(String[]urls,String requestURI){
for (String url:urls){
boolean match = PATH_MATCHER.match(url,requestURI);
if (match){
return true;
}
}
return false;
}
}
4、进行测试 :
1、这个时候未登录直接访问主页会跳转到登录页面
2、登录退出页面放行
3、添加断点测试前端页面
此时清一下浏览器缓存,不登录访问主界面
5、不熟练的技术点:
1、
是Spring框架中的一个工具类,用于匹配和操作Ant样式的路径模式。它可以用于实现路径匹配、路径变量提取等功能
public static final AntPathMatcher PATH_MATCHER =new AntPathMatcher();
2、response.getWriter()
返回一个PrintWriter
对象,通过该对象可以向客户端发送内容。JSON.toJSONString(R.error("NOTLOGIN"))
这里使用了JSON工具库,将一个表示错误消息的R
对象转换成JSON字符串。
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
二、新增员工
1、问题分析
1.1、分析员工前端页面
找到单机事件,crtl+b找到方法
通过引用index的方法完成页面的跳转
1.2、分析请求信息
1.3、分析数据库等信息
2、代码实现
/**
* 新增员工信息
* @param employee
* @return
*/
@PostMapping
public R<String> save(HttpServletRequest request,@RequestBody Employee employee){
log.info("新增员工,员工信息:{}",employee.toString());
employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());
// 获取当前用户id
Long empId = (Long) request.getSession().getAttribute("employee");
employee.setCreateUser(empId);
employee.setUpdateUser(empId);
employeeService.save(employee);
return R.success("新增员工成功");
}
}
3、测试
功能已实现
4、异常处理
由于账号设置了唯一索引,这个时候账号相同是要抛出异常
4.1 处理方式
这里选择第二种处理方案,因为第一种如果后续还有异常处理还需要写多个捕获,并不简洁
4.2代码编写
/**
* 注解参数 annotations 指定了需要处理的控制器的类型。
* annotations = {} 表示该全局异常处理类将会处理使用了
* {}内注解的控制器类。
*/
@RestControllerAdvice(annotations = {RestController.class, Controller.class})
@Slf4j
public class GlobalExceptionHandler {
/**
* 异常处理方法
*
*/
//ExceptionHandler()当遇到()内里面的异常时执行下面方法
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)
public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
log.info(ex.getMessage());
return R.error("失败了‘");
}
}
4.3测试
测试成功
4.4完善异常处理
当触发异常后控制台提示信息
4.5完善代码
/**
* 注解参数 annotations 指定了需要处理的控制器的类型。
* annotations = {} 表示该全局异常处理类将会处理使用了
* {}内注解的控制器类。
*/
@RestControllerAdvice(annotations = {RestController.class, Controller.class})
@Slf4j
public class GlobalExceptionHandler {
/**
* 异常处理方法
*
*/
//ExceptionHandler()当遇到()内里面的异常时执行下面方法
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)
public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
//getMessage()获取详细信息
log.info(ex.getMessage());
//如果异常信息中包含Duplicate entry
if (ex.getMessage().contains("Duplicate entry")){
String[] split = ex.getMessage().split(" ");
String msg = split[2] +"已经存在";
return R.error(msg);
}
return R.error("未知错误");
}
}
三、员工信息分页查询
1、问题分析
2、代码实现
创建mybatis-plus的分页拦截器
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
实现分页逻辑功能
/**
* 分页
* @param page
* @param pageSize
* @param name
* @return
*/
public R<Page> page(int page,int pageSize,String name){
log.info("page={},pageSize={},name={}",page,pageSize,name);
//构造分页构造器
Page pageInfo = new Page(page, pageSize);
//构造条件构造器
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper();
//添加过滤条件
// StringUtils.isNotEmpty(name)判断那么是否为空,如果为空则不执行查询语句,如果不为空则执行查询语句
queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);
//添加排序条件
queryWrapper.orderByDesc(Employee::getUpdateTime);
//mybatis-plus自带的分页
employeeService.page(pageInfo,queryWrapper);
return R.success(pageInfo);
}
3、测试
断点调试
测试功能实现
4、不熟悉的技术点:
1、StringUtils.isNotEmpty(name)判断那么是否为空,如果为空则不执行查询语句,如果不为空则执行查询语句
四、启用/禁用员工账号
1、问题分析
发送的是put请求,并且传进来的是json数据
2、代码实现
/**
* 修改员工信息
* @param request
* @param employee
* @return
*/
@PostMapping
public R<String> update(HttpServletRequest request,@RequestBody Employee employee){
log.info(employee.toString());
Long empId = (Long) request.getSession().getAttribute("employee");
employee.setUpdateTime(LocalDateTime.now());
employee.setUpdateUser(empId);
employeeService.updateById(employee);
return R.success("员工信息修改成功");
}
3、测试
调试发现并未修改成功
3.1寻找原因:
发现id并不相同
查询发现id在js处理长整型的时候丢失精度,导致提交id和数据库id不一致
3.2处理思路
将long型数据统一转为String字符串
/**
* 扩展mvc框架的消息转换器
* @param converters
*/
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
// 创建消息转换器对象
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
// 设置对象转换器
messageConverter.setObjectMapper(new JacksonObjectMapper());
// 将上面的消息转换器对象追加到mvc框架的转换器集合中
converters.add(0,messageConverter);
}
3.3重新测试
测试成功,功能正常执行
五、编辑员工信息
1、问题分析
发现他会弹出一个add页面,在前端代码中分析一下
请求方式:get请求 employee/id
数据格式:json数据
2、代码实现
/**
* 根据id查询员工信息
* @param id
* @return
*/
@GetMapping("/{id}")
public R<Employee> getById(@PathVariable Long id){
log.info("根据id查员工信息");
Employee employee = employeeService.getById(id);
if (employee!=null){
return R.success(employee);
}
return R.error("没有查询到对应的员工信息");
}
保存后调用update方法实现修改更新
3、测试
功能成功执行