Spring Data JPA和PUT请求创建

时间:2016-09-27 00:12:20

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

所以我正在尝试使用Spring Data JPA使用存储库接口来创建一些休息服务。但是我不想尝试做某事而不必创建自定义控制器。

假设此服务仅接受PUT和GET请求。 PUT请求用于创建和更新资源。所以ID是客户端生成的。

实体和存储库将是这样的:

@Entity
public class Document {
    @Id
    private String name;
    private String text;
        //getters and setters
}

@RepositoryRestResource(collectionResourceRel = "documents", path = "documents")
public interface DocumentRepository extends PagingAndSortingRepository<Document, String> {
}

当我尝试使用以下正文发出PUT请求@ localhost:8080 / documents / foo时:

{ 
  "text": "Lorem Ipsum dolor sit amet"
}

我收到此消息:

{
  "timestamp": 1474930016665,
  "status": 500,
  "error": "Internal Server Error",
  "exception": "org.springframework.orm.jpa.JpaSystemException",
  "message": "ids for this class must be manually assigned before calling save(): hello.Document; nested exception is org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): hello.Document",
  "path": "/documents/foo"
}

所以我必须寄身:

{ 
  "name": "foo",
  "text": "Lorem Ipsum dolor sit amet"
}

所以它返回201 Created with

{
  "text": "Lorem Ipsum dolor sit amet",
  "_links": {
    "self": {
      "href": "http://localhost:8080/documents/foo"
    },
    "document": {
      "href": "http://localhost:8080/documents/foo"
    }
  }
}

是否可以在不必在json体内发送id(名称字段)的情况下制作PUT?既然我已经在URI中发送了它?

我知道我可以使用/documents/{document.name}创建一个RestController和一些请求映射,并在保存之前使用它来设置名称字段,但我想知道是否有任何注释或其他内容。

1 个答案:

答案 0 :(得分:2)

您可以在保存之前定义@HandleBeforeCreate / @HandleBeforeSave方法来更改模型:

@Component
@RepositoryEventHandler(Document.class)
public class DocumentBeforeSave {
    @Autowired
    private HttpServletRequest req;

    @HandleBeforeCreate
    public void handleBeforeSave(Document document) {
        if("PUT".equals(req.getMethod())){
            String uri = req.getRequestURI();
            uri = uri.substring(uri.lastIndexOf('/') + 1);
            document.setName(uri);
        }
    }
}
  • 由于正文不包含任何ID(此时),POSTPUT都会触发@HandleBeforeCreate方法(如果正文包含idPUT请求宁可触发@HandleBeforeSave)。
  • 在分配RequestMethod之前,我们需要检查PUT是否为id(为了保持POST机构不变)。
  • HttpServletRequest作为代理注入,可供多个线程使用。阅读本文:Can't understand `@Autowired HttpServletRequest` of spring-mvc well