现在越来越多的服务都转向使用RESTful了,我们的项目也不例外,使用spring来做了REST。在采用RESTful的时候,我们会严格按照约定来使用 HTTP METHOD:

  • GET: 查询
  • POST: 创建
  • PUT: 修改
  • DELETE: 删除

本来,按照这种方式来做的时候,开发都很方便。不过,最近遇到一个问题:

在一个查询接口中,需要的参数比较多,如果还是使用GET方式进行请求的话,那么,Controller 中的方法的参数列表将会非常多,如:

public List<String> getName(@RequestParam String query1,
                            @RequestParam String query2,
                            @RequestParam String query3,
                            ......) {
        return new ArrayList<>();
}

很明显,这样的话,将会导致这个方法太难看 : ( 。

那么,该如何解决这个问题呢?下面说说我的思路:

方法一
换成POST请求,将所有参数封装成一个类,然后使用 @RequestBody注解将参数自动解析成该类的一个实例,如:

public List<String> getName(@RequestBody QueryDto queryDto) {
        return new ArrayList<>();
}

public class QueryDto {
    private String query1;
    private String query2;
    private String query3;

    // getter, setter ...
}

不过,有些人可能会纠结于上面的 RESTful“规范”,认为POST不应该用来进行查询。
对,这么想的确是合理的,不过,这个“规范”只是建议大家这么来遵守,并不是强制要求。有兴趣的,可以看看京东的请求,它的部分查询请求也是用的POST

方法二
还是使用GET请求,但是将所有请求参数通过JSON格式来传递,controller拿到参数后,使用 JSON 相关的库(如 gson),将该JSON转化为相应的对象,如:

public List<String> getName(@RequestParam String queryDtoStr) {
        QueryDto queryDto = new Gson().fromJson(queryDtoStr, QueryDto .class);
        // ....
        return new ArrayList<>();
}

public class QueryDto {
    private String query1;
    private String query2;
    private String query3;

    // getter, setter ...
}

这种情况下,请求的URL应该是类似于下面这样的:

http://localhost:8080/app/names?queryDtoStr={"query1":12,"query2":2,"query3":2}

 

方法三
在网法搜索时,发现有一种说法,说“GET请求也可以带body”,如果这个可以的话,就不用像上面方法一二那样麻烦了。直接使用GET + @RequestBody即可。

不过,我没试过,也不知道怎么试,我还是想用正常的方式,即:

  • get 的参数放在 URL 后面
  • post 的参数放在body中