2016-11-24 12 views
1

私はSpring-Mybatis Polyporphismの問題に苦しんでいます。ここでは、詳細は以下のとおりです。 私はEntityを持っている:スプリングMybatis多型

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

public class Filter { 
    private String type; 
} 

フィルターが多型であるところ。あなたが見ることができるように、各サブクラスはtype除く異なるスキーマを持つ

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

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

: は次のように、フィルター上のいくつかのサブクラスがあります。以下のような

とMySQLテーブルsegment

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; 
    } 
} 

とジャクソンが多型のデシリアライズを行うようにするために:

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を作ります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; 
} 

しかし、その結果、jackson ObjectMapperはすべてのメッセージを逆シリアル化できません。

何か問題がありますか?私は何をすべきでしょうか? 便利なリンクやドキュメントがあります。

+0

A lsoは、create(@RequestBody SegmentEntity segmentEntity)のようなコントローラSegmentControllerを使用してe 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; 
    } 

}