Java 8 Jackson 验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36357713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 17:46:25  来源:igfitidea点击:

Java 8 Hymanson validation

javajsonspringspring-mvcHymanson

提问by Richard

I have a springboot rest service. The user passes in a json object that gets deserialized into this java pojo:

我有一个 springboot 休息服务。用户传入一个 json 对象,该对象被反序列化为这个 java pojo:

public final class Request {
    private String id;
    private double code;
    private String name;

    public String getId() {
        return id;
    }

    public double getCode() {
        return code;
    }

    public String getName() {
        return name;
    }
}

So the user needs to pass in the following json:

所以用户需要传入以下json:

{
    "id": “123457896”,
    "code": "Foo",
    "name": "test"
} 

I want to make all of those fields required. Providing anything less or more will throw an exception. Is there a way to tell Hymanson to validate the input when it deserializes? I've tried @JsonProperty(required=true)but this doesn't work; apparently from hereand hereit seems the JsonPropertyannotation is not respected.

我想让所有这些字段都是必需的。提供任何更少或更多的东西都会引发异常。有没有办法告诉 Hymanson 在反序列化时验证输入?我试过了,@JsonProperty(required=true)但这不起作用;显然,从这里这里看来,JsonProperty注释没有得到尊重。

I have this validator that I call in my controller:

我在控制器中调用了这个验证器:

@Component
public class RequestValidator implements Validator {
    @Override
    public boolean supports(Class<?> clazz) {
        return false;
    }

    @Override
    public void validate(Object target, Errors errors) {
        String id = ((Request) target).getId();
        if(id == null || id.isEmpty()) {
            throw new InvalidRequestException("A valid id is missing. Please provide a non-empty or non-null id.");
        }
    }
}

But that just seems tedious and ugly to check every field. So given I'm using java 8, spring boot and latest version of Hymanson what is the best practice in terms of validating an incoming json input? Or am I already doing it in the most up to date manner?

但是,检查每个字段似乎既乏味又难看。因此,鉴于我使用的是 java 8、spring boot 和最新版本的 Hymanson,验证传入的 json 输入的最佳实践是什么?还是我已经以最新的方式在做?

采纳答案by Dennis R

You used Spring Validator approach. There is another approach:

您使用了 Spring Validator 方法。还有另一种方法:

J2EE JSR-303/JSR-349 Bean Validation API. it provides validation annotations (javax, not Hymanson).

J2EE JSR-303/JSR-349 Bean 验证 API。它提供验证注释(javax,而不是 Hymanson)。

See good example of both here

这里看到两者的好例子

回答by varren

There is no need for custom validator. There is a way to tell Hymanson to throw

没有必要自定义的验证。有一种方法可以告诉Hyman逊扔

  • JsonMappingExceptionif you don't have required fields

  • UnrecognizedPropertyExceptionif you have extra fields (UnrecognizedPropertyExceptionis just extended JsonMappingException) .

  • JsonMappingException如果您没有必填字段

  • UnrecognizedPropertyException如果您有额外的字段(UnrecognizedPropertyException只是扩展JsonMappingException)。

You just need to add @JsonCreatoror custom constructor. Something like this should work:

您只需要添加@JsonCreator或自定义构造函数。这样的事情应该工作:

public Request(@JsonProperty(value= "id", required = true)String id,
               @JsonProperty(value= "code",required = true)double code,
               @JsonProperty(value= "name",required = true)String name) {
    this.id = id;
    this.code = code;
    this.name = name;
}

Full Demo:

完整演示:

import com.fasterxml.Hymanson.annotation.JsonCreator;
import com.fasterxml.Hymanson.annotation.JsonProperty;
import com.fasterxml.Hymanson.databind.JsonMappingException;
import com.fasterxml.Hymanson.databind.ObjectMapper;
import java.io.IOException;

public class Main {

public static void main(String[] args) throws IOException {
    test("{\"id\": \"123457896\",\"code\": 1,\"name\": \"test\"}");
    test("{\"id\": \"123457896\",\"name\": \"test\"}");
    test("{\"id\": \"123457896\",\"code\": 1, \"c\": 1,\"name\": \"test\"}");
}

public static void test(String json) throws IOException{
    ObjectMapper mapper = new ObjectMapper();
    try {
        Request deserialized = mapper.readValue(json, Request.class);
        System.out.println(deserialized);
        String serialized = mapper.writeValueAsString(deserialized);
        System.out.println(serialized);
    } catch (JsonMappingException e) {
        System.out.println(e.getMessage());
    }
}

public static class Request {
    private String id;
    private double code;
    private String name;

    public Request(@JsonProperty(value= "id", required = true)String id,
                   @JsonProperty(value= "code",required = true)double code,
                   @JsonProperty(value= "name",required = true)String name) {
        this.id = id;
        this.code = code;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public double getCode() {
        return code;
    }

    public void setCode(double code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Request{" +
                "id='" + id + '\'' +
                ", code=" + code +
                ", name='" + name + '\'' +
                '}';
    }
}
}

Result:

结果:

Request{id='123457896', code=1.0, name='test'}
{"id":"123457896","code":1.0,"name":"test"}
Missing required creator property 'code' (index 1)
 at [Source: {"id": "123457896","name": "test"}; line: 1, column: 34]
Unrecognized field "c" (class Main7$Request), not marked as ignorable (3 known properties: "id", "code", "name"])
 at [Source: {"id": "123457896","code": 1, "c": 1,"name": "test"}; line: 1, column: 53] (through reference chain: Request["c"])

回答by tyagi

You can use Hymanson schema validation. Create a schema.json and validate each incoming input against this schema. Follow this link for more details http://wilddiary.com/validate-json-against-schema-in-java/

您可以使用 Hymanson 模式验证。创建一个 schema.json 并根据此架构验证每个传入的输入。点击此链接了解更多详情 http://wilddiary.com/validate-json-against-schema-in-java/

回答by octavian

Using the @JsonCreatorannotation on the constructor together with @JsonPropertywill work. Check this answeras well.

@JsonCreator将构造函数上的注释与一起使用@JsonProperty将起作用。也检查这个答案

public final class Request {
    private String id;
    private double code;
    private String name;

    @JsonCreator
    public Request(@JsonProperty(required = true) String id,
                   @JsonProperty(required = true) double code,
                   @JsonProperty(required = true) String name) {
        this.id = id;
        this.code = code;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public double getCode() {
        return code;
    }

    public String getName() {
        return name;
    }
}