Es ist taub, verwenden Sie nicht mehr einfach BeanUtil.copyProperties! ! !

Vorwort

Kürzlich erforderte das Projekt ein Upgrade einer Toolkit- hutoolVersion, 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, hutoolist 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:

  1. Datenübertragungsobjekt
@Data
@ToString
public class DiagramDTO {

    // 前端生产的字符串id
    private String id;

    private String code;

    private String name;
}
复制代码
  1. Datenentitätsobjekt
@Data
@ToString
public class Diagram {

    private Integer id;

    private String code;

    private String name;
}
复制代码
  1. 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 hutoolwar es Version 5.7.2, und das Ausführungsergebnis ist wie in der folgenden Abbildung dargestellt.

  • BeanUtil.copyPropertiesObwohl die Feldtypen unterschiedlich sind, wurde eine Kompatibilitätsverarbeitung durchgeführt, sodass das Geschäft die Geschäftslogik nicht beeinflusst.

Nach dem Upgrade hutoolist 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.copyPropertiesdie 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.copyPropertieslä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

  1. ursprünglicher getWeg set_

Ich plädiere eher für diese Vorgehensweise: Wenn Sie beispielsweise DiagramDTOjetzt 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~~

  1. Verwenden Sie Open-Source-BibliothekenModelMapper

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);
    }
复制代码
  1. 使用开源库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旭阳】交流学习!!

Guess you like

Origin juejin.im/post/7222305855978078265