@RequestMapping 映射不正确。

huangapple go评论105阅读模式
英文:

@RequestMapping doesn't map correctly

问题

问题是当我在CommentController类上方使用我的注释@RequestMapping("/adverts/{id}")时,我可以通过两种方式访问该类,即:localhost:8080/adverts/1/commentslocalhost:8080/comments。我如何禁止访问localhost:8080/comments?谢谢。

英文:

My problem is that when I use my annotation @RequestMapping("/adverts/{id}") above my CommentController class, I can reach this class using both (i.e): localhost:8080/adverts/1/comments and localhost:8080/comments. How I can disable reaching localhost:8080/comments? Thank you.

  1. @RestController
  2. class CommentController {
  3. private final CommentRepository commentRepository;
  4. private final AdvertRepository advertRepository;
  5. private final CommentModelAssembler assembler;
  6. CommentController(CommentRepository commentRepository, AdvertRepository advertRepository, CommentModelAssembler assembler) {
  7. this.commentRepository = commentRepository;
  8. this.advertRepository = advertRepository;
  9. this.assembler = assembler;
  10. }
  11. @GetMapping("/adverts/{advertId}/comments")
  12. CollectionModel<EntityModel<Comment>> all() {
  13. List<EntityModel<Comment>> comments =
  14. commentRepository.findAll().stream()
  15. .map(assembler::toModel)
  16. .collect(Collectors.toList());
  17. return CollectionModel.of(comments,
  18. linkTo(methodOn(CommentController.class).all()).withSelfRel());
  19. }
  20. @PostMapping("/adverts/{advertId}/comments")
  21. Comment newComment(@RequestBody Comment newComment) {
  22. return commentRepository.save(newComment);
  23. }
  24. @GetMapping("/adverts/{advertId}/comments/{id}")
  25. EntityModel<Comment> one(@PathVariable Long id) {
  26. Comment comment = commentRepository.findById(id)
  27. .orElseThrow(() -> new CommentNotFoundException(id));
  28. return assembler.toModel(comment);
  29. }
  30. @PutMapping("/adverts/{advertId}//comments/{id}")
  31. Comment replaceComment(@RequestBody Comment newComment,
  32. @PathVariable Long id) {
  33. return commentRepository.findById(id)
  34. .map(comment -> {
  35. comment.setAdvertId(newComment.getAdvertId());
  36. comment.setComment(newComment.getComment());
  37. return commentRepository.save(comment);
  38. })
  39. .orElseGet(() -> {
  40. newComment.setId(id);
  41. return commentRepository.save(newComment);
  42. });
  43. }
  44. @DeleteMapping("/adverts/{advertId}/comments/{id}")
  45. void deleteComment(@PathVariable Long id) {
  46. commentRepository.deleteById(id);
  47. }
  48. }
  1. @Component
  2. public class CommentModelAssembler implements RepresentationModelAssembler<Comment, EntityModel<Comment>> {
  3. @Override
  4. public EntityModel<Comment> toModel(Comment comment) {
  5. return EntityModel.of(comment,
  6. linkTo(methodOn(CommentController.class).one(comment.getId())).withSelfRel(),
  7. linkTo(methodOn(CommentController.class).all()).withRel("comments"));
  8. }
  9. }
  1. @RestController
  2. class UserController {
  3. private final UserRepository repository;
  4. private final UserModelAssembler assembler;
  5. UserController(UserRepository repository, UserModelAssembler assembler) {
  6. this.repository = repository;
  7. this.assembler = assembler;
  8. }
  9. @GetMapping("/users")
  10. CollectionModel<EntityModel<User>> all() {
  11. List<EntityModel<User>> users =
  12. repository.findAll().stream()
  13. .map(assembler::toModel)
  14. .collect(Collectors.toList());
  15. return CollectionModel.of(users,
  16. linkTo(methodOn(UserController.class).all()).withSelfRel());
  17. }
  18. @PostMapping("/users")
  19. User newUser(@RequestBody User newUser) {
  20. return repository.save(newUser);
  21. }
  22. @GetMapping("/users/{id}")
  23. EntityModel<User> one(@PathVariable Long id) {
  24. User user = repository.findById(id)
  25. .orElseThrow(() -> new UserNotFoundException(id));
  26. return assembler.toModel(user);
  27. }
  28. @PutMapping("/users/{id}")
  29. User replaceUser(@RequestBody User newUser,
  30. @PathVariable Long id) {
  31. return repository.findById(id)
  32. .map(user -> {
  33. user.setName(newUser.getName());
  34. user.setRole(newUser.getRole());
  35. user.setBoughtVehicles(newUser.getBoughtVehicles());
  36. user.setSoldVehicles(newUser.getSoldVehicles());
  37. return repository.save(user);
  38. })
  39. .orElseGet(() -> {
  40. newUser.setId(id);
  41. return repository.save(newUser);
  42. });
  43. }
  44. @DeleteMapping("/users/{id}")
  45. void deleteUser(@PathVariable Long id) {
  46. repository.deleteById(id);
  47. }
  48. }
  1. @RestController
  2. class AdvertController {
  3. private final AdvertRepository repository;
  4. private final AdvertsModelAssembler assembler;
  5. AdvertController(AdvertRepository repository, AdvertsModelAssembler assembler) {
  6. this.repository = repository;
  7. this.assembler = assembler;
  8. }
  9. @GetMapping("/adverts")
  10. CollectionModel<EntityModel<Advert>> all() {
  11. List<EntityModel<Advert>> adverts =
  12. repository.findAll().stream()
  13. .map(assembler::toModel)
  14. .collect(Collectors.toList());
  15. return CollectionModel.of(adverts,
  16. linkTo(methodOn(AdvertController.class).all()).withSelfRel());
  17. }
  18. @PostMapping("/adverts")
  19. Advert newAdvert(@RequestBody Advert newAdvert) {
  20. return repository.save(newAdvert);
  21. }
  22. @GetMapping("/adverts/{id}")
  23. EntityModel<Advert> one(@PathVariable Long id) {
  24. Advert advert = repository.findById(id)
  25. .orElseThrow(() -> new AdvertNotFoundException(id));
  26. return assembler.toModel(advert);
  27. }
  28. @PutMapping("/adverts/{id}")
  29. Advert replaceAdvert(@RequestBody Advert newAdvert,
  30. @PathVariable Long id) {
  31. return repository.findById(id)
  32. .map(advert -> {
  33. advert.setAutoCategory(newAdvert.getAutoCategory());
  34. advert.setAutoName(newAdvert.getAutoName());
  35. advert.setAutoModel(newAdvert.getAutoModel());
  36. advert.setComments(newAdvert.getComments());
  37. return repository.save(advert);
  38. })
  39. .orElseGet(() -> {
  40. newAdvert.setId(id);
  41. return repository.save(newAdvert);
  42. });
  43. }
  44. @DeleteMapping("/adverts/{id}")
  45. void deleteAdvert(@PathVariable Long id) {
  46. repository.deleteById(id);
  47. }
  48. }

