空id属性时反序列化JSON与Spring HATEOAS的杰克逊和Jackson2HalModule

问题描述 投票:7回答:3

我的实体:

public class User {

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

    // getters and setters
}

文件test.json(从REST Web服务响应):

{
 "_embedded" : {
  "users" : [ {
    "id" : 1,
    "mail" : "[email protected]",
    "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());
    }
}

第二测试通过而不是第一。我不明白,因为在用户的id属性是唯一一人失踪(邮件和启用属性不为空)...

我有什么做的,解决这个问题?它是在杰克逊或Spring Jackson2HalModule一个错误?

您可以通过克隆我的弹簧HATEOAS叉repository和发射单元测试重现。

java jackson spring-data-rest spring-hateoas hal
3个回答
10
投票

其实,这是由于它是建立包裹你的bean的内容Resource类。内容属性被@JsonUnwrapped注释,以便Resource类可以在此属性,而在JSON,bean属性处于同一水平_links财产bean的映射。有了这个注释,就可以有属性名称与包装物和内豆冲突。正是这里的情况,因为Resource类有来自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);

它应该解决的问题。


0
投票

有了这个代码,你会发现所有的@Entity豆的更改配置揭露ID值:

 import java.util.LinkedList;
 import java.util.List;

 import javax.persistence.Entity;

 import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
 import org.springframework.core.type.filter.AnnotationTypeFilter;
 import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
 import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter;
 import org.springframework.stereotype.Component;

 import com.rvillalba.exampleApiHateoas.entity.Example;

 import lombok.extern.slf4j.Slf4j;

 @Component
 @Slf4j
 public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {

     @Override
     public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
         listMatchingClasses(Entity.class).forEach(entity -> config.exposeIdsFor(entity));
     }

     public List<Class> listMatchingClasses(Class annotationClass) {
         List<Class> classes = new LinkedList<Class>();
         ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(true);
         scanner.addIncludeFilter(new AnnotationTypeFilter(annotationClass));
         for (BeanDefinition bd : scanner.findCandidateComponents(Example.class.getPackage().getName())) {
             try {
                 classes.add(Class.forName(bd.getBeanClassName()));
             } catch (ClassNotFoundException e) {
                 log.error("listMatchingClasses problem", e);
             }
         }
         return classes;
     }

 }

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

© www.soinside.com 2019 - 2024. All rights reserved.