Vorwort
Kürzlich erforderte das Projekt ein Upgrade einer Toolkit- hutool
Version, um das Problem der Sicherheitslücken zu lösen. Es ist in Ordnung, kein Upgrade durchzuführen, aber ein Upgrade verursacht ein größeres Durcheinander. Was ist los?
Veranstaltungsrückblick
Die ursprüngliche Version, die von unserem Projekt verwendet wird, hutool
ist 5.7.2.Im Code werden unser Datenübertragungsobjekt DTO und das Datenentitätsobjekt im Toolkit häufig verwendet.Der BeanUtil.copyProperties()
allgemeine Code lautet wie folgt:
- Datenübertragungsobjekt
@Data
@ToString
public class DiagramDTO {
// 前端生产的字符串id
private String id;
private String code;
private String name;
}
复制代码
- Datenentitätsobjekt
@Data
@ToString
public class Diagram {
private Integer id;
private String code;
private String name;
}
复制代码
- Geschäftslogik
public class BeanCopyTest {
public static void main(String[] args) {
// 前端传输的对象
DiagramDTO diagramDTO = new DiagramDTO();
// 如果前端传入的id事包含e的,升级后就会报错
diagramDTO.setId("3em3dgqsgmn0");
diagramDTO.setCode("d1");
diagramDTO.setName("图表");
Diagram diagram = new Diagram();
// 关键点,数据拷贝
BeanUtil.copyProperties(diagramDTO, diagram);
System.out.println("数据实体对象:" + diagram);
//设置id为空,自增
diagram.setId(null);
//保存到数据库中 TODO
//diagramMapper.save(diagram);
}
}
复制代码
Vor dem Upgrade hutool
war es Version 5.7.2, und das Ausführungsergebnis ist wie in der folgenden Abbildung dargestellt.
BeanUtil.copyProperties
Obwohl die Feldtypen unterschiedlich sind, wurde eine Kompatibilitätsverarbeitung durchgeführt, sodass das Geschäft die Geschäftslogik nicht beeinflusst.
Nach dem Upgrade hutool
ist es Version 5.8.8 und das Ausführungsergebnis ist in der folgenden Abbildung dargestellt:
- Führen Sie einen Fehlerbericht aus, da die aktualisierte Version die Implementierung geändert und die folgende Logik hinzugefügt hat. Wenn E enthalten ist, wird ein Fehler ausgegeben, der die Geschäftslogik beeinflusst. Gleichzeitig ist es ein Zufallsfaktor, ob die ID e enthält Es wird bis zur Produktion nicht gefunden, so eine Tragödie.
Analyse und Diskussion
Ich habe festgestellt, dass die meisten Leute beim Schreiben von Code gerne faul sind. In dem obigen Szenario sind BeanUtil.copyProperties
die Folgen, obwohl es eine Weile verwendet wird, manchmal sehr schwerwiegend, sodass diese Methode nicht empfohlen wird. Warum sagst du das?
Beispielsweise haben einige Personen im Team heimlich das DTO des Datenübertragungsobjekts geändert, z. B. den Typ geändert oder ein bestimmtes Feld gelöscht. Die angewandte Methode BeanUtil.copyProperties
lässt sich bei der Erstellung überhaupt nicht feststellen, geschweige denn der Einflussbereich der Modifikation, der nur das Produktionsrisiko aufdecken kann. Also, was ist besser?
Empfohlener Plan
- ursprünglicher
get
Wegset
_
Ich plädiere eher für diese Vorgehensweise: Wenn Sie beispielsweise DiagramDTO
jetzt ein bestimmtes Feld löschen, meldet der Compiler einen Fehler, der Ihre Aufmerksamkeit auf sich ziehen wird, sodass das Problem im Voraus aufgedeckt wird und sich niemand verstecken kann.
Du denkst vielleicht, dass Aufstehen und Reden deinem Rücken nicht weh tut, und es besser ist, weniger Felder zu haben. Wenn es viele Felder gibt, darfst du sie nicht zu Tode schreiben. Ich empfehle hier ein IDEA-Plugin, das dir helfen kann solche Codes intelligent generieren.
Nicht viel zu sagen, geh alleine spielen~~
- Verwenden Sie Open-Source-Bibliotheken
ModelMapper
ModelMapper
是一个开源库,可以很方便、简单地将对象从一种类型映射到另一种类型,底层是通过反射来自动确定对象之间的映射,还可以自定义映射规则。
private static void testModelMapper() {
ModelMapper modelMapper = new ModelMapper();
DiagramDTO diagramDTO = new DiagramDTO();
diagramDTO.setId("3em3dgqsgmn0");
diagramDTO.setCode("d1");
diagramDTO.setName("图表");
Diagram diagram = modelMapper.map(diagramDTO, Diagram.class);
}
复制代码
- 使用开源库
MapStruct
MapStruct
也是Java中另外一个用于映射对象很流行的开源工具。它是在编译阶段生成对应的映射代码,相对于ModelMapper
底层放射的方案,性能更好。
@Mapper
public interface DiagramMapper {
DiagramMapper INSTANCE = Mappers.getMapper(DiagramMapper.class);
DiagramDTO toDTO(Diagram diagram);
Diagram toEntity(DiagramDTO diagram);
}
private static void testMapStruct() {
DiagramDTO diagramDTO = new DiagramDTO();
diagramDTO.setId("3em3dgqsgmn0");
diagramDTO.setCode("d1");
diagramDTO.setName("图表");
Diagram diagram = DiagramMapper.INSTANCE.toEntity(diagramDTO);
}
复制代码
DiagramMapper
接口使用了@Mapper
注解,用来表明使用MapStruct
处理MapStruct
中更多高级特性大家自己探索一下。
总结
小结一下,对象在不同层之间进行转换映射,很不建议使用BeanUtil.copyProperties
这种方式,更加推荐使用原生的set
, get
方式,不容易出错。当然这不是将BeanUtil.copyProperties
一棒子打死,毫无用武之地,在特定场景,比如方法内部对象的转换等影响小的范围还是很方便的,如果你有其他的想法,也可以留下你的想法,一起探讨交流。
欢迎关注个人公众号【JAVA旭阳】交流学习!!