Custom Headers in ResponseEntity — HttpHeaders in Spring MVC
Fast recall
Quick revision
Core answer
Practical knowledge of HTTP header manipulation in Spring REST APIs
Not knowing the HttpHeaders API—trying to manually access HttpServletResponse instead of using ResponseEntity's fluent API
Show the Location header pattern for POST responses and mention Content-Type negotiation
Interview-ready guide
Interview answer
To add custom headers to a ResponseEntity, you create an HttpHeaders object, add your headers to it, then pass it to the ResponseEntity builder.
The HttpHeaders class is like a map. set to replace any existing value. headers and pass the HttpHeaders object.
A common use case is the Location header for POST responses. When you create a resource, you should return 201 Created with a Location header that points to the new resource's URI. setLocation and pass a URI object.
Another common header is Cache-Control. For GET endpoints that return data that doesn't change often, you can set Cache-Control with maxAge to let browsers and CDNs cache the response. For dynamic data, you use noCache.
Custom headers like X-Request-ID are useful for distributed tracing. You add a unique ID to the response, and when that request touches multiple services, you can correlate logs using that ID.
A common mistake is trying to use HttpServletResponse directly instead of the HttpHeaders API. That's lower-level servlet code and doesn't fit Spring's fluent builder pattern. Another mistake is forgetting the Location header in POST responses.
REST clients expect it, and without it, they have to parse the response body to find the new resource's ID. The key thing is headers are metadata about the response, and Spring gives you a clean API to set them through HttpHeaders and ResponseEntity.
Custom Headers in ResponseEntity — HttpHeaders in Spring MVC
Direct Answer
Create an HttpHeaders object, add headers with headers.add or headers.set, then pass it to the ResponseEntity builder with .headers(headers). Common headers include Location for 201 Created, Cache-Control for caching directives, and custom application headers for tracing or versioning.
Code Example
@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductService productService;
@PostMapping
public ResponseEntity<Product> createProduct(@RequestBody ProductRequest request) {
var product = productService.create(request);
var headers = new HttpHeaders();
headers.setLocation(URI.create("/api/products/" + product.id())); // Location header
headers.setCacheControl(CacheControl.noCache()); // No caching for mutations
return ResponseEntity.status(HttpStatus.CREATED).headers(headers).body(product);
}
@GetMapping("/{id}")
public ResponseEntity<Product> getProduct(@PathVariable Long id) {
var product = productService.findById(id).orElseThrow();
var headers = new HttpHeaders();
headers.setCacheControl(CacheControl.maxAge(300, TimeUnit.SECONDS)); // Cache for 5 min
headers.add("X-Request-ID", UUID.randomUUID().toString()); // Custom trace header
return ResponseEntity.ok().headers(headers).body(product);
}
}
Common Mistakes & Pitfalls
- Using HttpServletResponse directly: Learners often inject HttpServletResponse and call response.setHeader instead of using HttpHeaders with ResponseEntity. This bypasses Spring's fluent API and mixes low-level servlet code with high-level controller logic.
- Forgetting Location for POST: Not including a Location header in 201 Created responses breaks REST conventions. Clients may need that URI to fetch or update the new resource.
- Misspelling header names: Writing X-Request-Id instead of X-Request-ID or cache-control instead of Cache-Control. Header names are case-insensitive in HTTP but it's convention to use consistent casing. Use HttpHeaders constants like HttpHeaders.CACHE_CONTROL to avoid typos.
Check your understanding
Answer these without looking back at the article.
- What is the Location header and when should you set it?
- How do you add cache headers to a REST response in Spring?
- What is the difference between setting headers via ResponseEntity vs HttpServletResponse?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.