2016-11-20 16 views
1

ためだから... ...私はここに新たなんだと、以下の問題は、おそらく多くの時間を議論してきたが、私は私の問題に明確な解決策を見つけることができないことを知っているジェネリッククラス

をジャクソンTypeReferenceを使用する方法、I - AngularJSのフロントエンド - Spring MVCのバックエンド ジャクソンとJSON形式の両方の部分交換。 以下のJava関数にデータを送信する

\t \t /** 
 
    \t \t * Reference save. 
 
    \t \t * @param reference The reference to save 
 
    \t \t * @param type Type of reference 
 
    \t \t */ 
 
    \t \t save: function(reference,type) { 
 
    \t \t \t return $http.post('myApplication/reference/save/'+ type, reference); 
 
    \t \t }

  ** 
    * Reference Controller. 
    * @param <VO> Reference 
    * @param <E> Entity 
    */ 
    @RequestMapping("/reference/") 
    @Controller 
    public class ReferenceController<VO extends AbstractReferenceEntityVO, E extends AbstractReferenceEntity> { 

    /** Reference management service. */ 
    @Autowired 
    private ReferenceService<VO, E> referenceService; 

    /** 
    * Reference save method. 
    * @param referenceVO View Object of the reference to save 
    * @param type Reference type 
    * @return VO 
    */ 
    @ResponseBody 
    @RequestMapping(value = "/save/{type}", method = RequestMethod.POST, 
      headers = "Accept=application/json") 
    public VO save(@Validated @RequestBody final VO referenceVO, 
      @PathVariable final String type) 
    { 
     return this.referenceService.save(type, referenceVO); 

    } 
} 

だから私フロントエンドに以下のJavascript機能を持つオブジェクト(VO)

を表示するためにJSONを関連付ける このJAVAクラスは、抽象クラスから継承する2種類のReferenceVO(VO1 & VO2)を送受信できるため、汎用クラスです(A bstractReferenceEntityVO)。私はジェネリッククラスを管理するために、ジャクソン「TypeReference」を使用する必要が見つかっ

*Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of myApplication.AbstractReferenceEntityVO, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information 
    at [Source: [email protected]; line: 1, column: 1] 
     at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148) 
     at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:889) 
     at 
com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:139) 
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3702) 
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2798) 
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:205) 
    ... 88 more* 

研究の後:

今日私は、これは保存機能を呼び出すしようとすると、以下のジャクソンの問題を抱えています。だから私は、VOを継承したJacksonに、VOとマッピングするために使用する必要があるように指定する必要があると思います。

これは私ですObjectMapper & XML構成:

\t <mvc:annotation-driven conversion-service="applicationConversionService"> 
 
\t \t <mvc:message-converters> 
 
\t \t \t <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
 
    \t \t \t \t <property name="objectMapper"> 
 
\t \t \t \t \t <bean class="myApplication.CustomObjectMapper" /> 
 
\t \t \t \t </property> 
 
\t \t \t </bean> 
 
\t \t </mvc:message-converters> 
 
\t </mvc:annotation-driven>

/** 
* Mapper JSON objets. 
*/ 
public class CustomObjectMapper 
    extends ObjectMapper 
{ 
    /** Id. */ 
    private static final long serialVersionUID = 6488036405547458525L; 

    /** Constructor. */ 
    public PlageObjectMapper() 
    { 
     super(); 
     this.registerModule(new JodaModule()); 
     this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); 
     this.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); 

     TypeReference ref = new TypeReference<AbstractReferenceEntityVO>() { 
      // if(type== "TYPE_1") { 
      // TODO 
      // } else { 
      // TODO 
      // } 
     }; 
    } 
} 

誰かがすでに似た何かを持っていますか?私の場合、TypeReferenceの使い方は?正直言って私は何をすべきか分からない!

ありがとうございました!

答えて

0

jsonのフィールドとしてタイプ識別子を渡す必要があります。基底クラスに@JsonTypeInfoと注釈を付けて、使用するフィールドの名前と識別子を指定します。デフォルトでは、クラス名を識別子として使用している場合は、フィールド名は@classです。

詳細はpolymorphic deserialisationのwikiページをご覧ください。

例:

import com.fasterxml.jackson.annotation.JsonTypeInfo; 
import com.fasterxml.jackson.core.JsonProcessingException; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import org.xml.sax.SAXException; 

import javax.xml.transform.TransformerException; 
import java.io.IOException; 

public class Scratch { 

    private static ObjectMapper mapper = new ObjectMapper(); 

    public static void main(String[] args) throws IOException, TransformerException, SAXException { 
     System.out.println(mapper.readValue("{\"@class\": \"Scratch$B\", \"payload\": \"hello, world.\"}", A.class)); 
     System.out.println(mapper.readValue("{\"@class\": \"Scratch$C\", \"payload\": \"hello again.\", \"extra\": 1}", A.class)); 
    } 

    @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) 
    abstract public static class A { 
     abstract public String getPayload(); 

     @Override 
     public String toString() { 
      try { 
       return "I'm a " + getClass().getSimpleName() + ": " + mapper.writeValueAsString(this); 
      } catch (JsonProcessingException e) { 
       throw new RuntimeException(e); 
      } 
     } 
    } 

    public static class B extends A { 
     private String payload; 

     @Override 
     public String getPayload() { 
      return payload; 
     } 

     public void setPayload(String payload) { 
      this.payload = payload; 
     } 
    } 

    public static class C extends B { 
     private int extra; 

     public int getExtra() { 
      return extra; 
     } 

     public void setExtra(int extra) { 
      this.extra = extra; 
     } 
    } 
} 
関連する問題

 関連する問題