我正在构建一个REST API.我有一个由bean组成的域模型,而不能扩展ResourceSupport.使用Spring-HATEOAS将它们作为资源公开的最佳方法是哪种?
如果不可能,这是在bean生成的JSON上包含链接的最佳方式?
我们正在构建一个类似于spring.io指南" 使用REST访问JPA数据 "的RESTful Web服务.要重现下面的示例输出,只需向Person添加ManyToOne -Relation,如下所示:
// ...
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String firstName;
private String lastName;
@ManyToOne
private Person father;
// getters and setters
}
Run Code Online (Sandbox Code Playgroud)
添加一些样本数据后的GET请求产生:
{
"firstName" : "Paul",
"lastName" : "Mustermann",
"_links" : {
"self" : {
"href" : "http://localhost:8080/people/1"
},
"father" : {
"href" : "http://localhost:8080/people/1/father"
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,鉴于保罗的父亲存有ID 2,我们期望的结果将是其关系的规范网址:
// ...
"father" : {
"href" : "http://localhost:8080/people/2"
}
// ...
Run Code Online (Sandbox Code Playgroud)
如果父对某些人是空的,这当然会引起问题(好吧,这在这里没有多大意义......;)),但在这种情况下,我们根本不想在JSON中呈现链接. …
我在我的REST控制器中使用了spring-data-common的PagedResourcesAssembler,我很高兴看到它甚至在响应中生成了下一个/上一个链接.但是,在我有其他查询参数(除了页面,大小,排序)的情况下,这些参数不包含在生成的链接中.我能以某种方式配置汇编程序以包含链接中的参数吗?
非常感谢,丹尼尔
对于其余接口,Spring MVC + RxJava使用从控制器返回 + DeferredResult。
我正在考虑将Hateoas支持添加到端点。自然的选择是Spring Hateoas。问题是春季Hateoas使用ThreadLocal,因此它不能在异步/多线程环境中工作。
有什么方法可以解决该约束?我不这么认为,但也许有人有任何建议。
有没有人使用其他API添加 其他端点 Hateoas支持?
谢谢。
也许另一个人偶然发现了这个话题并找到了一个很好的解决方案.在Spring HATEOAS项目的帮助下使用HATEOAS REST方法可以很好地将链接构建到资源.但最后,为了将扁平化资源映射回实体对象树,我需要反汇编链接并查询持久性后端.给出示例,我有一个实体Item,引用ItemType(多对一).item的自然键是ItemType外键和Item代码本身的组合.我使用链接构建器在ItemController中映射的URL是
@RequestMapping("/catalog/items/{itemTypeCode}_{itemCode}")
Run Code Online (Sandbox Code Playgroud)
现在,项目的唯一链接是http://www.sample.com/catalog/items/p_abc123
要反转此链接,我会做一些非常难看的字符串工作:
@Override
public Item fromLink(Link link) {
Assert.notNull(link);
String baseLink = linkTo(ColorTypeController.class).toString() + "/";
String itemTypeAndItemPart = link.getHref().replace(baseLink, "");
int indexOfSplit = itemTypeAndItemPart.indexOf('_');
ItemType itemType = new ItemType();
itemType.setCode(itemTypeAndItemPart.substring(0, indexOfSplit));
Item item = new Item();
item.setItemType(itemType);
item.setCode(itemTypeAndItemPart.substring(indexOfSplit + 1));
return item;
}
Run Code Online (Sandbox Code Playgroud)
而且我一直在想,如果没有更好的和更灵活的方法(小心任何查询字符串部分,这将打破代码)来做这个逆映射.我实际上不想从控制器中调用另一个MVC控制器,但它会很好,以某种方式利用调度程序servlet反汇编函数将URL解构为更方便使用的东西.对我有什么有用的提示?多谢 :)
我有一个带有请求参数的方法,并且正在尝试从另一个资源链接到此方法。我希望链接是这样的:
"rel":{
"href":".../resources{?param}",
"templated":true
}
Run Code Online (Sandbox Code Playgroud)
我尝试了以下操作但未成功:
//First attempt
resources.add(linkTo(methodOn(Controller.class).method(null)).withRel("rel")
//Second attempt
resources.add(linkTo(methodOn(Controller.class).method("{parameter}")).withRel("rel")
//Third attempt
resources.add(entityLinks.linkToCollectionResource(LinkedResource.class).withRel("rel");
Run Code Online (Sandbox Code Playgroud) 当我想用一个多态变量成员反序列化一个实体时,杰克逊抛出一个com.fasterxml.jackson.databind.JsonMappingException,抱怨缺少类型信息(...实际上存在于JSON中 - >参见示例).
Unexpected token (END_OBJECT), expected FIELD_NAME: missing property '@class' that is to contain type id (for class demo.animal.Animal)\n at [Source: N/A; line: -1, column: -1] (through reference chain: demo.home.Home[\"pet\"])"
Run Code Online (Sandbox Code Playgroud)
所有实际工作都由Spring HATEOAS的PagingAndSortingRepository完成.
我使用spring-boot V 1.2.4.RELEASE,这意味着jackson是V 2.4.6而Spring HATEOAS是V 0.16.0.RELEASE.
例:
我家里有一只宠物:
@Entity
public class Home {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@OneToOne(cascade = {CascadeType.ALL})
private Animal pet;
public Animal getPet() {
return pet;
}
public void setPet(Animal pet) {
this.pet = pet;
}
}
Run Code Online (Sandbox Code Playgroud)
宠物是动物 - …
在自定义Spring MVC控制器中支持HTTP PATCH的最佳实践是什么?特别是在使用HATEOAS/HAL时?是否有更简单的方法来合并对象,而无需检查请求json(或编写和维护DTO)中是否存在每个字段,理想情况下是自动解组资源链接?
我知道Spring Data Rest中存在此功能,但是可以将其用于自定义控制器吗?
spring spring-mvc spring-data-rest spring-hateoas spring-boot
我正在使用派对模型:
@Entity
@Inheritance(strategy=...)
@JsonTypeInfo(use= JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@DiscriminatorColumn(name = "type")
public abstract class Party {
@Column(updatable = false, insertable = false)
private String type;
...
}
@Entity
public class Individual extends Party {
...
}
@Entity class Organization extends Party {
...
}
Run Code Online (Sandbox Code Playgroud)
Spring Data REST响应如下:
{
"_embedded": {
"organizations": [
{
"type":"Organization",
"name": "Foo Enterprises",
"_links": {
"self": {
"href": "http://localhost/organization/2"
},
"organization": {
"href": "http://localhost/organization/2"
}
}
}
],
"individuals": [
{
"type":"Individual",
"name": …Run Code Online (Sandbox Code Playgroud) 这个代表性例子:
有一个管理员用户A和一个正常用户B.
A可以看到并改变x,y,z.
只有当z具有特定值时,B才能看到x,y(不是z)并改变x(不是y,z).
public class U{
private Long id;
private String x;
private String y;
private String z;
[... getter and setter]
}
Run Code Online (Sandbox Code Playgroud)
问题是如何通过Spring Data Rest实现这一点.ResourceProcessor似乎只适用于链接,而Validator无法查看用户是否更改了字段...
我已经实现了基于属性的访问控制,因此我可以轻松地在数据库中创建和保存角色,权限和策略(使用SpEl),以确定谁可以查看和更改特定字段.
更新1
我添加了一个Jackson BeanSerializerModifier来过滤属性,但是有一个问题是我不知道z的原始(数据库)值,并且无法检查B是否有权更改x.
更新2
我添加了一个自定义Jackson Std(De)Serializer,但现在我不能动态地将它用于每个实体,因为我必须为每个实体编写完整的(de)序列化器.
更新3
经过两周的努力尝试解决这个问题很多次,我将尝试将过滤器集成到SDR中.
更新4
当我为PUT和PATCH请求添加了一个过滤器时,我重新认识了https://jira.spring.io/browse/DATAREST-373和https://jira.spring.io/browse/DATAREST-428将是更好的解决方案.现在我要为他们找到解决方案.
spring-security jackson spring-data-rest spring-hateoas spring-boot
spring-hateoas ×10
spring-boot ×5
spring ×4
spring-mvc ×4
jackson ×2
hateoas ×1
inheritance ×1
java ×1
polymorphism ×1
rel ×1
rest ×1