Spring引导休息服务,如何让它将链接封装为属性?

问题描述 投票:6回答:2

这里的第一个问题所以要温柔:)

我有一个JPA项目,我希望将其公开为REST。到目前为止我做到了这一点:

我的实体:

@Entity
public class SignUpSheet {
    @Id
    @GeneratedValue
    private Long id;

    @Column
    private String name;

    @Column
    private String description;

    @Column
    @Temporal(TemporalType.TIMESTAMP)
    private Date dateTime;

    @ManyToOne
    private User parent;

    @OneToMany
    private List<Volunteer> volunteers;

    //getter and setters
}

一切都很好,我打电话给我的pom添加了spring-boot-starter-data-rest,现在我得到了一个服务。这是我回来的JSON。

http://localhost:8080/api-0.1.0/signUpSheets/1

{
  "name": "Auction",
  "description": "My First Sign Up Sheet",
  "dateTime": "2015-04-22T03:47:12.000+0000",
  "volunteers": [
   {
    "role": "Bringing stuff",
    "comments": "I have comments!"
   }
   ], 
  "endpoint": "/signUpSheets",
  "_links": {
    "self": {
      "href": "http://localhost:8080/api-0.1.0/signUpSheets/1"
    },
    "parent": {
      "href": "http://localhost:8080/api-0.1.0/signUpSheets/1/parent"
    },
    "user": {
      "href": "http://localhost:8080/api-0.1.0/signUpSheets/1/user"
    } 
  }
}

超!几乎是我所期待的。现在我使用Spring的RestTemplate调用我的服务,这就是我被困的地方。当它返回到SignUpSheet对象时,它会拉入大部分对象,但ID字段为null(这是有道理的,因为Json中没有ID字段,只是一个自引用)并且所有OneToMany和ManyToOne对象都是null(我假设出于同样的原因)。

我的问题是:我如何告诉Spring Hateoas将ID添加到json或告诉Jackson如何将ID编组到ID字段中?此外,我如何获得链接?我是不是应该编组回JPA实体,而是为SignUpSheet创建另一个POJO(我希望避免出于重复目的,但如果因为某些原因我缺少必要/可取的话可以讨论)。我将Jackson2HalModule添加到我的ObjectMapper中,但是它是否存在似乎无关紧要。

@Bean
@Primary
public ObjectMapper objectMapper() {
    ObjectMapper o = new ObjectMapper();
    o.registerModule(new Jackson2HalModule());
    return o;
}

在此先感谢您的帮助!

=======================================================

解:

第一步,阅读手册:)

所以我发现我需要在新创建的DTO上扩展ResourceSupport。做完了。但我没有回复链接!好像我需要将Jackson2HalModule添加到RestTemplate上的对象映射器,如下所示:

    ObjectMapper o = new ObjectMapper();
    o.registerModule(new Jackson2HalModule());
    MappingJackson2HttpMessageConverter c = new MappingJackson2HttpMessageConverter();
    c.setObjectMapper(o);
    restTemplate.getMessageConverters().add(0, c);

所以我想我会延伸RestTemplate和@Component,我应该对任何HATEOAS资源都有好处。

spring-boot spring-data-jpa spring-data-rest spring-hateoas
2个回答
3
投票

我认为你不应该试图将JSON反序列化回你的JPA实体。 JPA实体与应用程序的数据库紧密相关,应被视为服务器的实现细节。相反,我建议映射到专门建模在REST API上的类型,而不是映射到数据库的结构和JPA的使用。

您正在使用强大包含超媒体的Spring Data REST。这意味着客户端应使用URI来标识资源和链接以在它们之间导航。例如,在客户端,注册表已经有ID;这是响应中href链接的self。因此,无需从JPA实体公开ID。实际上,这样做会暴露客户不需要了解的应用程序的实现细节。

Spring Data REST不是尝试填充响应中的所有属性,而是提供链接。例如,要访问注册表的父级,您应该从响应中提取href链接的parent,并对URI执行GET请求。


0
投票

您需要扩展RepositoryRestConfigurerAdapter来告诉您需要导出Id,例如:

public class RepositoryConfig extends RepositoryRestConfigurerAdapter {
    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.exposeIdsFor(SignUpSheet.class);
 }
}
© www.soinside.com 2019 - 2024. All rights reserved.