32

Spring MVC (v3.2.0.RELEASE) Web アプリケーションに次のオブジェクト モデルがあります。

public class Order {
  private Payment payment;
}

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = As.WRAPPER_OBJECT)
@JsonSubTypes.Type(name = "creditCardPayment", value = CreditCardPayment.class)
public interface Payment {}


@JsonTypeName("creditCardPayment")
public class CreditCardPayment implements Payment {}

Order クラスを JSON にシリアル化すると、次の結果が得られます (まさにこれが必要です)。

{
  "payment" : {
    "creditCardPayment": {
      ...
    } 
}

残念ながら、上記の JSON を逆シリアル化してオブジェクト モデルに戻そうとすると、次の例外が発生します。

JSON を読み取れませんでした: [ソース: org.apache.catalina.connector.CoyoteInputStream@19629355; 行: 1、列: 58] (参照チェーン経由: 注文["支払い"]); ネストされた例外は com.fasterxml.jackson.databind.JsonMappingException です: タイプ ID 'creditCardPayment' を [単純なタイプ、クラス支払い] のサブタイプに解決できませんでした [ソース: org.apache.catalina.connector.CoyoteInputStream@19629355; 行: 1、列: 58] (参照チェーン経由: Order["payment"])

私のアプリケーションは、Spring JavaConf を介して次のように構成されています。

@Configuration
@EnableWebMvc
public class AppWebConf extends WebMvcConfigurerAdapter {

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(Include.NON_NULL);
        objectMapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);
        return objectMapper;
    }

    @Bean
    public MappingJackson2HttpMessageConverter mappingJacksonMessageConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setObjectMapper(objectMapper());
        return converter;
    }

    @Bean
    public Jaxb2RootElementHttpMessageConverter jaxbMessageConverter() {
        return new Jaxb2RootElementHttpMessageConverter();
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(jaxbMessageConverter());
        converters.add(mappingJacksonMessageConverter());
    }
}

テスト用に、2 つのメソッドを持つコントローラーがあります。1 つは HTTP GET 要求の Order を返し (これは機能します)、もう 1 つは HTTP POST を介して注文を受け入れる (これは失敗します)。

@Controller
public class TestController {

    @ResponseBody
    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public Order getTest() {}

    @RequestMapping(value = "/test", method = RequestMethod.POST)
    public void postTest(@RequestBody order) {}

}

SOに関するさまざまな議論からのすべての提案を試しましたが、これまでのところうまくいきませんでした。誰かが私が間違っていることを見つけることができますか?

4

6 に答える 6

19

ObjectMapper.registerSubtypes注釈を使用する代わりに使用してサブタイプを登録してみてください

于 2013-10-08T05:44:49.307 に答える
4

dropwizard ベースのサービスに取り組んでいるときに、同様の問題が発生しました。dropwizard コードが機能するのと同じように機能しなかった理由は完全には理解できませんが、元の投稿のコードが機能しない理由はわかっています。@JsonSubTypes単一の値ではなく、サブタイプの配列が必要です。では、ラインを交換すると・・・

@JsonSubTypes.Type(name = "creditCardPayment", value = CreditCardPayment.class)

と...

@JsonSubTypes({ @JsonSubTypes.Type(name = "creditCardPayment", value = CreditCardPayment.class) })

あなたのコードはうまくいくと思います。

同じエラー メッセージが表示される場合は、サブタイプの検出に問題がある可能性があります。@JsonTypeName上記のような行を追加するか、タグを含むクラスの検出に関する問題を探してみてください。

于 2016-09-13T22:22:15.523 に答える
0

Rashmin の答えは機能し、com.fasterxml.jackson.databind.JsonMappingException: Could not resolve type id into a subtype of Blah使用せずに問題を回避する別の方法を見つけましたregisterSubtypes。できることは、次の注釈を親クラスに追加することです。

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "type")

JsonTypeInfo.Id.CLASS違いはではなく であることに注意してくださいJsonTypeInfo.Id.NAME。欠点は、作成された JSON に完全な名前空間を含むクラス名全体が含まれることです。利点は、サブタイプの登録について心配する必要がないことです。

于 2016-04-26T16:39:42.477 に答える
0

私の場合defaultImpl = SomeClass.class、 @JsonTypeInfo に追加し、それを SomeClass2.class に変換しようとしていました

于 2017-09-01T14:13:33.513 に答える