使用jackson

时间:2016-03-24 08:28:38

标签: java database serialization jackson deserialization

我想做的事情似乎很简单,只需处理如下对象:

  1. 当从客户端(Web浏览器)接收Post请求时,服务器将其反序列化为某个对象,并将其部分序列化,然后将其保存到数据库中。
  2. 当从客户端收到Get请求时,服务器从数据库中检索对象,对其进行反序列化,将其与其他信息组合并将其返回给客户端。
  3. 问题是,该对象包含一个抽象字段。

    保存请求正常

    当我将这些注释添加到抽象类时,第1阶段工作正常。

    请求JSON:

    { config: { type: "concreteA", ...}, ...}
    

    REST API:

    @RequestMapping(value="/configs", method=RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<Object> saveConfig(@RequestBody ConfigRequest request) 
    throws IOException {
    ...
    }
    

    ConfigRequest类:

    public class ConfigRequest {
        private AbstractConfig config;
        // Abbr. other fields, and all getters and setters 
    }
    

    AbstractConfig类,包含在ConfigRequest

    @JsonTypeInfo(use=JsonTypeInfo.Id.NAME,
                  include=JsonTypeInfo.As.PROPERTY,
                  property="type",
                  visible=true)
    @JsonSubTypes({@Type(value=ConcreteAConfig.class, name="concreteA")})
    public abstract class AbstractConfig {
        public AbstractConfig(){}
        private String type;
        // Abbr. other fields, and all getters and setters 
    }
    

    反序列化字符串:

    {"type":"concreteA", ...}
    

    反序列化json字符串失败

    但是当我尝试检索和反序列化(第2阶段)时,反序列化失败了:

    16/03/24 17:17:20 ERROR (...Abbr...) org.codehaus.jackson.map.JsonMappingException: Can not construct instance of AbstractConfig, problem: abstract types can only be instantiated with additional type information
    

    RowMapper,它引发了错误:

    public class BatchRowMapper implements RowMapper<Batch> {
      private static ObjectMapper objectMapper = new ObjectMapper();
    
      @Override
      public Batch mapRow(ResultSet row, int rowNum) throws SQLException {
        Batch batch = new Batch();
    
        try {
          // THIS METHOD RAISES THE ERROR
          batch.setConfig(objectMapper.readValue(row.getString(CONFIG), AbstractConfig.class));
        } catch (ClassCastException|IOException e) {
          throw new SQLException(e.toString());
        }
    
        return batch;
      }
    }
    

    我希望使用相同的&#34;类型&#34;来删除/删除一个抽象字段。字段,只使用注释是我的愿望......有可能吗?如果需要进一步的信息,我愿意。 提前谢谢。

1 个答案:

答案 0 :(得分:1)

我发现杰克逊使用的是这个问题。

当我使用codehause(旧版)的jackson时,使用JsonTypeInfo进行反序列化无法正常工作。 Jacksonxml的Jackson工作得很好。