For downloading a file I will add the "Content-Disposition" to my responseHeader but it doesn't work.
The response will not have any added properties.
@Bean
public ExpressionParser fileParser() {
return new SpelExpressionParser();
}
@Bean
public HeaderMapper<HttpHeaders> fileHeaderMapper() {
return new DefaultHttpHeaderMapper();
}
@Bean
public IntegrationFlow httpGetFileDownload() {
return IntegrationFlows.from(
Http.inboundGateway("/api/files/download/{id}")
.requestMapping(r -> r.methods(HttpMethod.GET))
.statusCodeExpression(fileParser().parseExpression("T(org.springframework.http.HttpStatus).BAD_REQUEST"))
.payloadExpression(fileParser().parseExpression("#pathVariables.id"))
.crossOrigin(cors -> cors.origin("*").exposedHeaders("Content-Disposition", "content-disposition"))
.headerMapper(fileHeaderMapper())
)
.channel("http.file.download.channel")
.handle("fileEndpoint", "download")
.get();
}
public Message<?> download(Message<Long> msg){
...
return MessageBuilder
.withPayload(resource)
.copyHeaders(msg.getHeaders())
.setHeader(STATUSCODE_HEADER, HttpStatus.OK)
.setHeader(HttpHeaders.CONTENT_DISPOSITION,"attachment;filename=" + file.getName())
.setHeader(HttpHeaders.CONTENT_TYPE, mimeType)
.setHeader(HttpHeaders.CONTENT_LENGTH, (int)file.length())
.build();
}
What I get:
cache-control: "no-cache, no-store, max-age=0, must-revalidate"
content-type: "application/json"
expires: "0"
pragma: "no-cache"
Your problem that DefaultHttpHeaderMapper
is empty by default. I think it might be a time to make the ctor as deprecated
to not allow to use it from end application.
Or to make some validation to reject just empty (not configured) DefaultHttpHeaderMapper
...
It is also confusing what is the point to use that return new DefaultHttpHeaderMapper();
if your don't customize it. There is a default one in the HttpRequestHandlingMessagingGateway
:
private HeaderMapper<HttpHeaders> headerMapper = DefaultHttpHeaderMapper.inboundMapper();
To fix your problem you definitely need to use this inboundMapper()
factory method, which does this:
/**
* Factory method for creating a basic inbound mapper instance.
* This will map all standard HTTP request headers when receiving an HTTP request,
* and it will map all standard HTTP response headers when sending an HTTP response.
* @return The default inbound mapper.
*/
public static DefaultHttpHeaderMapper inboundMapper() {
DefaultHttpHeaderMapper mapper = new DefaultHttpHeaderMapper();
setupDefaultInboundMapper(mapper);
return mapper;
}
That setupDefaultInboundMapper()
is very important: it brings for us a set of headers to map from the request and into response.