向REST API传递多个参数 - Spring

54

我正在尝试弄清楚是否可以将JSON对象传递给REST API,或者传递多个参数到该API?如何在Spring中读取这些参数?假设URL看起来像下面的示例:

例如1:http://localhost:8080/api/v1/mno/objectKey?id=1&name=saif

是否可以在url中像以下示例中传递JSON对象?

例如2:http://localhost:8080/api/v1/mno/objectKey/{"id":1,"name":"Saif"}

问题:

1)是否可以像示例2那样将JSON对象传递到URL中?

2)如何在示例1中传递和解析参数?

我尝试编写一些方法来实现我的目标,但找不到正确的解决方案?

我试图将JSON对象作为@RequestParam传递

http://localhost:8080/api/v1/mno/objectKey?id=1发生意外错误(类型=不受支持的媒体类型,状态=415)。不支持内容类型'null'

http://localhost:8080/api/v1/mno/objectKey/id=1发生意外错误(类型=未找到,状态=404)。没有可用的消息

http://localhost:8080/api/v1/mno/objectKey/%7B%22id%22:1%7D发生意外错误(类型=未找到,状态=404)。没有可用的消息

@RequestMapping(value="mno/{objectKey}",
                method = RequestMethod.GET, 
                consumes="application/json")
    public List<Book> getBook4(@RequestParam ObjectKey objectKey) {
        ...
    }

我尝试将JSON对象作为@Pathvariable传递

@RequestMapping(value="ghi/{objectKey}",method = RequestMethod.GET)
    public List<Book> getBook2(@PathVariable ObjectKey objectKey) {
        ...         
    }

我创建了这个对象来保存id参数和其他参数,如名称等...

class ObjectKey{
        long id;
        public long getId() {
            return id;
        }
        public void setId(long id) {
            this.id = id;
        }
    }

那么关于注解@RequestBody和将对象作为主体传递的问题呢? - bilak
你为什么要这样做?你应该能够从请求中获取一个与实体匹配的对象。 - ChiefTwoPencils
抱歉,如果示例不准确,那只是一个概念验证。我想根据搜索条件从数据库中获取建议项列表。我将拥有一个小部件调用REST API并传递参数。但目前我正在努力专注于后端部分。 - Arar
4个回答

100
(1)是否可以像示例2那样将JSON对象传递给URL?
不可以,因为http://localhost:8080/api/v1/mno/objectKey/{"id":1, "name":"Saif"}不是一个有效的URL。
如果你想按照RESTful的方式进行操作,可以使用http://localhost:8080/api/v1/mno/objectKey/1/Saif,并且定义你的方法如下:
@RequestMapping(path = "/mno/objectKey/{id}/{name}", method = RequestMethod.GET)
public Book getBook(@PathVariable int id, @PathVariable String name) {
    // code here
}

(2)我们如何在示例1中传递和解析参数? 只需添加两个请求参数,并提供正确的路径即可。
@RequestMapping(path = "/mno/objectKey", method = RequestMethod.GET)
public Book getBook(@RequestParam int id, @RequestParam String name) {
    // code here
}

更新 (来自评论)

What if we have a complicated parameter structure ?

"A": [ {
    "B": 37181,
    "timestamp": 1160100436,
    "categories": [ {
        "categoryID": 2653,
        "timestamp": 1158555774
    }, {
        "categoryID": 4453,
        "timestamp": 1158555774
    } ]
} ]
将其作为一个POST请求发送,将JSON数据放在请求体中而不是URL中,并指定内容类型为application/json
@RequestMapping(path = "/mno/objectKey", method = RequestMethod.POST, consumes = "application/json")
public Book getBook(@RequestBody ObjectKey objectKey) {
    // code here
}

1
你不应该在 GET 中发送这样的内容,而应该使用 POST,并将 JSON 包含在负载中,在内容类型中指定为 application/json - Andreas
谢谢上次的更新,Andreas。我想知道是否可以使用JavaScript创建一个POST请求,因为我不想使用表单来调用这个REST API,我希望JavaScript来调用它。 - Arar
1
是的。我建议你进行网页搜索。我还建议使用库,例如jQuery,以使其更容易。 - Andreas
有些人会争辩说,如果你想拥有一个符合RESTful API标准的API,就不应该发送POST而不是GET。简单来说:POST仅用于创建数据,PUT用于更新,GET用于检索数据。 - jolumg
4
有些人没有阅读POST方法的HTTP定义(https://tools.ietf.org/html/rfc7231#section-4.3.3):“POST方法请求目标资源根据资源自己特定的语义处理请求中所包含的表示”。当然,最常见的语义是为资源创建一些东西,但是“process”更通用,可以意味着其他事情,例如使用提供的数据运行信用检查。对于这种情况,GET方法是不合适的。 - Andreas
显示剩余5条评论

39

你可以在URL中传递多个参数,例如:

http://localhost:2000/custom?brand=dell&limit=20&price=20000&sort=asc

为了获取这些查询字段,你可以使用 map。

    @RequestMapping(method = RequestMethod.GET, value = "/custom")
    public String controllerMethod(@RequestParam Map<String, String> customQuery) {

        System.out.println("customQuery = brand " + customQuery.containsKey("brand"));
        System.out.println("customQuery = limit " + customQuery.containsKey("limit"));
        System.out.println("customQuery = price " + customQuery.containsKey("price"));
        System.out.println("customQuery = other " + customQuery.containsKey("other"));
        System.out.println("customQuery = sort " + customQuery.containsKey("sort"));

        return customQuery.toString();
    }

2
这真的帮助我创建了一个具有动态URL参数的GET服务。谢谢@Om Sharma。 - sunil

2

可以像下面这样给出多个参数:

    @RequestMapping(value = "/mno/{objectKey}", method = RequestMethod.GET, produces = "application/json")
    public List<String> getBook(HttpServletRequest httpServletRequest, @PathVariable(name = "objectKey") String objectKey
      , @RequestParam(value = "id", defaultValue = "false")String id,@RequestParam(value = "name", defaultValue = "false") String name) throws Exception {
               //logic
}

0

可以将JSON对象传递到URL中

queryString = "{\"left\":\"" + params.get("left") + "}";
 httpRestTemplate.exchange(
                    Endpoint + "/A/B?query={queryString}",
                    HttpMethod.GET, entity, z.class, queryString);

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