localhost:8080/comments result:

  1. {
  2. "_embedded" : {
  3. "comments" : [ {
  4. "advertId" : 1,
  5. "comment" : "That's a nice car!",
  6. "_links" : {
  7. "self" : {
  8. "href" : "http://localhost:8080/comments/3"
  9. },
  10. "comment" : {
  11. "href" : "http://localhost:8080/comments/3"
  12. }
  13. }
  14. }, {
  15. "advertId" : 2,
  16. "comment" : "What a nice color of the car!",
  17. "_links" : {
  18. "self" : {
  19. "href" : "http://localhost:8080/comments/4"
  20. },
  21. "comment" : {
  22. "href" : "http://localhost:8080/comments/4"
  23. }
  24. }
  25. } ]
  26. },
  27. "_links" : {
  28. "self" : {
  29. "href" : "http://localhost:8080/comments"
  30. },
  31. "profile" : {
  32. "href" : "http://localhost:8080/profile/comments"
  33. }
  34. },
  35. "page" : {
  36. "size" : 20,
  37. "totalElements" : 2,
  38. "totalPages" : 1,
  39. "number" : 0
  40. }
  41. }

答案1

得分: 1

你的 localhost:8080/comments API 似乎来自不同的控制器,而不是你所发布的控制器。

更新
如果你只想看到每个用户的评论,你可以按照以下方式更改你的控制器定义,使其更通用和简单:

  1. @RestController
  2. @RequestMapping("/adverts")
  3. class CommentController {

更新 2
你需要更新你的控制器 URL 映射。通常,我们为特定的控制器/目的定义一个公共的 URL 名称。比如你的 CommonController,你可以这样做:

  1. @RestController
  2. @RequestMapping("/common")
  3. class CommentController {

注意这个名字 /common。然后,在这个控制器下,你可以添加其他的 API,比如 /comments/all/comments/{id}/comments/others。要访问这些控制器方法,你必须按照这个层次结构,比如:
/common/comments/all 或者 /common/comments/1

类似地,对于 AdvertController:

  1. @RestController
  2. @RequestMapping("/advert")
  3. class AdvertController {

同样,检查一下常见的 URL 名称 /advert。在这个控制器下的 API 将会有这样的命名:
/all/{id}。要访问这个控制器方法,使用的 URL 形式如下:
/advert/all/advert/1

这应该能够清楚地解释你的问题。
需要注意的是,我在示例 URL 中排除了基本的 localhost:8080 部分,请记得添加上这部分。
希望这能够达到你的目的。

英文:

Your localhost:8080/comments API seems to come from different controller, not from this one you have posted.

Update:
If you want to see only each user's comment, you can change your controller definition following way to make it more generic and simple:

  1. @RestController
  2. @RequestMapping("/adverts")
  3. class CommentController {

Update 2:
You need to update your controller-url mapping. Generally, we define a common url-name for a specific controller/purpose. Like for your CommonController you can do this:

  1. @RestController
  2. @RequestMapping("/common")
  3. class CommentController {

See the name /commom. Then, under this controller, you add other API like /comments/all, /comments/{id}, /comments/others. To access these controller method, you must follow this hierarchy like:
/common/comments/all or /common/comments/1
Similarly for AdvertController:

  1. @RestController
  2. @RequestMapping("/advert")
  3. class AdvertController {

Again, check the common url-name /advert. API under this controller will have naming like this:
/all, '/{id}'. To access this controller method use URL this way:
/advert/all, /advert/1
This should clear your idea.
One thing, I have excluded the base-url localhost:8080 part from the url-example I have shown, mind adding this.
Hope, this will server your purpose.

huangapple
  • 本文由 发表于 2020年9月23日 13:57:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/64021854.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定