java spring REST 中的子资源
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40328835/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sub-Resources in spring REST
提问by prranay
I'm trying to build messanger app.
我正在尝试构建信使应用程序。
I've to call CommentResource from MessageResource.
我必须从 MessageResource 调用 CommentResource。
I want separate MessageResources and CommentResources.
我想要单独的 MessageResources 和 CommentResources。
I'm doing something like this :
我正在做这样的事情:
MessageResource.java
消息资源.java
@RestController
@RequestMapping("/messages")
public class MessageResource {
MessageService messageService = new MessageService();
@RequestMapping(value = "/{messageId}/comments")
public CommentResource getCommentResource() {
return new CommentResource();
}
}
CommentResource.java
评论资源.java
@RestController
@RequestMapping("/")
public class CommentResource {
private CommentService commentService = new CommentService();
@RequestMapping(method = RequestMethod.GET, value="/abc")
public String test2() {
return "this is test comment";
}
}
I want
我想
http://localhost:8080/messages/1/comments/abc
http://localhost:8080/messages/1/comments/abc
to return "this is test comment".
返回“这是测试评论”。
Any Idea??
任何的想法??
PS: In a simple word, I want to know JAX-RS sub-resource
equivalent implementation in spring-rest
PS:简单来说,我想知道JAX-RS sub-resource
在spring-rest
回答by Tapan
In Spring boot, we can implement JAX-RS subresource concept using @AutowiredSpring Concept. Create an object of your child resource class and Spring will initialize at runtime and return that object. Don't create an Object manually. like: Above mention scenario
在 Spring boot 中,我们可以使用@AutowiredSpring Concept实现 JAX-RS 子资源概念。创建子资源类的对象,Spring 将在运行时初始化并返回该对象。不要手动创建对象。像:上面提到的场景
- MessageResource.java
@RestController
@RequestMapping("/messages")
public class MessageResource {
MessageService messageService = new MessageService();
@Autowired
@Qualifier("comment")
CommentResource comment;
@RequestMapping(value = "/{messageId}/comments")
public CommentResource getCommentResource() {
return comment;
}
}
- CommentResource.java
@RestController("comment")
@RequestMapping("/")
public class CommentResource {
private CommentService commentService = new CommentService();
@RequestMapping(method = RequestMethod.GET, value="/abc")
public String test2() {
return "this is test comment";
}
}
Now it will work like sub-resource
http://localhost:8080/messages/1/comments/abc
You can send any type of request.
回答by alexbt
Your url (http://localhost:8080/messages/1/comments/abc) suggests that comments are nested in the message. Your controller should look like this:
您的 url ( http://localhost:8080/messages/1/comments/abc) 表明评论嵌套在消息中。您的控制器应如下所示:
@RestController
@RequestMapping("/messages")
public class MessageResource {
@RequestMapping(value = "/{messageId}")
public String getCommentResource(@PathVariable("messageId") String messageId) {
//test
return messageId;
}
@RequestMapping(value = "/{messageId}/comments/{commentsContent}")
public String getCommentResource(
@PathVariable("messageId") String messageId,
@PathVariable("commentsContent") String commentsContent) {
//test
return messageId + "/" + commentsContent;
}
}
I'm not entirely sure what you wish to do in your MessageResource class, but the idea is there.
我不完全确定您希望在 MessageResource 类中做什么,但想法就在那里。
Rest - HTTP methods
休息 - HTTP 方法
For now, these use are Get requests. You should however consider using the appropriate Http Method:
目前,这些用途是 Get 请求。但是,您应该考虑使用适当的 Http 方法:
- Get: read a resource
- Post: create a resource
- Put: update
- Delete: delete :)
- 获取:读取资源
- 帖子:创建资源
- 放置:更新
- 删除:删除 :)
Take a look at this: http://www.restapitutorial.com/lessons/httpmethods.html
看看这个:http: //www.restapitutorial.com/lessons/httpmethods.html
Example with Post:
帖子示例:
@RequestMapping(method=RequestMethod.POST, value = "/{messageId}/comments/{commentsContent}")
public ResponseEntity<String> getCommentResource(
@PathVariable("messageId") String messageId,
@RequestBody Comment comment) {
//fetch the message associated with messageId
//add the comment to the message
//return success
return new ResponseEntity<String>(HttpStatus.OK);
}
Class names
班级名称
Also, I would personally rename these classes to MessageController and CommentController.
此外,我个人会将这些类重命名为 MessageController 和 CommentController。
Edit after comments - Split controllers
评论后编辑 - 拆分控制器
You can just literally split the controllers (closer to what you had):
您可以直接拆分控制器(更接近您拥有的):
@RestController
@RequestMapping("/messages")
public class MessageResource {
@RequestMapping(value = "/{messageId}")
public String getCommentResource(@PathVariable("messageId") String messageId) {
//test
return messageId;
}
}
@RestController
@RequestMapping("/messages")
public class CommentResource {
@RequestMapping(value = "/{messageId}/comments/{commentsContent}")
public String getCommentResource(
@PathVariable("messageId") String messageId,
@PathVariable("commentsContent") String commentsContent) {
//test
return messageId + "/" + commentsContent;
}
}
回答by Paul Murphy
What you are looking for is supported in JAX-RS
implementations such as Jerseyand is called Sub-Resources
. When building large APIs which become nested in nature, sub resources are an extremly useful feature.
您正在寻找的内容在Jersey等JAX-RS
实现中得到支持,并被称为. 在构建本质上嵌套的大型 API 时,子资源是一个非常有用的功能。Sub-Resources
Spring Boot default rest implementation is not a JAX-RS
but SpringMVC
. Whilst it is possible to use Jersey in Spring Boot, it's a bit involved trying to set it up, and doesn't appear to be well used/supported in the community.
Spring Boot 默认的 rest 实现不是一个JAX-RS
but SpringMVC
。虽然可以在 Spring Boot 中使用 Jersey,但尝试设置它有点复杂,并且在社区中似乎没有得到很好的使用/支持。
On a side note, DropWizardis awesome!
顺便说一句,DropWizard很棒!
回答by Jin Kwon
I'm also being, forcedly, migrated from JAX-RS to Spring-MVC.
我也被迫从 JAX-RS 迁移到 Spring-MVC。
I'm still looking for an elegant way to do this just like I do with JAX-RS.
我仍在寻找一种优雅的方式来做到这一点,就像我对 JAX-RS 所做的那样。
I'm sharing what I've tried.
我正在分享我尝试过的东西。
@RestController
@RequestMapping("parents")
public class ParentsController {
@RequestMapping(method = RequestMethod.GET,
produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<List<Parent>> read() {
}
@RequestMapping(method = RequestMethod.GET,
path = "/{id:\d+}",
produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<Parent> read(@PathVariable("id") final long id) {
}
}
And the ChildrenController
.
而ChildrenController
.
@RestController
@RequestMapping("/parents/{parentId:\d+}/children")
public class ChildrenController {
@RequestMapping(method = RequestMethod.GET,
produces = {MediaType.APPLICATION_JSON_VALUE})
@ResponseBody
public List<Child> read(@PathVariable("parentId") final long parentId) {
}
@RequestMapping(method = RequestMethod.GET, path = "/{id:\d+}",
produces = {MediaType.APPLICATION_JSON_VALUE})
@ResponseBody
public Child read(@PathVariable("parentId") final long parentId,
@PathVariable("id") final long id) {
}
}
Two problems I've found,
我发现了两个问题,
@PathVariable
is not applicable on fields.
@PathVariable
不适用于字段。
I just can't do @PathVariable("parentId") private long parentId;
我就是做不到 @PathVariable("parentId") private long parentId;
No free will for multiple mapping for ChildrenController
没有自由意志进行多重映射 ChildrenController
A beauty of JAX-RS is that we can map ChildrenController
for different paths like even the ChildrenController
has a class-level @Path
with it.
JAX-RS 的一个优点是我们可以映射ChildrenController
不同的路径,就像它ChildrenController
有一个类级别@Path
一样。
@Path("/children");
public class ChildrenResource {
}
@Path("/parents")
public class ParentsResource {
@Path("/{id}/children")
public ChildrenResource resourceChildren() {
}
}
/children
/parents/{id}/children
回答by Dherik
Just create two classes and use a constantto refer the children resource with parent resource. This helps to make a link between the two classes and make the developer understand the relationship between them.
只需创建两个类并使用一个常量来引用带有父资源的子资源。这有助于在两个类之间建立联系,并使开发人员了解它们之间的关系。
So:
所以:
@RequestMapping(value= MessageController.URL)
public class MessageController {
public static final String URL= "/messages";
}
And:
和:
@RequestMapping(value = MessageController.URL + "/{idMessage}/comments")
public class CommentController {
}
You can also split the controllers in different packages, showing this hierarchy in your package organization too:
您还可以将控制器拆分为不同的包,在您的包组织中也显示此层次结构:
com.company.web.message.MessageController
com.company.web.message.comment.CommentController
回答by PraKhar
MessagesController.java
消息控制器.java
@RestController
@RequestMapping(value = "/messages")
public class MessageController {
@Autowired
private MessagesService messageService;
}
CommentController.java
注释控制器.java
@RestController
@RequestMapping("/messages/{messageId}/comments")
public class CommentController {
@GetMapping
public List<Comment> getComments(@PathVariable("messageId") Long messageId) {
System.out.println("Get "+messageId);
return null;
}
}