Return 来自 Spring 数据 REST 的 JSON 响应中的 ID

Return IDs in JSON response from Spring Data REST

我有一个实体

@Entity
@Table(name = "books")
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    @Column(name = "id", unique = true, nullable = false)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "name")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

我是这样初始化的

@PostConstruct
public void init() {
    List<String> newFiles = this.listFiles();
    newFiles.forEach(filename -> {
        Book book = new Book();
        book.setName(filename);

        dbRepository.save(book);
    });
}

如果我将 save 的结果设置为 Book 的实例,我可以获得 id 而不是 null — 所以 id创建的很好。

我定义了一个存储库

@RepositoryRestResource
public interface IBooksRepository extends CrudRepository<Book, Long> {
}

我想用它来获取和设置数据到数据库中的 books table。

当我尝试使用 curl localhost:8080/books 访问我的 repository rest 时,我收到此响应

{
   "_embedded":{
      "books":[
         {
            "name":"simple-file.txt",
            "_links":{
               "self":{
                  "href":"http://localhost:8080/books/1"
               },
               "book":{
                  "href":"http://localhost:8080/books/1"
               }
            }
         }
      ]
   },
   "_links":{
      "self":{
         "href":"http://localhost:8080/books"
      },
      "profile":{
         "href":"http://localhost:8080/profile/books"
      }
   }
}

books 元素仅 returns name。我怎样才能做到 return idname 处于同一水平?

Spring Data Rest 默认隐藏 ID,为了在JSON中包含它,您必须为您的实体手动配置它。根据您的 spring 版本,您可以提供自己的配置(旧):

@Configuration
public class ExposeEntityIdRestConfiguration extends RepositoryRestMvcConfiguration {

    @Override
    protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.exposeIdsFor(Book.class);
    }
}

...或注册一个 RepositoryRestConfigurer(当前):

@Component
public class ExposeEntityIdRestMvcConfiguration extends RepositoryRestConfigurerAdapter {

  @Override
  public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
    config.exposeIdsFor(Book.class);
  }
}

有关详细信息,请参阅 Spring Data Rest documentation

现在有一个静态方法 RepositoryRestConfigurer.withConfig 可以执行与上述相同的操作。见 javadoc:

Convenience method to easily create simple {@link RepositoryRestConfigurer} instances that solely want to tweak the {@link RepositoryRestConfiguration}.

我在其中一个 their integration tests

中找到了用法

因此,以下方法目前是最新的:

@Bean
public RepositoryRestConfigurer repositoryRestConfigurer()
{
    return RepositoryRestConfigurer.withConfig(config -> {
        config.exposeIdsFor(Book.class);
    });
}
@Component
public class RestConfig implements RepositoryRestConfigurer {

    @Override
      public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.exposeIdsFor(Book.class);
        //config.exposeIdsFor(Library.class);
      }

}

这是个好方法。

@Projection(name = "customBook", types = { Book.class }) 
public interface CustomBook {
 
    @Value("#{target.id}")
    long getId(); 
    
}

信用:https://www.baeldung.com/spring-data-rest-projections-excerpts

已接受的答案覆盖了已弃用的方法。这是更新后的版本:

@Component
public class RestConfig implements RepositoryRestConfigurer {

    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
        config.exposeIdsFor(Book.class);
    }
}

另一种方法是在您的 @SpringBootApplication 注释 class:

中实施 RepositoryRestConfigurer
@SpringBootApplication
public class MyApplication implements RepositoryRestConfigurer {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
        config.exposeIdsFor(Book.class);
    }

}

这是适用于所有实体的解决方案

    @Autowired
    private EntityManager entityManager;
    
    @Bean
    public RepositoryRestConfigurer repositoryRestConfigurer() {
        return RepositoryRestConfigurer.withConfig(config -> config.exposeIdsFor(entityManager.getMetamodel().getEntities().stream().map(Type::getJavaType).toArray(Class[]::new)));
    }