在Spring MVC 3中指定HTTP“位置”响应 header 的首选方法是什么?
据我所知,Spring仅会提供一个“位置”以响应重定向(“redirect:xyz”或RedirectView),但是在某些情况下,位置应与实体一起发送(例如, “201 Created”的结果)。
恐怕我唯一的选择是手动指定它:
httpServletResponse.setHeader("Location", "/x/y/z");
这样对吗?有没有更好的方法来解决这个问题?
最佳答案
关键是使用UriComponentsBuilder
。
有几种方法可以获取它的实例
UriComponentsBuilder
中预配置的MvcUriComponentsBuilder
UriComponentsBuilder
作为方法从
UriComponentsBuilder
预配置的MvcUriComponentsBuilder
这样,您可以获得的
UriComponentsBuilder
被配置为生成URI
,它指向带有预定义参数的某些 Controller 方法。这是javadoc中ojit_a的示例:
例如,给定此 Controller :
@RequestMapping("/people/{id}/addresses")
class AddressController {
@RequestMapping("/{country}")
public HttpEntity<Void> getAddressesForCountry(@PathVariable String country) { ... }
@RequestMapping(value="/", method=RequestMethod.POST)
public void addAddress(Address address) { ... }
}
A UriComponentsBuilder can be created:
// Inline style with static import of "MvcUriComponentsBuilder.on"
MvcUriComponentsBuilder.fromMethodCall(
on(AddressController.class).getAddressesForCountry("US")).buildAndExpand(1);
有时可能更可取的另一个选择是通过名称指定 Controller 方法:
UriComponents uriComponents = MvcUriComponentsBuilder.fromMethodName(
AddressController.class, "getAddressesForCountry", "US").buildAndExpand(1);
URI nextUri = uriComponents.toUri();
MvcUriComponentsBuilder
作为方法的参数注入(inject)从Spring 3.1开始,可以使用
UriComponentsBuilder
参数制作Location
并将其设置为返回的UriComponentBuilder
。 ResponseEntity
意识到上下文并使用相对路径进行操作:@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> createCustomer(UriComponentsBuilder b) {
UriComponents uriComponents =
b.path("/customers/{id}").buildAndExpand(id);
HttpHeaders headers = new HttpHeaders();
headers.setLocation(uriComponents.toUri());
return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
}
从4.1版开始,您可以使其更短
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> createCustomer(UriComponentsBuilder b) {
UriComponents uriComponents =
b.path("/customers/{id}").buildAndExpand(id);
return ResponseEntity.created(uriComponents.toUri()).build();
}
感谢Dieter Hubau指出这一点。