Como ler cabeçalhos HTTP nos controladores Spring REST

Como ler cabeçalhos HTTP nos controladores Spring REST

1. Introdução

Neste tutorial rápido, veremos como acessar cabeçalhos HTTP em umSpring Rest Controller.

Primeiro, usaremos a anotação@RequestHeader para ler cabeçalhos individualmente, bem como todos juntos.

Depois disso, daremos uma olhada mais detalhada nos atributos de@RequestHeader.

2. Acessando cabeçalhos HTTP

2.1. Individualmente

Se precisarmos de acesso a um cabeçalho específico,we can configure @RequestHeader with the header name:

@GetMapping("/greeting")
public ResponseEntity greeting(@RequestHeader("accept-language") String language) {
    // code that uses the language variable
    return new ResponseEntity(greeting, HttpStatus.OK);
}

Então, podemos acessar o valor usando a variável passada em nosso método. Se um cabeçalho chamadoaccept-language não for encontrado na solicitação, o método retorna um erro “400 Bad Request”.

Nossos cabeçalhos não precisam ser strings. Por exemplo, se sabemos que nosso cabeçalho é um número, podemos declarar nossa variável como um tipo numérico:

@GetMapping("/double")
public ResponseEntity doubleNumber(@RequestHeader("my-number") int myNumber) {
    return new ResponseEntity(String.format("%d * 2 = %d",
      myNumber, (myNumber * 2)), HttpStatus.OK);
}

2.2. Tudo de uma vez

Se não tivermos certeza de quais cabeçalhos estarão presentes, ou precisarmos de mais deles do que queremos na assinatura do nosso método, podemos usar a anotação@RequestHeader sem um nome específico.

Temos algumas opções para o nosso tipo de variável: um objetoMap,MultiValueMap ouHttpHeaders.

Primeiro, vamos obter os cabeçalhos da solicitação comoMap:

@GetMapping("/listHeaders")
public ResponseEntity listAllHeaders(
  @RequestHeader Map headers) {
    headers.forEach((key, value) -> {
        LOG.info(String.format("Header '%s' = %s", key, value));
    });

    return new ResponseEntity(
      String.format("Listed %d headers", headers.size()), HttpStatus.OK);
}

Se usarmos umMape um dos cabeçalhos tiver mais de um valor, we’ll get only the first value. Isso é o equivalente a usar o métodogetFirst em umMultiValueMap.

Se nossos cabeçalhos podem ter vários valores, podemos obtê-los comoMultiValueMap:

@GetMapping("/multiValue")
public ResponseEntity multiValue(
  @RequestHeader MultiValueMap headers) {
    headers.forEach((key, value) -> {
        LOG.info(String.format(
          "Header '%s' = %s", key, value.stream().collect(Collectors.joining("|"))));
    });

    return new ResponseEntity(
      String.format("Listed %d headers", headers.size()), HttpStatus.OK);
}

Também podemos obter nossos cabeçalhosas an HttpHeaders object:

@GetMapping("/getBaseUrl")
public ResponseEntity getBaseUrl(@RequestHeader HttpHeaders headers) {
    InetSocketAddress host = headers.getHost();
    String url = "http://" + host.getHostName() + ":" + host.getPort();
    return new ResponseEntity(String.format("Base URL = %s", url), HttpStatus.OK);
}

O objetoHttpHeaders tem acessores para cabeçalhos de aplicativos comuns.

Quando acessamos um cabeçalho por nome de um objetoMap,MultiValueMap ouHttpHeaders, obteremos umnull se ele não estiver presente.

3. Atributos de@RequestHeader

Agora que examinamos os fundamentos do acesso aos cabeçalhos de solicitação com a anotação@RequestHeader, vamos dar uma olhada em seus atributos.

Já usamos os atributosname ouvalue implicitamente quando nomeamos especificamente nosso cabeçalho:

public ResponseEntity greeting(@RequestHeader("accept-language") String language) {}

Podemos realizar a mesma coisa usando o atributoname:

public ResponseEntity greeting(
  @RequestHeader(name = "accept-language") String language) {}

A seguir, vamos usar o atributovalue exatamente da mesma maneira:

public ResponseEntity greeting(
  @RequestHeader(value = "accept-language") String language) {}

When we name a header specifically, the header is required by default. Se o cabeçalho não for encontrado na solicitação, o controlador retorna um erro 400.

Vamos usar o atributorequired para indicar que nosso cabeçalho não é obrigatório:

@GetMapping("/nonRequiredHeader")
public ResponseEntity evaluateNonRequiredHeader(
  @RequestHeader(value = "optional-header", required = false) String optionalHeader) {
    return new ResponseEntity(String.format(
      "Was the optional header present? %s!",
        (optionalHeader == null ? "No" : "Yes")),HttpStatus.OK);
}

Comoour variable will be null if the header isn’t present in the request, precisamos ter certeza de fazer a verificação apropriada denull.

Vamos usar o atributodefaultValue para fornecer um valor padrão para nosso cabeçalho:

@GetMapping("/default")
public ResponseEntity evaluateDefaultHeaderValue(
  @RequestHeader(value = "optional-header", defaultValue = "3600") int optionalHeader) {
    return new ResponseEntity(
      String.format("Optional Header is %d", optionalHeader), HttpStatus.OK);
}

4. Conclusão

Neste breve tutorial, aprendemos como acessar cabeçalhos de solicitação nos controladores Spring REST. Primeiro, usamos a anotação@RequestHeader para fornecer cabeçalhos de solicitação para nossos métodos de controlador.

Depois de dar uma olhada no básico, demos uma olhada detalhada nos atributos para a anotação@RequestHeader.

O código de exemplo está disponívelover on GitHub.