为啥 Jackson ObjectMapper 不能序列化 play.data.validation.ValidationError 类?

Posted

技术标签:

【中文标题】为啥 Jackson ObjectMapper 不能序列化 play.data.validation.ValidationError 类?【英文标题】:Why Jackson ObjectMapper cannot serialize play.data.validation.ValidationError class?为什么 Jackson ObjectMapper 不能序列化 play.data.validation.ValidationError 类? 【发布时间】:2014-06-03 22:46:55 【问题描述】:

我有以下设置:


public class ValidationUtils 

  public static class ValidationResults 
      public List validationErrors;
      public boolean valid;

      public ValidationResults()
        validationErrors = new ArrayList();
        valid = true;
    

      @Override
      public String toString() 
        return "ValidationResults [validationErrors=" + validationErrors
                    + ", valid=" + valid + "]";
      
  

  // some static methods that create instances of ValidationResults.


在 ValidationResults 类的序列化时出现此错误:

com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class play.data.validation.ValidationError and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: utils.ValidationResults["validationErrors"]->java.util.ArrayList[0])

我使用 play.libs.Json 实用程序类,它只是 Jackson 的对象映射器的包装器。 有谁知道问题是什么以及我该如何解决?

ValidationError类的结构如下:


package play.data.validation;

import java.util.*;

import com.google.common.collect.ImmutableList;

/**
 * A form validation error.
 */
public class ValidationError 

    private String key;
    private String message;
    private List arguments;

    /**
     * Constructs a new ValidationError.
     *
     * @param key the error key
     * @param message the error message
     */
    public ValidationError(String key, String message) 
        this(key, message, ImmutableList.of());
    

    /**
     * Constructs a new ValidationError.
     *
     * @param key the error key
     * @param message the error message
     * @param arguments the error message arguments
     */
    public ValidationError(String key, String message, List arguments) 
        this.key = key;
        this.message = message;
        this.arguments = arguments;
    

    /**
     * Returns the error key.
     */
    public String key() 
        return key;
    

    /**
     * Returns the error message.
     */
    public String message() 
        return message;
    

    /**
     * Returns the error arguments.
     */
    public List arguments() 
        return arguments;
    

    public String toString() 
        return "ValidationError(" + key + "," + message + "," + arguments + ")";
    


【问题讨论】:

【参考方案1】:

ValidationError 的字段访问器方法既不遵循JavaBean conventions,也没有使用@JsonProperty 注释,因此Jackson 无法识别它们。

以下是您稍作修改的类的工作示例,其中包含更新的方法名称:

public class JacksonGetters 
    public static class ValidationError 

        private String key;
        private String message;
        private List arguments;

        /**
         * Constructs a new ValidationError.
         *
         * @param key the error key
         * @param message the error message
         */
        public ValidationError(String key, String message) 
            this(key, message, null);
        

        /**
         * Constructs a new ValidationError.
         *
         * @param key the error key
         * @param message the error message
         * @param arguments the error message arguments
         */
        public ValidationError(String key, String message, List arguments) 
            this.key = key;
            this.message = message;
            this.arguments = arguments;
        

        /**
         * Returns the error key.
         */
        public String getKey() 
            return key;
        

        /**
         * Returns the error message.
         */
        public String getMessage() 
            return message;
        

        /**
         * Returns the error arguments.
         */
        public List getArguments() 
            return arguments;
        

        public String toString() 
            return "ValidationError(" + key + "," + message + "," + arguments + ")";
        

    

    public static void main(String[] args) throws JsonProcessingException 
        ValidationError err = new ValidationError("key", "message");
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(err));
    


输出:


  "key" : "key",
  "message" : "message",
  "arguments" : null

【讨论】:

以上是关于为啥 Jackson ObjectMapper 不能序列化 play.data.validation.ValidationError 类?的主要内容,如果未能解决你的问题,请参考以下文章

jackson objectMapper 与其他人的区别

spring boot定制Jackson ObjectMapper,为什么不生效

Spring Boot 不使用配置的 Jackson ObjectMapper 和 @EnableWebMvc

Spring Boot 自动配置的 Jackson ObjectMapper 默认不用于 WebFlux WebClient

Jackson ObjectMapper类使用解析

如何在不影响原始 bean 的“客户”的情况下声明另一个 Jackson ObjectMapper?