【问题标题】:Jackson check optional field杰克逊检查可选字段
【发布时间】:2018-09-28 13:13:13
【问题描述】:

问题

我正在 JAX-RS 项目中制作 POJO(人)并使用 Jackson。
我想创建一个可选的字符串字段(例如该人居住的国家/地区)并能够检查其长度。

我的测试

通过参考这篇文章 (How to define optional json field using Jackson) 我知道如何创建一个可选字段。但是,如果我想用 javax.validation.constraints.Pattern 来检查它的长度,如下所示:

@Pattern(regexp = "(?:.{0,12})?")
private final String country;

国家不能为 NULL 或不再存在。

我尝试添加 @Optional (org.jvnet.hk2.annotations.Optional) 并指定 国家,例如 private final Optional<String> country;。这两种方法我都没有成功。

我的实际 POJO

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import org.hibernate.validator.constraints.NotBlank;

import javax.validation.constraints.Pattern;

@JsonAutoDetect(creatorVisibility = Visibility.ANY, fieldVisibility = Visibility.ANY)
@JsonPropertyOrder({Person.LAST_NAME, Person.FIRST_NAME, Person.COUNTRY})
@JsonIgnoreProperties(ignoreUnknown = true)
public class Person {

    /**
     * The format string for the toString method
     */
    private static final String TO_STRING_FORMAT = "%S %s %s";

    /**
     * JSON property name for the last name
     */
    static final String LAST_NAME = "lastName";

    /**
     * JSON property name for the first name
     */
    static final String FIRST_NAME = "firstName";

    /**
     * JSON property name for the country
     */
    static final String COUNTRY = "country";

    /**
     * The last name of the person
     */
    @NotBlank
    private final String lastName;

    /**
     * The first name of the person
     */
    @NotBlank
    private final String firstName;

    /**
     * The country of the person
     */
    @Pattern(regexp = "(?:.{0,12})?")
    private final String country;

    /**
     * Returns an new {@code Person} with its properties initialized from parameters.
     *
     * @param lastName the last name of the person ({@link #lastName})
     * @param firstName the first name of the person ({@link #firstName})
     * @param country the country where the person live ({@link #country})
     */
    // Only used by Jackson for the JSON data deserialization
    @SuppressWarnings("unused")
    @JsonCreator
    private Person(@JsonProperty(Person.LAST_NAME) String lastName, @JsonProperty(Person.FIRST_NAME) String firstName, @JsonProperty(Person.COUNTRY) String country) {
        this.lastName = lastName.trim();
        this.firstName = firstName.trim();
        this.country = country.trim();
    }

    /**
     * Returns a new {@code Person} with its properties initialized from another one.
     *
     * @param person the instance used to create the new one
     */
    Person(Person person) {
        this.lastName = person.lastName;
        this.firstName = person.firstName;
        this.country = person.country;
    }

    /**
     * Returns a textual representation of the {@code Person}: {@link #lastName} {@link #firstName} {@link #country}.
     * <p>
     * The {@code lastName} is converted to uppercase for better readability of the person's name.
     *
     * @return a string representation of the {@code Person}
     */
    @Override
    public String toString() {
        return String.format(Person.TO_STRING_FORMAT, this.lastName, this.firstName, this.country);
    }
}

【问题讨论】:

    标签: java json jackson jax-rs


    【解决方案1】:

    问题

    问题是我在国家/地区创建了trim()(可能为 NULL 值)。见下文:

    @SuppressWarnings("unused")
    @JsonCreator
    private Person(@JsonProperty(Person.LAST_NAME) String lastName, @JsonProperty(Person.FIRST_NAME) String firstName, @JsonProperty(Person.COUNTRY) String country) {
        this.lastName = lastName.trim();
        this.firstName = firstName.trim();
        this.country = country.trim();
    }
    

    解决方案

    我要感谢@TheOddCoder 的解决方案。我的 @Pattern 正则表达式没有改变,但构造函数 private Person(...) (@JsonCreator) 发生以下变化:

    @SuppressWarnings("unused")
    @JsonCreator
    private Person(@JsonProperty(Person.LAST_NAME) String lastName, @JsonProperty(Person.FIRST_NAME) String firstName, @JsonProperty(Person.COUNTRY) String country) {
        this.lastName = lastName.trim();
        this.firstName = firstName.trim();
        if(country == null) {
            this.country = country;
        } else {
            this.country = country.trim();
        }
    }
    

    【讨论】:

    • “我要感谢@TheOddCoder 的解决方案。” 接受并点赞他的答案,而不是发布你的答案...
    • @CassioMazzochiMolin 正如我在对他的回答的评论中提到的,我不得不修改他的回答以使其与我的问题的根源相匹配。
    【解决方案2】:

    在您的情况下,我可能会建议您验证您的国家/地区是否已设置并以这种方式处理,而不是为您的字段使用可选项。

    private Person(@JsonProperty(Person.LAST_NAME) String lastName, @JsonProperty(Person.FIRST_NAME) String firstName, @JsonProperty(Person.COUNTRY) String country) {
        this.lastName = lastName.trim();
        this.firstName = firstName.trim();
        if(country == null) { //here you could also use the string empty or null check of apache or guava
            this.country = country;
        } else {
            this.country = country.trim();
        }
    }
    

    这样您就不必关心它是否设置,并且无论如何正则表达式都会匹配。

    我希望这会有所帮助。

    【讨论】:

    • 感谢您的有用回答。我刚刚将您的解决方案写入位置从构造函数Person(Person person) 更改为构造函数private Person(...) (@JsonCreator)
    猜你喜欢
    • 2013-08-16
    • 2012-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多