【问题标题】:How can I override a Spring Data REST method without disabling default implementations如何在不禁用默认实现的情况下覆盖 Spring Data REST 方法
【发布时间】:2020-08-10 09:54:58
【问题描述】:

我终于找到了一种使用自定义实现覆盖 Spring Data REST 方法的方法。不幸的是,这会禁用默认处理。

我的存储库应包含分别暴露在GET: /gamesGET: /games/{id} 上的findAllfindById,并且不应导出save,因为它已被控制器覆盖。

@RepositoryRestResource(path = "games", exported = true)
public interface GameRepository extends Repository<Game, UUID> {
    Collection<Game> findAll();

    Game findById(UUID id);

    @RestResource(exported = false)
    Game save(Game game);
}

我的控制器应该处理POST: /games,在服务器上生成游戏并返回保存的游戏。

@RepositoryRestController
@ExposesResourceFor(Game.class)
@RequestMapping("games")
public class CustomGameController {
    private final GameService gameService;

    public CustomGameController(GameService gameService) {
        this.gameService = gameService;
    }

    @ResponseBody
    @RequestMapping(value = "", method = RequestMethod.POST, produces = "application/hal+json")
    public PersistentEntityResource generateNewGame(@RequestBody CreateGameDTO createGameDTO, PersistentEntityResourceAssembler assembler) {
        Game game = gameService.generateNewGame(createGameDTO);
        return assembler.toFullResource(game);
    }

}

但是,当我尝试 GET: /games 它返回 405: Method Not AllowedPOST: /games 按预期工作。当我将 generateNewGame 映射的值更改为 "new" 时,所有三个请求都有效。但是POST: /games/new 不是 RESTful URL 布局,我宁愿避免它。我不明白为什么会出现这种行为以及如何解决它。有人知道吗?

【问题讨论】:

  • 据此 (faithfull.me/overriding-spring-data-rest-repositories) 你不应该在类级别有 ResquestMapping。
  • 感谢修复。我从这里得到了它作为“约定”docs.spring.io/spring-hateoas/docs/current/reference/html/… 无论如何,这种行为非常奇怪。你认为这可以被认为是一个错误吗?
  • @marcellorvalle 请您将此作为答案,然后我很乐意接受。
  • 我真的不知道这是否是一个错误,我从未使用过 RepositoryRestController。不幸的是,我没有我的开发机器。如果您愿意,请随时发布正确答案。

标签: java spring spring-data-jpa spring-data-rest


【解决方案1】:

在您的控制器上方使用@BasePathAwareControllerannotation 来保留默认的弹簧数据休息路径并根据您的需要添加新的自定义路径。虽然覆盖了默认的spring数据休息路径。

@BasePathAwareController
public class CustomGameController {
private final GameService gameService;

public CustomGameController(GameService gameService) {
    this.gameService = gameService;
}

@ResponseBody
@RequestMapping(value = "", method = RequestMethod.POST, produces = 
 "application/hal+json")
public PersistentEntityResource generateNewGame(@RequestBody CreateGameDTO 
createGameDTO, PersistentEntityResourceAssembler assembler) {
    Game game = gameService.generateNewGame(createGameDTO);
    return assembler.toFullResource(game);
}

}

【讨论】:

  • 感谢您的回答,但由于我不再从事此项目,因此无法验证答案。也许我会回到它。
  • RepositoryRestController 继承自 BasePathAwareController,因此,如问题的 cmets 所述,保留自动生成的端点的技巧是不要在类级别使用 ResquestMapping
【解决方案2】:

也许你可以做一些我们通常在 Linux 中做的事情。设置一个假路径并链接到它。

POST /games     ==> [filter] request.uri.euqal("/games") && request.method==POST
 ==> Redirect /new/games

你看到的也是/games

不要使用/games/new,可能会和Spring内部的东西冲突。

【讨论】:

    猜你喜欢
    • 2019-01-16
    • 1970-01-01
    • 2019-11-16
    • 2014-06-05
    • 1970-01-01
    • 2014-12-12
    • 1970-01-01
    • 1970-01-01
    • 2019-08-13
    相关资源
    最近更新 更多