Spring Integration NotWritablePropertyException:‘Content-Type’属性无效问题
解决Spring Integration HTTP出站网关的415与NotWritablePropertyException问题
我来帮你一步步拆解和解决这个问题:
先搞懂两个错误的关联
首先,HTTP 415错误本质是媒体类型不兼容——要么你请求里的Content-Type服务端不认,要么你压根没正确设置这个请求头。而你加了headerMapper Bean后触发的NotWritablePropertyException,大概率是和Content-Type属性的getter/setter规范不匹配有关,或者是配置headerMapper的方式不对。
重点检查Getter/Setter的类型匹配
Spring处理Bean属性时,严格遵循JavaBean规范,针对Content-Type这块:
- 如果你是自定义了HeaderMapper类,一定要确保
getContent-Type()的返回类型,和setContent-Type(...)的参数类型完全一致。比如要么都是MediaType类型,要么都是String类型,绝对不能一个返回MediaType.APPLICATION_JSON,另一个却接收String类型的"application/json",这种类型不匹配会直接让Spring识别不了属性,抛出“不可写”的异常。
正确配置Spring Integration的HeaderMapper
其实大部分场景下,你不需要完全自定义HeaderMapper,Spring Integration自带的DefaultHttpHeaderMapper就足够用了,配置时要注意正确的姿势:
XML配置示例(适配你的场景)
<int:gateway id="requestGateway" service-interface="org.myorg.springintegration.gateway.http.RequestGateway" default-request-channel="httpOutboundChannel"/> <int-http:outbound-gateway id="httpOutboundGateway" request-channel="httpOutboundChannel" url="http://你的目标服务地址" http-method="POST" header-mapper="customHeaderMapper"/> <bean id="customHeaderMapper" class="org.springframework.integration.http.support.DefaultHttpHeaderMapper"> <!-- 指定要映射的出站请求头,这里包含Content-Type --> <property name="outboundHeaderNames" value="Content-Type, Accept"/> <!-- 去掉自定义头的前缀,避免头名被修改 --> <property name="userDefinedHeaderPrefix" value=""/> </bean>
如果你用Java配置的话
@Bean public DefaultHttpHeaderMapper customHeaderMapper() { DefaultHttpHeaderMapper mapper = DefaultHttpHeaderMapper.outboundMapper(); // 设置需要传递的请求头 mapper.setOutboundHeaderNames(Arrays.asList("Content-Type", "Accept")); mapper.setUserDefinedHeaderPrefix(""); return mapper; } @Bean public HttpRequestHandlingMessagingGateway httpOutboundGateway() { HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway(); gateway.setRequestChannel(httpOutboundChannel()); gateway.setHeaderMapper(customHeaderMapper()); // 补充其他必要配置,比如URL、HTTP方法等 return gateway; }
关键提醒
别直接给headerMapper的Content-Type属性硬赋值!正确的做法是通过outboundHeaderNames指定要映射的请求头,然后在发送请求时,通过网关接口的方法参数或者消息头来设置具体的Content-Type值(比如MediaType.APPLICATION_JSON_VALUE)。
最终解决流程
- 先确认目标服务期望的
Content-Type是什么(比如application/json、application/x-www-form-urlencoded)。 - 按照上面的正确方式配置
headerMapper,确保它能正确传递这个请求头。 - 如果是自定义HeaderMapper,务必检查getter和setter的参数/返回类型完全一致,符合JavaBean规范。
内容的提问来源于stack exchange,提问作者user1575148
相关产品推荐
相关产品推荐

