处理添加员工时,员工信息添加重复,使用异常处理来显示错误
出现Duplicate异常时,表示数据库的数据重复,并且数据库设置不能重复,则根据设置异常拦截,使运行时不报出异常。
@ControllerAdvice(annotations = {Controller.class, RestController.class})//意思是所以含有Controller、RestController注解的类都会被扫描进行异常处理
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {
/**
* 异常处理方法
* @param ex
* @return
*/
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)//注解用于处理异常,因为处理的是重复登录的异常,所以指定这个异常类
//一旦抛出这个类的异常则会被拦截处理
public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex) {
log.error(ex.getMessage());
if(ex.getMessage().contains("Duplicate entry")){
//如果异常的关键字为Duplicate entry,则弹出信息
String[] split = ex.getMessage().split(" ");
String msg=split[2] + "已存在";
return R.error(msg);
}
return R.error("未知错误");
}
}
代码的意思为当这个异常跳出时,返回R.error给前端,前端就会知道是什么错误
处理TooManyResultsException异常,表示使用selectone查询的到多条结果的异常。
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 2
String password = employee.getPassword();
password=DigestUtils.md5DigestAsHex(password.getBytes());
// 2、根据页面提交的用户名username查询数据库
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Employee::getPassword,password);//queryWrapper为查询包装对象,eq为equal的缩写,意思是查询条件为括号里面的的数据相等
Employee emp = employeeService.getOne(queryWrapper,false);//getone方法是只返回第一条记录,fasle是表示如果返回多条记录不弹出异常,并且选择第一个
您提供的是Spring框架中的一个登录方法的代码片段。这个方法使用`@PostMapping`注解来处理HTTP POST请求,并且期望接收一个`HttpServletRequest`对象和一个`Employee`对象作为参数。以下是对这段代码的分析和一些建议:
1. **密码加密**:代码首先对提交的密码进行MD5加密处理。这是常见的安全措施,但请注意,MD5算法已经不再被认为是安全的,因为它容易受到彩虹表攻击。建议使用更安全的加密算法,如SHA-256。
2. **查询数据库**:使用MyBatis Plus的`LambdaQueryWrapper`来构建查询条件,查询数据库中密码与加密后的密码匹配的员工记录。`employeeService.getOne(queryWrapper)`调用期望返回匹配的第一条记录。
3. **登录失败处理**:如果查询结果为空(即没有找到匹配的员工记录),则返回一个错误响应。
4. **密码比对**:即使查询到了员工记录,代码还会再次进行密码比对,如果密码不匹配,同样返回错误响应。
5. **员工状态检查**:如果员工的状态为0(可能表示已禁用),则返回账号已禁用的错误响应。
6. **登录成功处理**:如果所有检查都通过,代码将员工的ID存入HTTP会话(Session)中,并将员工对象作为成功响应返回。
针对您之前的日志错误,这里的`employeeService.getOne(queryWrapper)`调用可能是导致`TooManyResultsException`的原因。如果查询条件设置不当,可能会返回多条记录,而`getOne()`方法期望只返回一条记录。
**解决方法**:
- 确保查询条件足够精确,以避免返回多条记录。例如,您可以同时检查用户名和密码:
queryWrapper.eq(Employee::getUsername, employee.getUsername()).eq(Employee::getPassword, password);
- 如果您的业务逻辑允许存在多个员工具有相同的密码,但不希望`getOne()`抛出异常,您可以使用`getOne(queryWrapper, false)`,其中第二个参数`false`表示如果找到多个结果也不抛出异常,而是返回找到的第一个结果。
- 检查数据库中是否存在数据问题,确保每个员工的密码是唯一的。
- 如果您希望在登录时返回所有匹配的员工记录,可以使用`List<Employee> empList = employeeService.list(queryWrapper);`,然后根据需要处理这个列表。
最后,请确保您的`Employee`实体类和MyBatis的映射配置正确无误,以避免不必要的问题。