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 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 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)));
}
我有一个实体
@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 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 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)));
}