メッセンジャーアプリを作成しようとしています。
MessageResourceからCommentResourceを呼び出す必要があります。
MessageResourcesとCommentResourcesを分離したいのですが。
私はこのようなことをしています:
MessageResource.Java
@RestController
@RequestMapping("/messages")
public class MessageResource {
MessageService messageService = new MessageService();
@RequestMapping(value = "/{messageId}/comments")
public CommentResource getCommentResource() {
return new CommentResource();
}
}
CommentResource.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";
}
}
が欲しいです
http:// localhost:8080/messages/1/comments/abc
これは「テストコメントです」を返します。
何か案が??
PS:簡単なWordで、JAX-RS sub-resource
での同等の実装spring-rest
について知りたい
あなたの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;
}
}
MessageResourceクラスで何をしたいかは完全にはわかりませんが、アイデアはそこにあります。
現時点では、これらの使用はGetリクエストです。ただし、適切なHttpメソッドの使用を検討する必要があります。
これを見てください: http://www.restapitutorial.com/lessons/httpmethods.html
@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);
}
また、これらのクラスの名前をMessageControllerとCommentControllerに個人的に変更します。
文字通りコントローラーを分割することができます(以前のものに近い):
@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;
}
}
あなたが探しているものは Jersey などのJAX-RS
実装でサポートされており、Sub-Resources
と呼ばれます。自然にネストされる大きなAPIを構築する場合、サブリソースは非常に便利な機能です。
Spring BootのデフォルトのREST実装はJAX-RS
ではなくSpringMVC
です。 JerseyをSpring Bootで使用することは可能ですが、それを設定しようとするのは少し複雑であり、コミュニティで十分に使用/サポートされているようには見えません。
余談ですが、 DropWizard は素晴らしいです!
また、強制的にJAX-RSからSpring-MVCに移行しています。
JAX-RSの場合と同じように、これを行うためのエレガントな方法をまだ探しています。
私が試したことを共有しています。
_@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) {
}
}
_
そして、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) {
}
}
_
私が見つけた2つの問題、
@PathVariable
_はフィールドには適用されません。できません@PathVariable("parentId") private long parentId;
ChildrenController
の複数マッピングの自由意志はありませんJAX-RSの優れている点は、ChildrenController
にクラスレベルの_@Path
_が含まれている場合でも、ChildrenController
を異なるパスにマップできることです。
_@Path("/children");
public class ChildrenResource {
}
@Path("/parents")
public class ParentsResource {
@Path("/{id}/children")
public ChildrenResource resourceChildren() {
}
}
/children
/parents/{id}/children
_
Springブートでは、@ Autowired Springコンセプトを使用して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.
2つのクラスを作成し、constantを使用して、子リソースを親リソースで参照するだけです。これは、2つのクラス間のリンクを作成し、開発者にそれらの間の関係を理解させるのに役立ちます。
そう:
@RequestMapping(value= MessageController.URL)
public class MessageController {
public static final String URL= "/messages";
}
そして:
@RequestMapping(value = MessageController.URL + "/{idMessage}/comments")
public class CommentController {
}
また、コントローラーをさまざまなパッケージに分割して、パッケージ組織でこの階層を表示することもできます。
com.company.web.message.MessageController
com.company.web.message.comment.CommentController
MessagesController.Java
@RestController
@RequestMapping(value = "/messages")
public class MessageController {
@Autowired
private MessagesService messageService;
}
CommentController.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;
}
}