@RequestMapping 映射不正确。

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

@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.

@RestController
class CommentController {

    private final CommentRepository commentRepository;
    private final AdvertRepository advertRepository;
    private final CommentModelAssembler assembler;

    CommentController(CommentRepository commentRepository, AdvertRepository advertRepository, CommentModelAssembler assembler) {
        this.commentRepository = commentRepository;
        this.advertRepository = advertRepository;
        this.assembler = assembler;
    }

    @GetMapping("/adverts/{advertId}/comments")
    CollectionModel<EntityModel<Comment>> all() {
        List<EntityModel<Comment>> comments =
                commentRepository.findAll().stream()
                        .map(assembler::toModel)
                        .collect(Collectors.toList());
        return CollectionModel.of(comments,
                linkTo(methodOn(CommentController.class).all()).withSelfRel());
    }

    @PostMapping("/adverts/{advertId}/comments")
    Comment newComment(@RequestBody Comment newComment) {
        return commentRepository.save(newComment);
    }

    @GetMapping("/adverts/{advertId}/comments/{id}")
    EntityModel<Comment> one(@PathVariable Long id) {
        Comment comment = commentRepository.findById(id)
                .orElseThrow(() -> new CommentNotFoundException(id));
        return assembler.toModel(comment);
    }

    @PutMapping("/adverts/{advertId}//comments/{id}")
    Comment replaceComment(@RequestBody Comment newComment,
                          @PathVariable Long id) {
        return commentRepository.findById(id)
                .map(comment -> {
                    comment.setAdvertId(newComment.getAdvertId());
                    comment.setComment(newComment.getComment());
                    return commentRepository.save(comment);
                })
                .orElseGet(() -> {
                    newComment.setId(id);
                    return commentRepository.save(newComment);
                });
    }

    @DeleteMapping("/adverts/{advertId}/comments/{id}")
    void deleteComment(@PathVariable Long id) {
        commentRepository.deleteById(id);
    }
}
@Component
public class CommentModelAssembler implements RepresentationModelAssembler<Comment, EntityModel<Comment>> {

    @Override
    public EntityModel<Comment> toModel(Comment comment) {
        return EntityModel.of(comment,
                linkTo(methodOn(CommentController.class).one(comment.getId())).withSelfRel(),
                linkTo(methodOn(CommentController.class).all()).withRel("comments"));
    }
}
@RestController
class UserController {

    private final UserRepository repository;
    private final UserModelAssembler assembler;

    UserController(UserRepository repository, UserModelAssembler assembler) {
        this.repository = repository;
        this.assembler = assembler;
    }

    @GetMapping("/users")
    CollectionModel<EntityModel<User>> all() {
        List<EntityModel<User>> users =
                repository.findAll().stream()
                        .map(assembler::toModel)
                        .collect(Collectors.toList());
        return CollectionModel.of(users,
                linkTo(methodOn(UserController.class).all()).withSelfRel());
    }

    @PostMapping("/users")
    User newUser(@RequestBody User newUser) {
        return repository.save(newUser);
    }

    @GetMapping("/users/{id}")
    EntityModel<User> one(@PathVariable Long id) {
        User user = repository.findById(id)
                .orElseThrow(() -> new UserNotFoundException(id));
        return assembler.toModel(user);
    }

    @PutMapping("/users/{id}")
    User replaceUser(@RequestBody User newUser,
                     @PathVariable Long id) {
        return repository.findById(id)
                .map(user -> {
                    user.setName(newUser.getName());
                    user.setRole(newUser.getRole());
                    user.setBoughtVehicles(newUser.getBoughtVehicles());
                    user.setSoldVehicles(newUser.getSoldVehicles());
                    return repository.save(user);
                })
                .orElseGet(() -> {
                    newUser.setId(id);
                    return repository.save(newUser);
                });
    }

    @DeleteMapping("/users/{id}")
    void deleteUser(@PathVariable Long id) {
        repository.deleteById(id);
    }
}
@RestController
class AdvertController {

    private final AdvertRepository repository;
    private final AdvertsModelAssembler assembler;

    AdvertController(AdvertRepository repository, AdvertsModelAssembler assembler) {
        this.repository = repository;
        this.assembler = assembler;
    }

    @GetMapping("/adverts")
    CollectionModel<EntityModel<Advert>> all() {
        List<EntityModel<Advert>> adverts =
                repository.findAll().stream()
                .map(assembler::toModel)
                .collect(Collectors.toList());
        return CollectionModel.of(adverts,
                linkTo(methodOn(AdvertController.class).all()).withSelfRel());
    }

    @PostMapping("/adverts")
    Advert newAdvert(@RequestBody Advert newAdvert) {
        return repository.save(newAdvert);
    }

    @GetMapping("/adverts/{id}")
    EntityModel<Advert> one(@PathVariable Long id) {
        Advert advert = repository.findById(id)
                .orElseThrow(() -> new AdvertNotFoundException(id));
        return assembler.toModel(advert);
    }

    @PutMapping("/adverts/{id}")
    Advert replaceAdvert(@RequestBody Advert newAdvert,
                         @PathVariable Long id) {
        return repository.findById(id)
                .map(advert -> {
                    advert.setAutoCategory(newAdvert.getAutoCategory());
                    advert.setAutoName(newAdvert.getAutoName());
                    advert.setAutoModel(newAdvert.getAutoModel());
                    advert.setComments(newAdvert.getComments());
                    return repository.save(advert);
                })
                .orElseGet(() -> {
                    newAdvert.setId(id);
                    return repository.save(newAdvert);
                });
    }

    @DeleteMapping("/adverts/{id}")
    void deleteAdvert(@PathVariable Long id) {
        repository.deleteById(id);
    }
}

localhost:8080/comments result:

{
  "_embedded" : {
    "comments" : [ {
      "advertId" : 1,
      "comment" : "That's a nice car!",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/comments/3"
        },
        "comment" : {
          "href" : "http://localhost:8080/comments/3"
        }
      }
    }, {
      "advertId" : 2,
      "comment" : "What a nice color of the car!",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/comments/4"
        },
        "comment" : {
          "href" : "http://localhost:8080/comments/4"
        }
      }
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/comments"
    },
    "profile" : {
      "href" : "http://localhost:8080/profile/comments"
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 2,
    "totalPages" : 1,
    "number" : 0
  }
}

答案1

得分: 1

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

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

@RestController
@RequestMapping("/adverts")
class CommentController {

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

@RestController
@RequestMapping("/common")
class CommentController {

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

类似地,对于 AdvertController:

@RestController
@RequestMapping("/advert")
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:

@RestController
@RequestMapping("/adverts")
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:

@RestController
    @RequestMapping("/common")
    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:

@RestController
@RequestMapping("/advert")
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:

确定