spring-boot - Spring集成HttpRequestExecutingMessageHandler ContentType问题
问题描述
我遇到了 Spring Integration 的问题。我正在尝试通过 HttpRequestExecutingMessageHandler 执行休息调用。我的休息端点只接受内容类型“应用程序/json”。
问题是 HttpRequestExecutingMessageHandler 发布内容类型为“text/plain;charset=UTF-8”。
@ServiceActivator(inputChannel = "transformRequestToJsonChannel",
outputChannel = "httpRequestOutChannel")
public Message<?> transformRequest(Message<DocumentConverterRequest>
message)
{
LOG.info("transforming document converter request to json: '{}'",
ObjectToJsonTransformer transformer = new ObjectToJsonTransformer();
transformer.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
Object payload = transformer.transform(message).getPayload();
LOG.info("payload: '{}'", payload.toString());
return MessageBuilder.withPayload(payload).build();
}
@Bean
@ServiceActivator(inputChannel = "httpRequestOutChannel")
public HttpRequestExecutingMessageHandler outbound() {
HttpRequestExecutingMessageHandler handler = new
HttpRequestExecutingMessageHandler(documentConverterRestUrl);
handler.setHttpMethod(HttpMethod.POST);
handler.setErrorHandler(httpResponseErrorHandler);
handler.setExpectedResponseType(String.class);
handler.setCharset(Charset.defaultCharset().name());
HeaderMapper<HttpHeaders> mapper = new DefaultHttpHeaderMapper();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add(HttpHeaders.CONTENT_TYPE,
MediaType.APPLICATION_JSON_VALUE);
mapper.toHeaders(httpHeaders);
handler.setHeaderMapper(mapper);
handler.setOutputChannel(httpResponseChannel());
return handler;
}
如何覆盖内容类型?
解决方案
这段代码什么都不做:
HeaderMapper<HttpHeaders> mapper = new DefaultHttpHeaderMapper();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add(HttpHeaders.CONTENT_TYPE,
MediaType.APPLICATION_JSON_VALUE);
mapper.toHeaders(httpHeaders);
这toHeaders()
是从HttpRequestExecutingMessageHandler
我们收到响应时调用的。在代码中显式使用它真的没用,尤其是在 bean 定义阶段和忽略结果时。
您根本不需要使用显式HeaderMapper
:默认的应该足够了。
ObjectToJsonTransformer
真正将其映射到setContentType()
它回复的消息的标题中:
if (headers.containsKey(MessageHeaders.CONTENT_TYPE)) {
// override, unless empty
if (this.contentTypeExplicitlySet && StringUtils.hasLength(this.contentType)) {
headers.put(MessageHeaders.CONTENT_TYPE, this.contentType);
}
}
else if (StringUtils.hasLength(this.contentType)) {
headers.put(MessageHeaders.CONTENT_TYPE, this.contentType);
}
所以,有一个合适的内容类型来映射。默认HttpRequestExecutingMessageHandler
使用:
/**
* Factory method for creating a basic outbound mapper instance.
* This will map all standard HTTP request headers when sending an HTTP request,
* and it will map all standard HTTP response headers when receiving an HTTP response.
* @return The default outbound mapper.
*/
public static DefaultHttpHeaderMapper outboundMapper() {
使用一组适当的标头映射到 HTTP 请求和来自 HTTP 响应。
new DefaultHttpHeaderMapper()
只带来一组空的标题来映射。
请提出一个问题来改进 JavaDocs 和参考手册,以注意该类的默认 ctor 不会将任何标题带到映射中。
推荐阅读
- android - Firestore (Android) 中的范围查询时间戳
- javascript - Mapbox queryRenderedFeatures on load
- php - 如何为动态 sql 语句制作准备好的 mysqli 语句
- twitter-bootstrap - bootstrap datepicker - beforeShowDay 没有触发,我想突出显示日历上的日期
- ruby-on-rails - 如何在服务器端使用 graphql-ruby 传递多部分表单数据和文件上传?
- android - CountryCodePicker 是否支持输入电话号码
- kotlin - 如何在 Kotlin 中将串联转换为模板
- python - Eve:在响应中抑制验证错误详细信息
- php - 使用 Json 发布数据转换为数组
- javascript - for循环错误中的函数调用