所以我正在尝试使用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和一些请求映射,并在保存之前使用它来设置名称字段,但我想知道是否有任何注释或其他内容。
答案 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);
}
}
}
POST
和PUT
都会触发@HandleBeforeCreate
方法(如果正文包含id
, PUT
请求宁可触发@HandleBeforeSave
)。RequestMethod
之前,我们需要检查PUT
是否为id
(为了保持POST
机构不变)。HttpServletRequest
作为代理注入,可供多个线程使用。阅读本文:Can't understand `@Autowired HttpServletRequest` of spring-mvc well