复制java中的bean
通常和前台交互时传输的bean和数据库中直接映射的bean不一致,或者使用线程ThreadLocal改变某些值,但java对象又是地址引用时会用到bean的复制
直接给个简单的demo,这里只是用了我遇到的枚举类型的映射
数据库中的对应类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private String name;
private StudentType studentType;
}
StudentType的枚举类
public enum StudentType {
MAN(0,"男"),
WOMAN(1,"女");
private int code;
private String value;
StudentType(int code, String value) {
this.code = code;
this.value = value;
}
public int getCode() {
return code;
}
public String getValue() {
return value;
}
public static StudentType fromCode(int code){
for (StudentType value : StudentType.values()) {
if (value.getCode()==code){
return value;
}
}
return null;
};
@Override
public String toString() {
return "StudentType{" +
"value='" + value + '\'' +
'}';
}
}
要传输出去的类
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class StudentOutPut {
private String name;
private Integer studentType;
}
最后就是复制bean的代码块了,主要介绍转换器中三个参数
这里我写在了一个controller中触发复制,但并不是一定要在web项目中才能使用,引入了对应的包即可
@RequestMapping(value = "/helloWorld",produces="text/html;charset=UTF-8")
@ResponseBody
public String helloWorld(HttpServletRequest request){
Student student = new Student("测试用", StudentType.MAN);
Converter converter = new Converter() {
@Override
public Object convert(Object o, Class aClass, Object o1) {
try {
if (o instanceof Enum){
Method method = ((Enum) o).getDeclaringClass().getMethod("getCode");
Object invoke = method.invoke(o);
return invoke;
}
return o;
} catch (Exception e) {
throw new IllegalStateException("复制bean失败");
}
}
};
StudentOutPut studentOutPut = new StudentOutPut();
BeanCopier beanCopier = BeanCopier.create(Student.class,StudentOutPut.class, true);
beanCopier.copy(student,studentOutPut,converter);
request.getSession().setAttribute("user",studentOutPut);
System.out.println(studentOutPut);
页面请求后,打印结果
StudentOutPut(name=测试用, studentType=0)
成功将 Student中StudentType枚举类型映射成了 StudentOuput中的 studentType中的Integer类型,值就是对应枚举类的code值
提示:要复制的bean和目标bean对应的字段属性名一点更要一致,否则将不会走进传入的自定义 Converter对象
比如我这里Student中 private StudentType studentType;
和StudentOutPut中的private Integer studentType;
虽然属性类型不一样,但是属性名一定要保持一致