9

私のエンティティ:

public class User {

    private Integer id;
    private String mail;
    private boolean enabled;

    // getters and setters
}

ファイル test.json (REST Web サービスからの応答):

{
 "_embedded" : {
  "users" : [ {
    "id" : 1,
    "mail" : "admin@admin.com",
    "enabled" : true,
    "_links" : {
      "self" : {
        "href" : "http://localhost:8080/api/users/1"
      }
    }
  } ]
 }
}

そして私のテストクラス:

public class TestJson {

    private InputStream is;
    private ObjectMapper mapper;

    @Before
    public void before() {
        mapper = new ObjectMapper();
        mapper.registerModule(new Jackson2HalModule());
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        is = TestJson.class.getResourceAsStream("/test.json");
    }

    @After
    public void after() throws IOException {
        is.close();
    }

    @Test
    public void test() throws IOException {
        PagedResources<Resource<User>> paged = mapper.readValue(is, new TypeReference<PagedResources<Resource<User>>>() {});
        Assert.assertNotNull(paged.getContent().iterator().next().getContent().getId());
    }

    @Test
    public void testResource() throws IOException {
        PagedResources<User> paged = mapper.readValue(is, new TypeReference<PagedResources<User>>() {});
        Assert.assertNotNull(paged.getContent().iterator().next().getId());
    }
}

2 番目のテストはパスしますが、最初のテストはパスしません。ユーザーの id プロパティだけが欠落しているため、わかりません (メールと有効なプロパティは空ではありません)...

修正するにはどうすればよいですか? Jackson または Spring Jackson2HalModule のバグですか?

私の spring-hateoas フォークリポジトリを複製し、単体テストを起動することで再現できます。

4

3 に答える 3

13

実際にResourceは、Bean のコンテンツをラップするように構築されたクラスが原因でした。@JsonUnwrappedクラスがこのプロパティでBeanをマップできるように、コンテンツプロパティには注釈が付けられていResourceますが、jsonでは、Beanプロパティはプロパティと同じレベルに_linksあります。このアノテーションを使用すると、プロパティ名がラッパーおよび内部 Bean と競合する可能性があります。Resourceclass にはクラスidから継承されたResourceSupportプロパティがあり、このプロパティには悲しいことに によって注釈が付けられているため、ここではまさにそう@JsonIgnoreです。

この問題には回避策があります。MixInクラスから継承された新しいクラスを作成し、アノテーションでメソッドをResourceSupportMixinオーバーライドできます。getId()@JsonIgnore(false)

public abstract class IdResourceSupportMixin extends ResourceSupportMixin {

    @Override
    @JsonIgnore(false)
    public abstract Link getId();
}

IdResourceSupportMixin次に、クラスをに追加するだけですObjectMapper

mapper.addMixInAnnotations(ResourceSupport.class, IdResourceSupportMixin.class);

それは問題を解決するはずです。

于 2015-06-12T20:23:24.700 に答える
0

これは私のために働いた:

public class User extends ResourceSupport {

    @JsonIgnore(false)
    private Integer id;
    private String mail;
    private boolean enabled;

    // getters and setters
}

また、httpクライアントをPagedResources <User>代わりに返すように変更しますPagedResources<Resource<User>>

于 2016-12-23T17:00:28.067 に答える