修改员工状态解析
- 在页面中, 通过Vue指令v-if进行判断,如果登录用户为admin将展示 启用/禁用 按钮, 否则
不展示
- statusHandle方法中进行二次确认, 然后发起ajax请求, 传递id、status参数(注意我们这里传的值,因为数据中是1所以我们需要改成0 所以就传了0,数据库直接修改即可)
后端代码
@PutMapping //因为前端发送的请求为put类型,所以我们这里用的 @PutMapping
public R<String> update(HttpServletRequest request,@RequestBody Employee employee){
log.info(employee.toString());
Long empId = (Long) request.getSession().getAttribute("employee");
employee.setUpdateUser(empId);
employee.setUpdateTime(LocalDateTime.now());
employeeService.updateById(employee);
return R.success("员工信息修改成功");
}
- 我们现在想要修改员工的状态,也就是数据库中指定id的status Mybatis-plus给我们封装了固有方法,这里直接使用即可(前端传过来的id和status都封装在了employee中)
employeeService.updateById(employee);
- 这里我们还需要设置更改时间UpdateTime与执行修改操作的人UpdateUser,像UpdateTime可以直接获取当前时间,而UpdateUser需要我们通过HttpServletRequest 中的getSeesion.getAttribute(“employee”)拿到,因为我们之前返回请求时已经把数据存储到浏览器中了。
update(HttpServletRequest request..){
Long empId = (Long) request.getSession().getAttribute("employee");
employee.setUpdateUser(empId);
}
- 我们存入浏览器中的数据如图所示
- 在执行完代码之后,我们发现测试过程并没有报错,数据库中的数据也没有变化,从控制台日志可以看出,并没有执行成功
最后发现日志中前端传来的指定ID与我们数据库中的ID并不相同,这是因为Long类型精准度只有16位,而这里ID我们有19位,所以致使后三位损失精度
解决Long类型损失精度问题
- 通过控制台sql发现页面传过来的员工id已经损失精度了
- 要想解决问题,很简单,我们只要将js处理的数据类型为字符串类型即可,这样就不会损失精度
代码修复
由于在SpringMVC中, 将Controller方法返回值转换为json对象, 是通过jackson来实现的, 涉
及到SpringMVC中的一个消息转换器MappingJackson2HttpMessageConverter, 所以我们要解决这个问题, 就需要对该消息转换器的功能进行拓展。
具体实现步骤:
1). 提供对象转换器JacksonObjectMapper,基于Jackson进行Java对象到json数据的转换。
2). 在WebMvcConfig配置类中扩展Spring mvc的消息转换器,在此消息转换器中使用提供的对象转换器进行Java对象到json数据的转换
- 该自定义的对象转换器, 主要指定了在进行json数据序列化及反序列化时, LocalDateTime、LocalDate、LocalTime的处理方式, 以及BigInteger及Long类型数据,直接转换为字符串。
/**
* 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
* 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
* 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
*/
public class JacksonObjectMapper extends ObjectMapper {
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
public JacksonObjectMapper() {
super();
//收到未知属性时不报异常
this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
//反序列化时,属性不存在的兼容处理
this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
SimpleModule simpleModule = new SimpleModule()
.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
.addSerializer(BigInteger.class, ToStringSerializer.instance)
.addSerializer(Long.class, ToStringSerializer.instance)
.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
//注册功能模块 例如,可以添加自定义序列化器和反序列化器
this.registerModule(simpleModule);
}
}
- 在提供了对象转换器JacksonObjectMapper后,我们还需要在WebMvcConfig中重写方法extendMessageConverters,代码如下:
/**
* 扩展MVC的消息转换器
* @param converters
*/
@Override
// 传进来的时候converters就已经自带几个转换器了
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
log.info("扩展消息转换器...");
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
messageConverter.setObjectMapper(new JacksonObjectMapper());
converters.add(0,messageConverter);
}
- 代码解析:
- 先创建转换器(因为 转换器有我们需要的方法:将java对象转换为json)
此转换器的作用:controller层中的返回结果R对象转换成相应的json,再通过输出流相应给我们页面
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
- 执行转换器自带的方法setObjectMapper,参数是我们引入的对象映射器文件
设置对象转换器,底层使用Jackson将java对象转换为json
messageConverter.setObjectMapper(new JacksonObjectMapper());
- 将上面的消息转换器对象追加到mvc框架的转换器集合中 这里把我们的转换器放到第一位 优先使用我们重写的转换器
converters.add(0,messageConverter);
-
其实大体的流程就是:
先创建转换器 因为 转换器有我们需要的方法-》将java对象转换为json new出来以后使用该方法转换 然后把转换器放在第一位,保证我们的转换器能够优先使用。 -
在DEBUG中我们可以看到传过来的时候就已经有内部的8个转换器了
-
在执行了代码之后,可以看到converters里已经有9个转换器,而且我们的转换器放到了第一位
-
最后我们测试一下,成功。数据库状态也正常修改了。
-
编辑员工信息我们可以复用之前代码,减少冗余,这里点击编辑按钮我们需要传id到后端,查询数据库信息再返回给页面。
-
在点击编辑按钮以后,可以看到出现了新的页面并且将相对应的数据带过来了,这里的数据就是我们从后端接受的
-
从控制台可以看出前端发送的请求
-
后端我们需要接受请求并根据id返回相对应得数据库的值
@GetMapping("/{id}")
public R<Employee> getById(@PathVariable Long id){
log.info("查询员工信息");
Employee employee = employeeService.getById(id);
if(employee!=null){
return R.success(employee);
}
return R.error("没查询到对应员工");
}
- 根据id查员工数据,因为前端发送过来的请求为 http://localhost:8080/employee/1560176825315962882 所以我们需要拿/{id}用来接收
- @PathVariable用来拿取id