无法使用带有构建器模式的 jackson 3+ 实例化 POJO

hur*_*own 1 java spring json spring-mvc jackson

我有以下课程:

@JsonDeserialize(builder = Article.Builder.class)
public class Article {

    private final String id;
    private final String headline;

    private Article(final Builder builder) {
        this.id = checkNotNull(builder.id);
        this.headline = checkNotNull(builder.headline);
    }

    @Nonnull
    public String getId() {
        return id;
    }

    @Nonnull
    public String getHeadline() {
        return headline;
    }

    public static Builder builder() {
        return new Builder();
    }

    @JsonPOJOBuilder(buildMethodName = "build", withPrefix = "")
    public static class Builder {
        private String id;
        private String headline;

        public Builder id(final String id) {
            this.id = id;
            return this;
        }

        public Builder headline(final String headline) {
            this.headline = headline;
            return this;
        }

        public Article build() {
            return new Article(this);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

通过这些注释,我可以使用 Jackson ObjectMapper 序列化和反序列化对象,但是在以下控制器中使用 Article 时收到错误:

@RequestMapping(value = "/article/{category}", method = PUT)
public void receiveArticle(@PathVariable("category") final String category, final Article article) {
    service.createOrUpdateArticle(category, article);
}
Run Code Online (Sandbox Code Playgroud)

用这个 URL 调用它:

http://localhost:8080/article/cat_1/?article={"id":"aid001","headline":"this is the headline"}
Run Code Online (Sandbox Code Playgroud)

这是错误:

HTTP Status 500 - Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.example.Article]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.example.Article.<init>()

java.lang.NoSuchMethodException: com.example.Article.<init>()
java.lang.Class.getConstructor0(Class.java:2892)
...
Run Code Online (Sandbox Code Playgroud)

我按照本教程使用构建器模式:http : //wiki.fasterxml.com/JacksonFeatureBuilderPattern

有人知道为什么我会收到此错误吗?

Sot*_*lis 5

Spring 不会使用 JSON 反序列化为您的处理程序方法生成参数。

@RequestMapping(value = "/article/{category}", method = PUT)
public void receiveArticle(@PathVariable("category") final String category, final Article article) {
    service.createOrUpdateArticle(category, article);
}
Run Code Online (Sandbox Code Playgroud)

您目前拥有它的方式,Article参数被解释为模型属性,就好像它用@ModelAttribute. Spring 将尝试使用无参数构造函数来实例化类。由于您的Article课程没有提供,因此失败了。

相反,将 JSON 移动到请求正文,在请求中发送Content-Type: application/json标头,并使用 @RequestBody.

@RequestMapping(value = "/article/{category}", method = PUT)
public void receiveArticle(@PathVariable("category") final String category, @RequestBody final Article article) {
    service.createOrUpdateArticle(category, article);
}
Run Code Online (Sandbox Code Playgroud)