在Spring MVC 3中指定HTTP“位置”响应 header 的首选方法是什么?

据我所知,Spring仅会提供一个“位置”以响应重定向(“redirect:xyz”或RedirectView),但是在某些情况下,位置应与实体一起发送(例如, “201 Created”的结果)。

恐怕我唯一的选择是手动指定它:

httpServletResponse.setHeader("Location", "/x/y/z");

这样对吗?有没有更好的方法来解决这个问题?

最佳答案

关键是使用UriComponentsBuilder
有几种方法可以获取它的实例

  • UriComponentsBuilder中预配置的MvcUriComponentsBuilder
  • UriComponentsBuilder作为方法
  • 的参数注入(inject)

    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并将其设置为返回的UriComponentBuilderResponseEntity意识到上下文并使用相对路径进行操作:
    @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指出这一点。

    07-24 19:29