2016-11-24 104 views
1

我正在遭受Spring-Mybatis多态性问题。下面是详细: 我有一个Entity春天Mybatis多态性

public class SegmentEntity { 
    private int id; 
    private String name; 
    private Filter filter; 
    // getter and setter 
} 

public class Filter { 
    private String type; 
} 

其中滤波器是多态的。 上有过滤某些子类,如:

public class OneFilter extends Filter { 
    private String field1; 
    private int field2; 
} 

public class AnotherFilter extends Filter { 
    private List<Integer> field3; 
    private double field4; 
} 

正如你可以看到,每个子类都有不同的type不同的架构。

和MySQL表segment像:

CREATE TABLE `segment` { 
    `id` int(11) NUL NULL AUTO_INCREMENT, 
    `name` varchar(32) NOT NULL, 
    `filter` varchar(1024) NOT NULL, 
    PRIMARY KEY (`id`) 
} ENGINE=InnoDB DEFAULT CHARSET=utf8; 

因此,为了在MYSQL反序列化filter(VARCHAR)我做这个FilterTypeHandler:

public class FilterTypeHandler implements TypeHandler<Filter> { 
    @Override 
    public Filter getResult(ResultSet rs, String columnName) throws SQLException { 
     String json = rs.getString(columnName); 
     Filter filter = null; 
     try { 
      filter = new ObjectMapper().readValue(json, Filter.class); 
     } catch (IOException e) {} 
     return filter; 
    } 
} 

,为了让杰克逊做多态反序列化,我更换过滤器类:

@JsonIgnoreProperties(ignoreUnknown = true) 
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") 
@JsonSubTypes({@JsonSubTypes.Type(value = OneFilter.class, name = "someTypeName"), 
      @JsonSubTypes.Type(value = AnotherFilter.class, name = "anotherTypeName")}) 
public class Filter { 
    private String type; 
} 

但结果是,杰克逊ObjectMapper不能反序列化所有消息。

那么有什么不对吗?我应该做什么正确的步骤? 任何有用的链接或文档都很有帮助。

+0

一个另外,当使用Controller(如SegmentController)创建e segmentEntity(@RequestBody SegmentEntity segmentEntity)时,反序列化也很难编码。 –

回答

0

我已经解决了我的问题,使用杰克森定制解串器。 这里是我的solusion:

首先我修改我的豆类,如:

@JsonDeserialize(using = FilterJsonDeserializer.class) 
public interface Filter { 
} 

和:

@JsonDeserialize(as = OneFilter.class) 
public class OneFilter implements Filter, Serializable { 
    private String type; 
    private String field1; 
    private int field2; 
    @JsonCreator 
    public OneFilter(@JsonProperty("type") String type, @JsonProperty("field1") String field1, @JsonProperty("field2") int field2) { 
     // omit 
    } 
    // getter and setter 
    // override toString 
} 

@JsonDeserialize(as = AnotherFilter.class) 
public class AnotherFilter implements Filter, Serializable { 
    private String type; 
    private List<Integer> field3; 
    private double field4; 
    @JsonCreator 
    public AnotherFilter(@JsonProperty("type") String type, @JsonProperty("field3") List<Integer> field3, @JsonProperty("field4") double field4) { 
     // omit 
    } 
    // getter and setter 
    // override toString 
} 

FilterJsonDeserializer是:

public class FilterJsonDeserializer extends JsonDeserializer<Filter> { 
    private static final String TYPE = "type"; 
    @Override 
    public Filter deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { 
     Filter result = null; 
     ObjectMapper = mapper = (ObjectMapper) jp.getCodec(); 
     ObjectNode root = mapper.readTree(jp); 
     if (root.has(TYPE)) { 
      String filterType = root.get(TYPE).asText(); 
      switch (filterType) { 
       case FILTER1: 
        result = mapper.readValue(root.toString(), OneFilter.class); 
        break; 
       case FILTER2: 
        result = mapper.readValue(root.toString(), AnotherFilter.class); 
        break; 
       default: 
        throw new IllegalArgumentException("Not supported filter type."); 
      } 
     } 
     return result; 
    } 

}