Spring

Reading HTTP Headers in Spring REST Controller

Quick guide on How to Read HTTP Headers in Spring REST Controller.

Overview

This tutorial covers a different ways of Reading HTTP Headers in a Spring REST Controller. We will get introduced to the Spring’s @RequestHeader annotation, which maps Request Header values into Java Objects. We will also cover using @RequestHeader in detail with the helps of different examples.

Lastly, we will cover how to use HttpServletRequest instance to read the header values in the Spring REST Controller.

Reading Header Values With @RequestHeader

Spring provides @RequestHeader annotation that maps all or a particular header values to an argument of a controller method. The type of @RequestHeader annotation is parameter. Thus we can add it directly on a controller method argument.

In order to do that the only prerequisite is that the data type of the header value and the controller method argument must match or they must be compatible.

Spring REST Header Values to Map

In the next example we are Reading all HTTP headers in a HashMap. The method in the snippet is a POST endpoint from a Spring REST controller. We are using @RequestHeader annotation to map all HTTP headers into Java Map instance.

@PostMapping("/students") public Student postStudent( @RequestHeader Map<String, String> headers, @RequestBody Student student) { log.info("Request to create student: {}", student); log.info("Header values: {}", headers); return repository.save(student); }
Code language: Java (java)

Spring REST Header Values into HttpHeaders Instance

Alternatively, we can inject the HTTP Headers into an instance of HttpHeaders class. The HttpHeaders is an implementation of a MultiValueMap class.

Next, is an example of reading HTTP Header values in HttpHeader instance.

@PostMapping("/students") public Student postStudent( @RequestHeader HttpHeaders headers, @RequestBody Student student) { log.info("Request to create student: {}", student); log.info("Header values: {}", headers); return repository.save(student); }
Code language: Java (java)

Spring REST Header values to MultiValueMap

While mapping HttpHeader values to a Map, Spring only maps first value of the key into the Map. However, if a header key has more than one values and we want to read all values, we can use MultiValueMap.

Example of Reading HttpHeaders to MultiValueMap in Spring REST Controller.

@PostMapping("/students") public Student postStudent( @RequestHeader MultiValueMap<String, String> headers, @RequestBody Student student) { log.info("Request to create student: {}", student); log.info("Header values: {}", headers); return repository.save(student); }
Code language: Java (java)

Reading Specific Http Header with @RequestHeader

So far, we have seen examples of reading all Http Headers at once in one type of object. However, we can also read only a specific header using @RequestHeader by providing the header key as annotation value.

Example of Reading a specific header in Spring REST Controller.

@PostMapping("/students") public Student postStudent( @RequestHeader("content-type") String contentType, @RequestBody Student student) { log.info("Request to create student: {}", student); log.info("Header value - Content-Type: {}", contentType); return repository.save(student); }
Code language: Java (java)

By default, if a particular header is mapped into Controller method argument, spring treats it as a mandatory header. Thus, Spring returns a HTTP status code of 400 (Bad Request), if the mapped header is not present in the request.

In order to make the header optional we can use required attribute of @RequestHeader annotation.

@PostMapping("/students") public Student postStudent( @RequestHeader(value = "content-type", required = false) String contentType, @RequestBody Student student) { log.info("Request to create student: {}", student); log.info("Header value - Content-Type: {}", contentType); return repository.save(student); }
Code language: Java (java)

Next, is an example of setting a default header value if a particular header is not present in the request. In order to set a default value we can use defaultValue attribute of @RequestHeader annotation.

@PostMapping("/students") public Student postStudent( @RequestHeader(value = "content-type", defaultValue = "application/json") String contentType, @RequestBody Student student) { log.info("Request to create student: {}", student); log.info("Header value - Content-Type: {}", contentType); return repository.save(student); }
Code language: Java (java)

Note that, Spring will inject the default value only if the original header is missing or is Null.

Reading Header Values from HttpServletRequest

So far, we covered how @RequestHeader annotation maps various headers into Java Objects. However, we can always read all or a particular headers using the HttpServletRequest instance.

In order to access HttpServletRequest instance in a Spring REST Controller, we need to add it as a method argument.

Next is an example of Reading all header values in Spring REST Controller, using HttpServletRequest.

@PostMapping("/students") public Student postStudent( HttpServletRequest request, @RequestBody Student student) { log.info("Request to create student: {}", student); Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String key = headerNames.nextElement(); log.info(key + ": " + request.getHeader(key)); } return repository.save(student); }
Code language: Java (java)

Summary

In this tutorial we learnt How to Read HTTP Headers in Spring REST Controllers. We learned that using @RequestHeader annotation we can map all headers or a particular header into an argument of controller method. Also, we covered how to make a header value optional or how to provide a default value for a missing header. Lastly, we learned how to use HttpServletRequet and read headers manually.

For more on Spring and Spring Boot, please visit Spring Tutorials.


Leave a Reply

Your email address will not be published. Required fields are marked *