我正在尝试做一些我认为应该非常简单的事情.我有一个Question对象,设置有spring-boot,spring-data-rest和spring-hateoas.所有的基础工作都很好.我想添加一个自定义控制器,它返回一个List<Question>与我Repository的/questions网址完全相同的格式,以便两者之间的响应兼容.
这是我的控制器:
@Controller
public class QuestionListController {
@Autowired private QuestionRepository questionRepository;
@Autowired private PagedResourcesAssembler<Question> pagedResourcesAssembler;
@Autowired private QuestionResourceAssembler questionResourceAssembler;
@RequestMapping(
value = "/api/questions/filter", method = RequestMethod.GET,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody PagedResources<QuestionResource> filter(
@RequestParam(value = "filter", required = false) String filter,
Pageable p) {
// Using queryDSL here to get a paged list of Questions
Page<Question> page =
questionRepository.findAll(
QuestionPredicate.findWithFilter(filter), p);
// Option 1 - default resource assembler
return …Run Code Online (Sandbox Code Playgroud) spring spring-mvc spring-data spring-data-rest spring-hateoas
我按照这个例子,它允许发布一个唯一的Person对象.我想一个REST服务,我可以张贴的集合Person一次,如列表/名为任何集合Team众多Person只在一个通话对象.
我的意思是,我的问题并不完全是关于OneToMany你在REST请求中发送每个人的关系.本主题很好回答.
我想发送一组Person利用@RepositoryRestResourceSpring Data Rest的其他功能的对象.这是否可以使用Spring Data Rest或者我应该通过创建控制器来解决,接收列表并解析Team列表以插入每个Person?
我发现了这个功能请求,似乎回答说现在Spring Rest Data缺少我想要的东西,但我不确定.
在我的业务需求中,应用程序A会将一个订单列表发布到应用程序B,我必须将其保存在数据库中以供将来处理,因此,在阅读了Spring Data Rest并制作了一些示例后,我发现它的干净架构非常棒且非常适合对于我的要求,除了我没有弄清楚如何发布列表的事实.
我正在尝试了解如何在Spring HATEOAS中创建和修改链接.
例如,假设我有两个集合,一个在api/users,另一个在api/event.我想将用户api/user/56与事件api/event/21相关联.为了论证,这是多对多的 - 用户可以参加许多活动,一个活动可能有很多用户.
据我了解,这样做的另一种方法是使用URI作为主键,因此我可以将以下内容发布到api/user/56/events;
{
attends: "http://localhost:9090/api/event/21"
}
Run Code Online (Sandbox Code Playgroud)
然后端点需要能够解析该URL并提取ID(在本例中为21)和控制器(EventController.class),以便我可以持久保存.
问题1:这是在REST API方面处理Spring Hateoas中的关系的正确方法吗?
问题2:如何将控制器中的此URL解析为数据的可用句柄(例如,对相应控制器/方法的引用,主键等)
研究
RestTemplate可用于从请求映射方法内的控制器请求数据,如此;
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<EventResource> response = restTemplate.getForEntity(attendsUrl, EventResource.class);
EventResource eventResource = response.getBody();
Run Code Online (Sandbox Code Playgroud)
但是我不相信eventResource应该返回一个Id字段作为数据的一部分 - 它不是很安静,这将在API上公开.一种方法是使参数"includePK = true",但这感觉不对 - 它只是隐藏了问题.此外,服务器以这种方式向它自己的API发出请求的想法似乎很迂回.
更新
这里有一个未解决的问题https://github.com/spring-projects/spring-hateoas/issues/292.基于该问题的一些评论(由用户kevinconaway)松散地我已经创建了一个快速的util类,它提供了一个简单的解决方案:SpringHateoasUtils.解决方案归结为;
String mapping = DISCOVERER.getMapping(targetClass, targetMethod);
UriTemplate template = new UriTemplate(mapping);
//values is key/value map of parameters that the referenced method accepts
Map<String, String> values = uriTemplate.match(uri);
Run Code Online (Sandbox Code Playgroud)
SpringHateoasUtils使这个稍微好一点,但它仍然觉得它应该是一个功能.我将寻求在春季代码中得到一些东西 - 当它清楚地发生了什么时,我会回答这个问题.
我有两个具有双向关联的jpa实体.
Container包含项目集合的实体(oneToMany)Ommiting getter/setters
@javax.persistence.Entity
@Table(name = "CONTAINER")
public class Container implements Serializable {
private static final long serialVersionUID = -3288335692695653843L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "container", cascade = CascadeType.ALL)
private List<Item> items;
}
Run Code Online (Sandbox Code Playgroud)
实体Item包含对容器(ManyToOne)的引用,具有属性值和日期.提出二传手/吸气剂
@javax.persistence.Entity
@Table(name = "ITEM")
public class Item implements Serializable {
private static final long serialVersionUID = -758343957629274274L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
@Basic
private Long value;
@Basic
private …Run Code Online (Sandbox Code Playgroud) 现在,如果涉及复杂的聚合根,我无法获得Spring Data REST背后的概念.如果我正确理解域驱动设计(这是AFAIK弹簧数据的基本原理吗?),那么只能通过存储库公开聚合根.
比方说,我有两个类Post和Comment.两者都是实体,Post有一个@OneToMany List<Comment> comments.
因为Post显然是聚合根我想通过一个访问它PostRepository.如果我创建@RepositoryRestResource public interface PostRepository extends CrudRepository<Post, Long>REST访问Post工作正常.
现在comments是内联渲染,不作为子资源公开/posts/{post}/comments.只有当我引入一个CommentRepository(如果我想坚持使用DDD时我不应该这样做),就会发生这种情况.
那么如何在复杂的域对象中正确使用Spring Data REST?假设你必须检查所有注释都不包含超过X个字符.这显然是Post聚合根处理的一些不变量.你会把逻辑放在哪里Post.addComment()?如何将其他类公开为子资源,以便我可以在/posts/{post}/comments/{comment}不引入不必要的存储库的情况下访问?
我有一个非常简单的Spring Data REST项目,它有两个实体,Account和AccountEmail.有一个帐户存储库,但不适用于AccountEmail.帐户与AccountEmail有@OneToMany关系,并且AccountEmail没有反向链接.
更新:我认为这是一个错误.在Spring JIRA上被命名为DATAREST-781.我包括了一个演示项目和复制说明.
我可以使用以下调用创建一个帐户:
$ curl -X POST \
-H "Content-Type: application/json" \
-d '{"emails":[{"address":"nil@nil.nil"}]}' \
http://localhost:8080/accounts
Run Code Online (Sandbox Code Playgroud)
哪个回报:
{
"emails" : [ {
"address" : "nil@nil.nil",
"createdAt" : "2016-03-02T19:27:24.631+0000"
} ],
"_links" : {
"self" : {
"href" : "http://localhost:8080/accounts/1"
},
"account" : {
"href" : "http://localhost:8080/accounts/1"
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后我尝试使用JSONPatch为该帐户添加另一个电子邮件地址:
$ curl -X PATCH \
-H "Content-Type: application/json-patch+json" \
-d '[{ "op": "add", "path": "/emails/-","value":{"address":"foo@foo.foo"}}]' \
http://localhost:8080/accounts/1
Run Code Online (Sandbox Code Playgroud)
这会向集合中添加一个新对象,但由于某种原因,该地址为null:
{
"emails" : [ { …Run Code Online (Sandbox Code Playgroud)