Is there any option to add a default value to all @RequestHeader's in spring boot?
@RequestHeader(value = "User-Accept-Language", defaultValue = "en-IN") String localeCd
I am copy/pasting to all the API's. Any help to avoid code duplication!!
Is there any option to add a default value to all @RequestHeader's in spring boot?
@RequestHeader(value = "User-Accept-Language", defaultValue = "en-IN") String localeCd
I am copy/pasting to all the API's. Any help to avoid code duplication!!
I didn't find anything already done for having an annotation for adding a header with a value so I did my own. Here is the code, is very simple, I did it using spring AOP
I created the annotation classes
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ResponseHeader {
public String key() default "";
public String value() default "";
}
and the one for containing an array of Headers annotations
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ResponseHeaders {
public ResponseHeader[] headers();
}
The AOP class for catching the restControllers (you can customise the AOP for setting you own pointcut as you wish:
import YOUR_PACKAGE_ANNOTATION.ResponseHeaders;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* Aspect for inserting headers on the methods of the @RestController
annotated classes
*/
@Aspect
@Component
public class ResponseHeadersAnnotation {
/**
* Pointcut for filtering just classes with @RestController annotation
*/
@Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
public void restControllerClass() {
}
/**
* It adds the headers to the response of the method of the controller
*
* @param responseHeaders
*/
@After("restControllerClass() && @annotation(responseHeaders)")
public void addHeaders(final ResponseHeaders responseHeaders) {
final HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
List.of(responseHeaders.headers()).forEach(responseHeader -> response.setHeader(responseHeader.key(), responseHeader.value()));
}
}
Here is an example of how to use it in a controller:
@GetMapping(value = {"/ServiceTicketCollection", "/ServiceRequestCollection"})
@ResponseHeaders(headers = {
@ResponseHeader(key = "cookie1", value = "value1"),
@ResponseHeader(key = "cookie2, value = "value2")
})
public Object restControllerMethod() {
...
}
This is an example on how to provide a default value for a header using spring WebFlux
@Component
public class CorrelationIdFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
var correlationId = exchange.getRequest().getHeaders().getFirst(CORRELATION_ID_HEADER);
if (correlationId == null || correlationId.isEmpty()) {
correlationId = UUID.randomUUID().toString();
ServerHttpRequest mutatedRequest = exchange.getRequest()
.mutate()
.header(CORRELATION_ID_HEADER, correlationId)
.build();
exchange = exchange
.mutate()
.request(mutatedRequest)
.build();
}
exchange.getResponse().getHeaders().add(CORRELATION_ID_HEADER, correlationId);
return chain.filter(exchange);
}
}
And this is for Spring web
@Component
public class CorrelationIdFilter implements Filter {
static final String CORRELATION_ID_HEADER = "X-Correlation-ID";
@Override
public void init(FilterConfig filterConfig) {
// empty
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String correlationId = httpRequest.getHeader(CORRELATION_ID_HEADER);
if (correlationId == null) {
correlationId = XidFactory.nextXid();
((HttpServletResponse) response).addHeader(CORRELATION_ID_HEADER, correlationId);
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
// empty
}
}