@Data
public class Result implements Serializable {
private Integer code; //编码:1成功,0和其它数字为失败
private String msg; //错误信息
private T data; //数据
public static Result success() {
Result result = new Result();
result.code = 1;
return result;
}
此项目中,由于有关查询需要返回data数据,这里建议在Controllor的返回类型加上泛型,而其他的业务不需要返回data只用返回code就行,所以也可以不加泛型。
当用户名重复时由于username已经添加了唯一约束,不能重复。
异常信息:SQLIntegrityConstraintViolationException:Duplicate entry 'zhangsan' for key 'employee.idx_username'
@ExceptionHandler
public Result exceptionHandler(SQLIntegrityConstraintViolationException ex){
//Duplicate entry 'zhangsan' for key 'employee.idx_username'
String message = ex.getMessage();
if(message.contains("Duplicate entry")){
String[] split = message.split(" ");
String username = split[2];
String msg = username + MessageConstant.ALREADY_EXISTS;
return Result.error(msg);
}else{
return Result.error(MessageConstant.UNKNOWN_ERROR);
}
}
解决方法:在全局异常处理中处理spil异常信息返回错误信息。
在员工登录成功后会生成JWT令牌并响应给前端,后续的请求中前端都会携带JWT令牌,我们可以通过解析JWT获取当前id。
那么解析出来的id怎么传送给service的save方法呢?
ThreadLocal 并不是一个Thread,而是Thread的局部变量。 ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。
所以在JWT校验成功后通过 setCurrentId(empId) 把id set到ThreadLocal,这时在实现类中getCurrentId()获取当前登录人。
方案一:
在属性上加上注解,对日期进行格式化,但这种方式,需要在每个时间属性上都要加上该注解,使用较麻烦,不能全局处理。
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
方案二:
在WebMvcConfiguration中扩展SpringMVC的消息转换器,统一对日期类型进行格式处理。
/**
* 扩展Spring MVC框架的消息转化器
* @param converters
*/
protected void extendMessageConverters(List> converters) {
log.info("扩展消息转换器...");
//创建一个消息转换器对象
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
//需要为消息转换器设置一个对象转换器,对象转换器可以将Java对象序列化为json数据
converter.setObjectMapper(new JacksonObjectMapper());
//将自己的消息转化器加入容器中
converters.add(0,converter);
}
如图我们在 parameterType 中本来要配置Employee的相对路径,但是我们在yml中对mybatis进行type-aliases-package的配置。指定entity扫描包类让mybatis自定扫描到自定义的entity。如下会扫描entity下的所有类。所以我们只需要写Employee即可
编辑员工信息没什么好说的,回显数据然后注意的是设计到回显密码这种敏感信息可以设置为***来隐藏信息。
@Override
public Employee getById(Long id) {
Employee employee = employeeMapper.getById(id);
employee.setPassword("****");
return employee;
}
编辑没什么注意的,记得在 ServiceImpl 类中使用 BeanUtils.copyProperties将DTO的数据拷贝到我们new出来的employee,并且设置当前修改时间和修改人(BaseContext.getCurrentId())在检验JWT时已经将 id 存入Thread的局部变量。我们的 BaseContext 只是封装了一下。
public class BaseContext {
public static ThreadLocal threadLocal = new ThreadLocal<>();
public static void setCurrentId(Long id) {
threadLocal.set(id);
}
public static Long getCurrentId() {
return threadLocal.get();
}
public static void removeCurrentId() {
threadLocal.remove();
}
}