【瑞吉外卖】-day03
目录
前言
启动禁用员工账号
消息转换器
1. Jackson (用于JSON)
2. JAXB (用于XML)
3. Gson (用于JSON)
4. MessagePack (用于二进制格式)
页面展示
代码部分
启动禁用员工账号修改(个人意见)
公共字段自动填充
ThreadLocal简要概述
基本用法
创建 ThreadLocal 实例:
设置值:
示例代码
注意事项
前言
由于昨天的员工禁用功能没有来得及实现,今天在这里重新进行实现。但是遇到了点小问题,就是前端的页面展示效果一直无法实现,状态也没有进行更新,反复观看了好多遍都没有找到问题所在。希望能够得到大佬们的指点。
启动禁用员工账号
由于格式的问题,在这里要引入一个新概念,消息转换器。
消息转换器
在Java中,消息转换器(Message Converter)通常用于将数据从一种格式转换为另一种格式。这种转换在许多场景中都非常有用,例如:
- Web服务和REST API:在处理HTTP请求和响应时,经常需要将JSON、XML等格式的数据转换为Java对象,或将Java对象转换为这些格式的数据。
- 消息队列:在使用消息队列(如RabbitMQ、Kafka等)时,消息通常以字节数组的形式传输,因此需要将消息内容转换为特定的格式。
- 序列化和反序列化:在分布式系统中,不同节点之间可能需要传递复杂的对象,这时就需要进行序列化和反序列化操作。
以下是一些常见的Java消息转换器及其使用示例:
1. Jackson (用于JSON)
Jackson是一个流行的JSON处理库,可以方便地将Java对象与JSON数据相互转换。
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonExample {
public static void main(String[] args) throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
// Java对象转JSON字符串
MyObject obj = new MyObject("John", 30);
String jsonString = objectMapper.writeValueAsString(obj);
System.out.println("JSON String: " + jsonString);
// JSON字符串转Java对象
MyObject objFromJson = objectMapper.readValue(jsonString, MyObject.class);
System.out.println("Java Object: " + objFromJson);
}
}
class MyObject {
private String name;
private int age;
// Constructors, getters and setters omitted for brevity
}
2. JAXB (用于XML)
JAXB(Java Architecture for XML Binding)是Java自带的一个框架,用于将Java对象与XML数据相互转换。
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;
public class JAXBExample {
public static void main(String[] args) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(MyObject.class);
// Java对象转XML字符串
MyObject obj = new MyObject("John", 30);
Marshaller marshaller = context.createMarshaller();
StringWriter writer = new StringWriter();
marshaller.marshal(obj, writer);
String xmlString = writer.toString();
System.out.println("XML String: " + xmlString);
// XML字符串转Java对象
Unmarshaller unmarshaller = context.createUnmarshaller();
MyObject objFromXml = (MyObject) unmarshaller.unmarshal(new StringReader(xmlString));
System.out.println("Java Object: " + objFromXml);
}
}
@XmlRootElement
class MyObject {
private String name;
private int age;
// Constructors, getters and setters omitted for brevity
}
3. Gson (用于JSON)
Gson是Google提供的一个用于处理JSON的库,它比Jackson更轻量级。
import com.google.gson.Gson;
public class GsonExample {
public static void main(String[] args) {
Gson gson = new Gson();
// Java对象转JSON字符串
MyObject obj = new MyObject("John", 30);
String jsonString = gson.toJson(obj);
System.out.println("JSON String: " + jsonString);
// JSON字符串转Java对象
MyObject objFromJson = gson.fromJson(jsonString, MyObject.class);
System.out.println("Java Object: " + objFromJson);
}
}
class MyObject {
private String name;
private int age;
// Constructors, getters and setters omitted for brevity
}
4. MessagePack (用于二进制格式)
MessagePack是一种高效的二进制序列化格式,适用于需要高性能的场景。
import org.msgpack.MessagePack;
import java.io.IOException;
public class MessagePackExample {
public static void main(String[] args) throws IOException {
MessagePack msgpack = new MessagePack();
// Java对象转MessagePack字节数组
MyObject obj = new MyObject("John", 30);
byte[] bytes = msgpack.write(obj);
System.out.println("MessagePack Bytes: " + bytes);
// MessagePack字节数组转Java对象
MyObject objFromBytes = msgpack.read(bytes, MyObject.class);
System.out.println("Java Object: " + objFromBytes);
}
}
class MyObject {
private String name;
private int age;
// Constructors, getters and setters omitted for brevity
}
页面展示
这里出了点小问题,就是这个账号状态老是显示不成功,求解!!!
代码部分
// 启用禁用员工账号
@PutMapping
public R<String> update(HttpServletRequest request,@RequestBody Employee employee){
// 获取当前登录用户的id
Long empId = (Long) request.getSession().getAttribute("employee");
// 设置更新时间和更新者
employee.setUpdateTime(LocalDateTime.now());
employee.setUpdateUser(empId);
// 更新员工信息
employeeService.updateById(employee);
// 返回成功提示信息
return R.success("员工信息修改成功");
}
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
import com.von.ruiji_take_out.common.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.cbor.MappingJackson2CborHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
@Slf4j
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
/**
* 重写扩展消息转换器的方法
*
* @param converters Spring Boot自动配置的消息转换器列表
*
* 此方法的目的是向Spring Boot的HTTP消息转换器列表中添加一个自定义的消息转换器
* 通过这种方式,我们可以定制HTTP请求和响应的序列化和反序列化行为
*
* @see <a href="https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#web.servlet.spring-message-converters">Spring Boot Documentation</a>
*/
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
// 创建一个CBOR格式的消息转换器
MappingJackson2CborHttpMessageConverter messageConverter = new MappingJackson2CborHttpMessageConverter();
// 设置自定义的ObjectMapper,用于提高序列化和反序列化的灵活性和性能
messageConverter.setObjectMapper(new JacksonObjectMapper());
// 将自定义的消息转换器添加到列表的最前面,确保它优先被使用
converters.add(0, messageConverter);
}
}
启动禁用员工账号修改(个人意见)
由于没有找到问题所在,索性直接修改id的值了。简单除暴但是十分可行,只不过每次添加员工的时候都需要手动修改,这点有点麻烦。
公共字段自动填充
ThreadLocal简要概述
ThreadLocal
是 Java 中提供的一种机制,用于在多线程环境中为每个线程提供独立的变量副本。它的主要目的是解决多线程环境下的共享数据问题,避免线程间的数据干扰。
基本用法
-
创建
ThreadLocal
实例:ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
-
设置值:
threadLocal.set(100);
-
获取值:
Integer value = threadLocal.get();
-
移除值:
threadLocal.remove();
示例代码
以下是一个简单的示例,展示了如何在多线程环境中使用 ThreadLocal
:
public class ThreadLocalExample {
private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
public static void main(String[] args) {
Runnable task = () -> {
// 设置初始值
threadLocal.set((int) (Math.random() * 100));
try {
// 模拟一些工作
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 获取并打印当前线程的值
System.out.println(Thread.currentThread().getName() + ": " + threadLocal.get());
};
Thread thread1 = new Thread(task, "Thread-1");
Thread thread2 = new Thread(task, "Thread-2");
thread1.start();
thread2.start();
}
}
在这个示例中,两个线程分别设置了不同的随机值,并在稍后获取并打印出来。由于 ThreadLocal
确保了每个线程都有自己独立的变量副本,因此两个线程不会互相干扰。
注意事项
-
内存泄漏:在使用
ThreadLocal
时,如果不及时调用remove()
方法,可能会导致内存泄漏。特别是在使用线程池的情况下,因为线程会被重用,如果不清理ThreadLocal
变量,这些变量会一直存在,导致内存无法被回收。 -
初始化值:可以通过重写
initialValue()
方法来提供默认值:private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>() { @Override protected Integer initialValue() { return 0; // 默认值 } };
-
适用场景:
ThreadLocal
适用于需要在多个线程之间隔离数据的场景,例如数据库连接、用户会话等。
通过合理使用 ThreadLocal
,可以有效地解决多线程编程中的共享数据问题,提高程序的安全性和可维护性。