使用 HTTPServletRequest 和使用 @PathVariable 的 REST 服务行为
Behaviour of REST service using HTTPServletRequest and using @PathVariable
以下是我在学校为一个项目编写服务代码时遇到的两个场景。
场景 1
@RequestMapping("/customer/firstName/")
public CustomerRepresentation getCustomersByFirstName(HttpServletRequest request) {
String name = request.getParameter("fname");
List<Customer> customer = customerActivity.findByCustFirstName(name);
// etc
}
场景 2
@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
}
行为:
如果我使用第一种方法,我可以使用 link 从任何浏览器甚至 Postman 访问结果。
如果我使用第二种方法,只有当我指定 Accept Headers 时,我才能使用 Postman 访问结果。如果我使用浏览器,它会显示错误 406,类型不受支持。
对 URL.
稍作修改,使用客户端都可以正常工作
这是什么原因造成的?我假定 HttpServletRequest
中的默认设置?如果我们使用第二种方法,网站将如何运行,或者我做错了什么?
如果您指定
produces = {"text/html","application/json", "application/xml"}
您需要使用其中一种类型发送接受 header。
一些客户端使用默认接受 header,它可能与您期望的不同。
这两个URI在原理上是不同的,根本不应该被认为是相同的。
首先,路径变量和查询参数之间存在巨大差异 - 路径变量需要成为路径的一部分,否则路径将无法访问。就是这两个URI的区别:
/customer/firstName?fname=Bob
/customer/firstName/Bob
没有 Bob,您将无法访问第二个 URI,这与第一个 URI 不同;你可能想要 other 而不是 fname
.
其次,您必须设置 Accept
headers 的原因是由于 produces
数组的设置方式:您有 text/html
、application/json
,和application/xml
;您的客户将无法接受任何不是这三种类型之一的东西。
第三,为了直接回答最后一个问题,我会明确反对你的第二种方法,因为路径变量应该被分区。该路径描述了一些要求 请求继续的信息;在这里,您只询问有关客户的信息,这些信息应该包含在查询中。
在这种情况下,您的请求 URI 应该 真的 只是 customer
查询 firstName
.
/customer?firstName=Bob
以下是我在学校为一个项目编写服务代码时遇到的两个场景。
场景 1
@RequestMapping("/customer/firstName/")
public CustomerRepresentation getCustomersByFirstName(HttpServletRequest request) {
String name = request.getParameter("fname");
List<Customer> customer = customerActivity.findByCustFirstName(name);
// etc
}
场景 2
@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
}
行为:
如果我使用第一种方法,我可以使用 link 从任何浏览器甚至 Postman 访问结果。
如果我使用第二种方法,只有当我指定 Accept Headers 时,我才能使用 Postman 访问结果。如果我使用浏览器,它会显示错误 406,类型不受支持。
对 URL.
稍作修改,使用客户端都可以正常工作
这是什么原因造成的?我假定 HttpServletRequest
中的默认设置?如果我们使用第二种方法,网站将如何运行,或者我做错了什么?
如果您指定
produces = {"text/html","application/json", "application/xml"}
您需要使用其中一种类型发送接受 header。 一些客户端使用默认接受 header,它可能与您期望的不同。
这两个URI在原理上是不同的,根本不应该被认为是相同的。
首先,路径变量和查询参数之间存在巨大差异 - 路径变量需要成为路径的一部分,否则路径将无法访问。就是这两个URI的区别:
/customer/firstName?fname=Bob
/customer/firstName/Bob
没有 Bob,您将无法访问第二个 URI,这与第一个 URI 不同;你可能想要 other 而不是 fname
.
其次,您必须设置 Accept
headers 的原因是由于 produces
数组的设置方式:您有 text/html
、application/json
,和application/xml
;您的客户将无法接受任何不是这三种类型之一的东西。
第三,为了直接回答最后一个问题,我会明确反对你的第二种方法,因为路径变量应该被分区。该路径描述了一些要求 请求继续的信息;在这里,您只询问有关客户的信息,这些信息应该包含在查询中。
在这种情况下,您的请求 URI 应该 真的 只是 customer
查询 firstName
.
/customer?firstName=Bob