以下是我在为学校项目编写服务时遇到的两种情况。
@RequestMapping("/customer/firstName/")
public CustomerRepresentation getCustomersByFirstName(HttpServletRequest request) {
String name = request.getParameter("fname");
List<Customer> customer = customerActivity.findByCustFirstName(name);
// etc
}
@RequestMapping(value="/customer/firstName/{fname}",method = RequestMethod.GET, produces = {"text/html","application/json", "application/xml"})
public @ResponseBody List<CustomerRepresentation> getCustomersByFirstName(@PathVariable("fname") String name) {
List<Customer> customer = customerActivity.findByCustFirstName(name);
// etc
}
行为:
如果我使用第一种方法,我可以使用任何浏览器甚至邮递员的链接访问结果。
如果我使用第二种方法,只有在指定Accept Headers时才能使用Postman访问结果。如果我使用浏览器,它会给我错误406,键入不支持。
使用客户端两者都可以正常工作,只需稍微修改一下URL。
是什么原因引起的?我假设HttpServletRequest
中的默认设置?如果我们使用第二种方法,网站将如何运作,或者我做错了什么?
答案 0 :(得分:1)
如果您指定
produces = {"text/html","application/json", "application/xml"}
您需要使用其中一种类型发送Accept标头。 有些客户端使用默认的Accept标头,它可能与您期望的不同。
答案 1 :(得分:1)
这两个URI在原则上是不同的,根本不应该被认为是相同的。
首先,路径变量和查询参数之间存在巨大差异 - 路径变量必需是路径的一部分,否则路径将无法访问。这是两个URI的区别:
/customer/firstName?fname=Bob
/customer/firstName/Bob
如果没有Bob,则无法访问第二个URI,而不是第一个URI;你可能会要求其他而不是fname
。
其次,您必须设置Accept
标头的原因是由于produces
数组的设置方式:您有text/html
,application/json
和application/xml
;你的客户将无法接受任何不属于这三种类型的东西。
第三,要直接回答最后一个问题,我会明确地劝阻你的第二种方法,因为应该对路径变量进行分区。该路径描述了一些必需的信息,以便继续请求;在这里,您只询问有关客户的信息,该信息应包含在查询中。
在这种情况下,您的请求URI应该真的只有customer
并且firstName
的查询。
/customer?firstName=Bob