Spring REST @RequestMapping 实践

4
@RestController
@RequestMapping(value = "/players")
public class REST {

    @RequestMapping(method = RequestMethod.GET)
    public List<Player> getAll() {
        return service.getAll();
    }

    @RequestMapping(method = RequestMethod.GET, params = {"team", "score"})
    public List<Player> getByPlayerAndScore(@RequestParam(value = "team") String team, 
                                                @RequestParam(value = "score", required = false) int score) {
        return service.getByPlayerAndScore(team, score);
    }
}

问题1:我期望第一个方法适用于url "/players"(按预期工作),第二个方法适用于url's ("/players?team=xyz", "/players?team=xyz&score=1000")。Spring在"/players?team=xyz"中使用了方法1。即使我将分数指定为可选项,除非我指定2个参数,否则Spring不会使用第2个方法。如何解决这个问题,并编写最佳的控制器方法来处理这些类型的请求,其中用户可以发送不同的可用参数集(如param1&param2、仅param1、仅param2等)。

问题2:对于具有不同参数集的第二种查询类型,在DAO层如何编写数据库查询。我应该编写单独的方法,每个方法都有不同的查询,还是一个方法多个if语句(例如,如果用户发送“team”,则将团队添加到DB查询中,如果用户发送“score”,则将其添加到DB查询中...)

1个回答

6
你的第二个映射清楚地指定了必须同时出现teamscore请求参数,但是在你的例子 /players?team=xyz 中并没有出现这两个参数。方法参数绑定中写了required = false是无关紧要的 - @RequestMapping 明确表示请求参数必须存在。(请注意,你可以有一个参数但没有值,就像 Spring Security 常用的 URL /login?error。这将匹配 params = { "error" } 但不会有值。)
使用单个控制器方法中的正常 if 语句可能会更简单。
或者,你可能想查看Spring的Querydsl集成,它允许你将查询参数解释为可直接传递给Spring数据查找方法的Predicate
此外,请查看新的复合方便注释,比如 @GetMapping,这将使你的代码更易于阅读。

我在第二个映射中设置了 required = false。 - lch
@LokeshCherukuri,你应该将它放在参数绑定中,而不是请求映射中。已更新答案。 - chrylis -cautiouslyoptimistic-

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接