简体   繁体   English

如何保持服务器端Java和客户端JS DTO属性的一致性

[英]how to keep server side Java and client side JS DTO properties consistent

Hi I'm looking for a solution/plugin in Eclipse to keep server-side Java DTO properties and their client-side JSON counterparts consistent throughout the evolution of the codebase. 嗨,我正在寻找Eclipse中的解决方案/插件,以保持服务器端Java DTO属性和它们的客户端JSON对应在整个代码库的演变过程中保持一致。 For example, for a webapp with a Java backend, with APIs exposed through a REST interface (using Jackson), the webapp could have something like this on the server: 例如,对于具有Java后端的webapp,通过REST接口(使用Jackson)公开API,webapp可能在服务器上有类似的东西:

the DTO: DTO:

public class Person {
    private String firstName;
    private String lastName;
    public Person(String string, String string2) {
        firstName = string; lastName = string2;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

The REST Service: REST服务:

@Path("/data")
public class PersonService {
    @GET
    @Path("persons")
    @Produces(MediaType.APPLICATION_JSON)
    public List<Person> getAssets() {
        List<Person> persons = new ArrayList<Person>();
        persons.add(new Person("Jimmy", "Hendrix"));
        persons.add(new Person("Roger", "Waters"));
        return persons;
    }
}

On the Client side, in Javascript/JQuery, we can have code like this: 在客户端,在Javascript / JQuery中,我们可以使用以下代码:

$.ajax('/data/persons/', function(data){ for(var i = 0; i < data.length; i++){ var firstName = data[i].firstName; var lastName = data[i].lastName; //do some stuff to populate the view with the person data } });

This is all straightforward to set up. 这一切都很简单。 However, as the codebase evolves and changes (as it always does), suppose there is a need to change the names of the DTO fields from “firstName” and “lastName”, to “foreName”, and “surName”. 但是,随着代码库的发展和变化(一如既往),假设需要将DTO字段的名称从“firstName”和“lastName”更改为“foreName”和“surName”。

In Eclipse, refactoring all of the Java code is simple using the Refactor menu item, which will find ALL references of the method/field in the Java code, and replace them. 在Eclipse中,使用Refactor菜单项重构所有Java代码很简单,该菜单项将在Java代码中找到方法/字段的所有引用,并替换它们。 Note that Eclipse's “Refactor…” is different than a Find/Replace action. 请注意,Eclipse的“Refactor ...”与“查找/替换”操作不同。 Find/Replace does a basic text replace on all files specified. 查找/替换会对指定的所有文件执行基本文本替换。 Refactor on the other hand, takes into account that Java is a strongly typed programming language, and searches for all method invocations with that signature. 另一方面,重构考虑到Java是强类型编程语言,并搜索具有该签名的所有方法调用。

It would be great if there was some plugin or Eclipse feature that would be smart enough to change the reference to “firstName” and “lastName” in the Javascript code as well. 如果有一些插件或Eclipse功能足够聪明,可以在Javascript代码中更改对“firstName”和“lastName”的引用,那将是很棒的。 That would save developers the time of having to do a Refactor for just the Java code, and then a selective Find/Replace in the Javascript code, and reduce potential runtime errors. 这样可以节省开发人员只需要为Java代码执行Refactor,然后在Javascript代码中进行选择性查找/替换,并减少潜在的运行时错误。 Does anyone know if such a tool/plugin exists? 有谁知道这样的工具/插件是否存在?

Yeah, me too. 我也是。 This seems like a pattern I encounter at every job. 这似乎是我在每个工作中遇到的模式。

Best I've done in the past is generate Javascript stubs from the java DTOs and used JsDoc to indicate where those javascript DTOs are used. 我过去做过的最好的事情是从java DTO生成Javascript存根,并使用JsDoc来指示这些javascript DTO的使用位置。

If I was doing that same solution today, I'd probably see what Swagger codegen would give me out of the box. 如果我今天也在做同样的解决方案,我可能会看到Swagger codegen会给我开箱即用的东西。

Intellij at least will highlight missing fields in the javascript, which is helpful. Intellij至少会突出显示javascript中缺少的字段,这很有帮助。

It would be great if there was a plugin, but this was better than nothing. 如果有一个插件会很棒,但这总比没有好。

With typescript you'd even get compile safety with the stubs. 使用打字稿,您甚至可以使用存根获得编译安全性。

For the JavaScript snippet you presented in the question, such a tool is probably impossible to write. 对于您在问题中提供的JavaScript代码段,这样的工具可能无法编写。

However, there are things you can do to improve the situation. 但是,您可以采取一些措施来改善这种情况。

On one side, you can write a generator for JavaScript representations of your DTOs. 一方面,您可以为DTO的JavaScript表示编写生成器。 IDE-friendly strategy would be to generate objects that have properties with default values. IDE友好的策略是生成具有默认值属性的对象。 Like 喜欢

var Person = { firstName: "", lastName: "", roles:[] };

Even if you do not actively integrate such a file into the actual web UI, it helps to reduce typo errors by checking the warnings IDE will throw at you. 即使您没有将这样的文件主动集成到实际的Web UI中,也可以通过检查IDE将向您发出的警告来减少拼写错误。

On another side, you could/should use a real JavaScript model layer. 另一方面,您可以/应该使用真正的JavaScript模型层。 Then you can validate all DTO JavaScript representations during automated testing and/or with a special button in eg maintenance part of the UI that QA always verifies before release. 然后,您可以在自动化测试期间验证所有DTO JavaScript表示和/或在QA始终在发布之前验证的UI的维护部分中使用特殊按钮。 If you upgrade your web UI together with the server, it definitely helps to catch missed refactoring leftovers. 如果您将Web UI与服务器一起升级,它肯定有助于捕获错过的重构剩余部分。

Validation endpoint would receive a JSON object like this: 验证端点将收到如下的JSON对象:

 { "Person": {...}, "Address": {...}, "Item": {...}, ... } 

and run it against package(s) with DTOs using a little bit of Java reflection. 并使用一些Java反射,使用DTO对包进行运行。 Of course, you could also use Nashorn engine in Java to do the validation directly on the server, eg during server start-up. 当然,您也可以使用Java中的Nashorn引擎直接在服务器上进行验证,例如在服务器启动期间。

It is not a silver bullet, it just greatly helps to reduce errors. 它不是一个银弹,它只是极大地帮助减少错误。 In the end, the less obscure logic you have in the UI, the easier it is to do the refactorings. 最后,UI中的逻辑不那么模糊,重构更容易。 Create or use generic, universal components, wire them up to DTOs in a very thin translation layer that uses label look-up tables, which can be validated as well. 创建或使用通用的通用组件,将它们连接到使用标签查找表的非常薄的转换层中的DTO,这也可以进行验证。 Also helps with i18n. 也有助于i18n。

Generation and validation can be used separately or together in one project. 生成和验证可以在一个项目中单独使用或一起使用。

BTW, one of the reasons to choose GWT for UI layer some years ago was to achieve exactly what you want. BTW,几年前为UI层选择GWT的原因之一就是实现你想要的。 I haven't been following it for a while, but it would be hard to imagine its drawbacks will outweigh this benefit. 我有一段时间没有关注它,但很难想象它的缺点将超过这个好处。

There is no such plugin. 没有这样的插件。 Welcome to the world of languages that are not statically typed. 欢迎来到非静态类型的语言世界。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM