从 Spring Data REST 返回 JSON 响应中的 ID
Posted
技术标签:
【中文标题】从 Spring Data REST 返回 JSON 响应中的 ID【英文标题】:Return IDs in JSON response from Spring Data REST 【发布时间】:2017-10-18 04:52:49 【问题描述】:我有一个实体
@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 boot @ResponseBody doesn't serialize entity id的可能重复 【参考方案1】: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。
【讨论】:
嗯,RepositoryRestMvcConfiguration
中没有方法configureRepositoryRestConfiguration
你用的是哪个版本的spring data rest?
你知道默认关闭的原因吗?看起来backbone.js需要传播id才能完全发挥作用,例如集合.get(id)
你为什么先用@Configuration
,再用@Component
?
RepositoryRestConfigurerAdapter
现已弃用,您必须直接实现 RepositoryRestConfigurer
。【参考方案2】:
现在有一个静态方法RepositoryRestConfigurer.withConfig
可以做与上面相同的事情。见javadoc:
轻松创建简单的 @link RepositoryRestConfigurer 实例的便捷方法,这些实例只想调整 @link RepositoryRestConfiguration。
我在their integration tests 之一中找到了用法
因此,截至目前,以下方法将是最新的:
@Bean
public RepositoryRestConfigurer repositoryRestConfigurer()
return RepositoryRestConfigurer.withConfig(config ->
config.exposeIdsFor(Book.class);
);
【讨论】:
【参考方案3】:@Component
public class RestConfig implements RepositoryRestConfigurer
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config)
config.exposeIdsFor(Book.class);
//config.exposeIdsFor(Library.class);
【讨论】:
感谢您的贡献!您可能希望通过引用为您的答案添加描述以使其更清晰。有关指南,请参阅 ***.com/help/how-to-answer。【参考方案4】:这是一个好方法。
@Projection(name = "customBook", types = Book.class )
public interface CustomBook
@Value("#target.id")
long getId();
信用:https://www.baeldung.com/spring-data-rest-projections-excerpts
【讨论】:
【参考方案5】:接受的答案会覆盖已弃用的方法。这是更新版本:
@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);
【讨论】:
【参考方案6】:这是适用于所有实体的解决方案
@Autowired
private EntityManager entityManager;
@Bean
public RepositoryRestConfigurer repositoryRestConfigurer()
return RepositoryRestConfigurer.withConfig(config -> config.exposeIdsFor(entityManager.getMetamodel().getEntities().stream().map(Type::getJavaType).toArray(Class[]::new)));
【讨论】:
以上是关于从 Spring Data REST 返回 JSON 响应中的 ID的主要内容,如果未能解决你的问题,请参考以下文章
如何配置 Spring-Data-Rest 以仅返回登录用户拥有的数据
Spring Data Rest with Spring Security - 按当前用户查找所有内容
是否有适用于 JPA、spring-data、spring-data-rest 的通用 REST 查询语言
Spring Data REST 默认对 JSON 隐藏技术实体字段(@Version、@Id)。如何将它们作为通常的属性返回?