【问题标题】:Spring Data Rest post to collection end-pointSpring Data Rest 发布到收集端点
【发布时间】:2015-08-13 21:03:44
【问题描述】:

我有一个我认为相当简单的问题,但经过数小时的搜索后可以找到解决方案,而且我对 Spring 还比较陌生,所以请原谅任何不正确的术语或明显的错误。

我有一个事件对象,它与预订对象具有一对多的关系,如下所示

事件:

@Entity
public class Event {

   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   private Long eventId;
   private Date start;
   private Date end;
   private String title;

   @OneToMany(mappedBy="event")
   private Set<Booking> Bookings;

   protected Event() {
       // for JPA
   }
   // Getters and setters omitted for brevity
}

预订:

@Entity
public class Booking {  

   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   private Long bookingId;
   private String title;
   private String contact;

   @ManyToOne
   @JoinColumn(name="event_id", nullable=false)
   private Event event; 

   public DiveBooking() {
      // for JPA
   }
   // Getters and setters omitted for brevity
}

EventRepository:

public interface DiveEventRepository extends JpaRepository<Event, Long> {

List<Event> findByStartBetweenOrEndBetween(
        @Param("start") Date startStartTime,
        @Param("end") Date startEndTime,
        @Param("start") Date endStartTime,
        @Param("end") Date endEndTime);
}

BookingRepository

public interface BookingRepository extends JpaRepository<Booking, Long>{

}

这些暴露端点:

/休息/事件 /休息/预订

一个事件的实例为:

/rest/events/1

预订:

/rest/events/1/bookings

我想要实现的是创建一个新的预订并将其与一个活动相关联。我的数据模型将 event_id 作为必填字段(因为没有事件,预订就毫无意义),并且我的每一条信息都说我应该能够发布一个新的预订对象到 /rest/events /1/bookings 并让它创建一个与 id 为 1 的事件关联的新预订对象。但是,每当我尝试发布到该 URI 时,我都会收到以下消息:

加载资源失败:服务器响应状态为 405 (方法不允许)

在检查端点 /rest/events/1/bookings 的标头时,我可以看到该帖子是允许的:

访问控制允许方法:POST、GET、OPTIONS、DELETE

所以现在我完全糊涂了,不知所措。感觉我应该能够以这种方式创建预订,而且我真的不想走必须创建孤立预订然后将其与事件相关联的路线,因为它会破坏我的数据模型(必须使event_id null in booking),并且无法对事务中的操作执行这些操作(有吗?)。我已经尝试对我模型中的其他集合进行类似的操作,并且他们也发布了拒绝,所以我猜测这与我的 spring 数据休息配置有关,但我不知道是什么。

在此先感谢您提供任何帮助或指点。

【问题讨论】:

标签: spring spring-data-jpa spring-data spring-data-rest


【解决方案1】:

这不是你的弹簧休息配置的问题,如下面的thread。我的理解是 Spring 休息不支持您尝试做的方式

鉴于here,您必须使用以下内容来更新资源,这意味着您必须更新模型。

curl -v -X PUT -H "Content-Type: text/uri-list" -d "http://localhost:8080/events/1" http://localhost:8080/bookings/1/event

【讨论】:

  • 我认为发布者想要创建一个新的预订,并将其链接到单个交易中的现有活动。使用更新资源机制需要先创建booking,再链接,这是两个事务。
  • 从我所链接的答案的讨论中,我的理解是不可能做问题中提出的问题
  • 我已经看过提到的线程,它并没有真正回答我想要做什么。正如 Jay 评论的那样,我希望能够在一笔交易中做到这一点,因为所有信息都可用(引用的 id)。此外,还有一个问题是为什么我收到不允许 POST 的消息,尽管响应标头说允许 POST。
  • 据我了解,您正在尝试做一些不受支持的事情。就 POST 而言,我认为这是需要在他们没有做的框架中进行更改的事情
【解决方案2】:

/rest/events/1/bookings 是一个关联资源。它只能处理 URI。

如果您想创建一个新的Booking,那么发布到/rest/bookings 有点合乎逻辑。 event 字段应包含关联事件的 URI,例如/rest/events/1.

顺便说一句:Access-Control-Allow-Methods 不一定表示 API 支持 的方法。它仅与跨域浏览器请求相关,并且每个 URL 的值很可能相同。

【讨论】:

  • 谢谢,我想我已经尝试了所有方法,但在发布到 /rest/bookings 时,包括将事件对象放入事件字段并将事件 uri 放入预订时的 _links 中。
【解决方案3】:

将您的新预订发布至:/rest/bookings

{
  "title": "my booking title",
  "contact": "my contact",
  "event": "http:localhost:8080/rest/events/1"
}

正如其他人已经回答的那样,您可以创建一个预订,然后通过对 /rest/events/1/bookings 执行 PUT (text/uri-list) 将其关联到一个事件,但我认为上述方法很多更明智。

【讨论】:

  • 非常感谢您提供“text/uri-list”提示。这对我有用,尽管当前的 Spring 文档应该发送 Content-Type:“application/json”。但它没有指定要发送的任何 JSON 格式。
猜你喜欢
  • 2015-07-06
  • 2016-07-11
  • 2018-07-23
  • 2018-11-14
  • 2016-08-19
  • 2015-10-01
  • 2018-12-31
  • 2015-12-23
  • 1970-01-01
相关资源
最近更新 更多