Spring REST重用嵌套的请求映射
问题描述:
我们有一个REST API,用于一些评论。目前,最有趣的URI是:Spring REST重用嵌套的请求映射
GET /products/1/comments // get all comments of product 1
GET /products/1/comments/5 // get the 5th comment of product 1
GET /products/1/comments/5/user // get the user of the 5th comment
GET /products/1/comments/latest // get the latest comment of product 1
GET /products/1/comments/latest/user // get the user of the latest comment
此外,您可以直接访问评论
GET /comments/987 // get the comment with id 987
GET /comments/987/user // get the user of comment with id 987
所以,我们有两个@RestController
:
@RestController
@RequestMapping("/products/{productId}")
public class ProductsCommentsResource {
@GetMapping(value = "/comments")
public ResponseEntity<?> getComments(@PathVariable Long productId){
// get all products...
}
@GetMapping(value = "/comments/{commentNr}")
public ResponseEntity<?> getComment(@PathVariable Long productId, @PathVaraible Long commentNr){
// get comment with number commentNr of product productId
}
@GetMapping(value = "/comments/{commentNr}/user")
public ResponseEntity<?> getCommentUser(@PathVariable Long productId, @PathVaraible Long commentNr){
// get the user of comment with commentNr of productId
}
@GetMapping(value = "/comments/latest")
public ResponseEntity<?> getLatestComment(@PathVariable Long productId){
// get latest commentNr and call getComment(productId, commentNr)
}
@GetMapping(value = "/comments/latest/user")
public ResponseEntity<?> getLatestCommentUser(@PathVariable Long productId){
// get latest commentNr and call getCommentUser(productId, commentNr)
}
}
@RestController
@RequestMapping("/comments")
public class CommentsResource {
@GetMapping(value = "/{commentId}")
public ResponseEntity<?> getComment(@PathVaraible Long commentId){
// get comment id commentId
}
@GetMapping(value = "/{commentId}/user")
public ResponseEntity<?> getCommentUser(@PathVaraible Long commendId){
// get the user of comment with id commentId
}
}
所以只有与该latest
被替换关键字为“获取最后评论Nr并用此评论ID调用相应的方法”
这只是一个摘录,除了用户,评论还有大约30个子和子子资源(包括POST,DELETE等方法)。 因此,我们有三次或多或少的一切。
因此,很明显,我们需要改进这一点,删除重复的代码等。 这个想法是“封装”评论资源,并使用类注解的@RequestMapping
来重复使用。
我们想过像mechnism:
- 的
/products/1/comments/latest/user
叫 - 呼叫被截获和产品1的“最新”解析为commentId
- 呼叫将被重定向到```/评论/ {} commendId /用户
因此,我们需要有一些重定向 - /products/1/comments/latest[what ever]
到/comments/{commentId}[what ever]
- /products/1/comments/5[what ever]
也为/comments/{commentId}[what ever]
和/ comments/{commentId}将是唯一的实现。
但是,我们并没有找到合适的春天文档什么...
答
你可以在你的控制器的@RequestMapping
添加额外的URL路径前缀。
@RequestMapping(value = { "/products/{productId}", "/" })
这意味着,你可以删除CommentsResource
控制器,你就可以在访问相同的资源:
/products/1/comments/5
,并在
/comments/5
举例来说,在这里:
@GetMapping(value = "/comments/{commentNr}")
public ResponseEntity<?> getComment(@PathVariable Long productId, @PathVaraible Long commentNr){
// get comment with number commentNr of product productId
}
明显的问题是productId
路径变量。如果您使用的是Java 8,那么使用Optional
即可很容易解决:
@GetMapping(value = "/comments/{commentNr}")
public ResponseEntity<?> getComment(@PathVariable Optional<Long> productId, @PathVaraible Long commentNr){
// get comment with number commentNr of product productId
// Check whether productId exists
}
谢谢。始终认为路径变量不能是可选的。我会试一下 – Indivon