What is the preferred way to specify an HTTP “Location” Response Header in Spring MVC 3?

前端 未结 5 805
名媛妹妹
名媛妹妹 2020-12-28 12:29

What is the preferred way to specify an HTTP \"Location\" Response Header in Spring MVC 3?

As far as I can tell, Spring will only provide a \"Location\" in response

5条回答
  •  攒了一身酷
    2020-12-28 13:30

    The key point is to use UriComponentsBuilder. There are several ways how you can get the instance of it

    1. preconfigured UriComponentsBuilder from MvcUriComponentsBuilder
    2. UriComponentsBuilder injected as parameter to method

    Preconfigured UriComponentsBuilder from MvcUriComponentsBuilder

    This way you can get UriComponentsBuilder that is configured to produce URI that points to some controller methods with predefined parameters.

    Here is example from the javadoc for MvcUriComponentsBuilder:

    For example, given this controller:

     @RequestMapping("/people/{id}/addresses")
     class AddressController {
    
       @RequestMapping("/{country}")
       public HttpEntity 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);
    

    Another options which sometimes may be preferable is to specify controller method by name:

    UriComponents uriComponents = MvcUriComponentsBuilder.fromMethodName(
        AddressController.class, "getAddressesForCountry", "US").buildAndExpand(1);
    URI nextUri = uriComponents.toUri();
    

    UriComponentsBuilder injected as parameter to method

    As of spring 3.1 Location can be crafted using UriComponentBuilder parameter and set it to the returned ResponseEntity. UriComponentBuilder is aware of the context and manipulates with relative paths:

    @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(headers, HttpStatus.CREATED);
    }
    

    Since version 4.1 you can make it even shorter

    @RequestMapping(method = RequestMethod.POST)
    public ResponseEntity createCustomer(UriComponentsBuilder b) {
    
        UriComponents uriComponents = 
            b.path("/customers/{id}").buildAndExpand(id);
    
        return ResponseEntity.created(uriComponents.toUri()).build();
    }
    

    Thanks to Dieter Hubau to pointing this out.

提交回复
热议问题