在服务器和客户端之间共享字段约束

时间:2020-01-25 18:44:31

标签: java angular typescript spring-boot jpa

我正在一个项目中,服务器端基于Spring Boot 2,前端基于Angular。

在服务器端,在数据模型类中,我有这样的声明:

@Column(length = 256, nullable = false)
@Size(max = 256)
private String subject;

我也想在前端(角度侧)实现字段长度验证。

在服务器和客户端之间共享字段长度约束的最佳方法是什么?

我不喜欢这样的想法,即我需要在服务器和客户端两边重复我自己和硬编码字段的长度。

如果我声明这样的一组常量,这是否是我的最佳选择:

private static final int maxSubjectLength = 256;

并按如下所示使用它们:

@Column(length = maxSubjectLength, nullable = false)
@Size(max = maxSubjectLength)
private String subject;

然后使用这些常量创建一个配置类,可以通过GET http-request访问哪个实例?

还是有更好的方法?

1 个答案:

答案 0 :(得分:0)

我决定使用以下方法。假设我们有一个模型类Question,它有一个属性body

@Entity
@Table(name = "Questions")
public final class Question {

    // other properties & code

    private String body;

    // other properties & code
}

我们希望将主体长度限制为1024个符号,并在服务器上仅定义一次此限制,并在应用程序的后端和前端使用此限制。

在服务器端,我们在模型类Question中定义了静态映射,其中包含所有类属性的大小限制。

@Entity
@Table(name = "Questions")
public final class Question {

    private static class ModelConstraints {
        static final int MAX_BODY_LENGTH = 1024;
        // limits for other fields are going here
    }

    private static final Map<String, Integer> modelConstraintsMap;

    static
    {
        final Map<String, Integer> localConstraintsMap = new HashMap<>();
        localConstraintsMap.put("MAX_BODY_LENGTH", ModelConstraints.MAX_BODY_LENGTH);
        // .... putting all constants from ModelConstraints to the map here

        // composing unmodifable map    
        modelConstraintsMap = Collections.unmodifiableMap(localConstraintsMap);
    }

    @Column(length = ModelConstraints.MAX_BODY_LENGTH, nullable = false)
    @Size(max = ModelConstraints.MAX_BODY_LENGTH)
    private String body;

    // other properties and code

    public static Map<String, Integer> getModelConstraintsMap() {
        return modelConstraintsMap;
    }   

    // other properties and code
}

内部类ModelConstraints包含所有相关模型属性的最大长度值的定义。

在静态块中,我创建了一个不可修改的映射,其中包含这些约束,然后通过公共方法返回此映射。

在控制器中,与模型类相关,我添加了一个返回属性长度约束的休息端点。

@RequestMapping(path = "/questions/model-constraints", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<Map<String, Integer>> getModelConstraints() {
    return new ResponseEntity<>(Question.getModelConstraintsMap(), HttpStatus.OK);
}

此方法返回具有属性长度约束的地图的json表示形式。

在(角度)框架上,我将其称为端点,并设置与模型类属性相关的表单域的maxlength属性。

我在组件打字稿文件中添加并调用此方法:

  loadConstraints() {
    var url: string = "/questions/model-constraints";
    this.http
      .get(url)
      .subscribe((data: Map<string, number>) => (this.modelConstraints = data));
  }

在调用此方法后,组件属性modelConstraints将包含具有字段长度约束的映射。

我在组件模板(html)文件中设置了这些约束。

  <textarea
    matInput
    rows="7"
    placeholder="Question body"
    maxlength="{{ modelConstraints['MAX_BODY_LENGTH'] }}"
    [(ngModel)]="questionBody"
  ></textarea>

就是这样。使用这种方法,您只能在服务器上定义一次字段长度,并在服务器和客户端上使用此定义。

相关问题