从 Spring Data REST 返回 JSON 响应中的 ID



我有一个实体

@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表中。

当我尝试使用 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元素仅返回name。我怎样才能让它也返回id,与name处于同一水平?

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 文档。

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

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

另一种方法是在@SpringBootApplication注释类中实现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);
    }
}

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

轻松创建简单的 {@link RepositoryRestConfigurer} 实例的便捷方法,这些实例只想调整 {@link RepositoryRestConfiguration}。

我在他们的一个集成测试中找到了用法

因此,到目前为止,以下方法将更加最新:

@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);
      }
}

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

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

这是一个很好的方法。

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

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

它帮助了我。 Spring Data Rest hides the ID by default, in order to have it in the JSON you have to manually configure that for your entity

最新更新