Spring Integration:如何用HttpRequestExecutingMessageHandler传递JSON参数到API URL
Spring Integration通过HttpRequestExecutingMessageHandler传递JSON参数到REST API
你需要将JSON中的msg和mobileNo参数通过Spring Integration的HttpRequestExecutingMessageHandler传递到目标REST API的URL参数中,现针对你的代码给出修改方案:
现有代码模块
Controller代码
@RestController @RequestMapping("/api") public class NotificationController { @Autowired NotificationGateway notificationGateway; @PostMapping("/sendmsg") public String sendMsg(@RequestBody SMSData smsData) { return notificationGateway.sendMsg(smsData); } }
Gateway代码
@MessagingGateway public interface NotificationGateway { @Gateway(requestChannel = "httpOutRequest") String sendMsg(SMSData smsData); }
原配置类代码
@Configuration public class HTTPConfig { private final Logger log = LoggerFactory.getLogger(HTTPConfig.class); @Bean @ServiceActivator(inputChannel = "httpOutRequest") public MessageHandler outbound() { log.info("Inside HTTPConfig :: outbound() invoked "); HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler( "http://localhost:9090/Gateway/rest?msg={msg}&mobileNo={mobileNo}", restTemplate()); handler.setHttpMethod(HttpMethod.GET); handler.setExpectedResponseType(String.class); handler.setExpectReply(true); ExpressionParser expressionParser = new SpelExpressionParser(); handler.setUriVariableExpressions( Collections.singletonMap("msg", expressionParser.parseExpression("headers['msg']"))); handler.setUriVariableExpressions( Collections.singletonMap("mobileNo", expressionParser.parseExpression("headers['mobileNo']"))); return handler; } @Bean public RestTemplateBuilder restTemplateBuilder() { log.info("Inside HTTPConfig :: restTemplateBuilder() invoked "); return new RestTemplateBuilder(); } @Bean public RestTemplate restTemplate() { log.info("Inside HTTPConfig :: restTemplate() invoked "); RestTemplate restTemplate = new RestTemplate(); return restTemplate; } }
DTO代码
public class SMSData { public String msg; public String mobileNo; }
问题分析
- 原配置中两次调用
setUriVariableExpressions,第二次会直接覆盖第一次的参数映射,导致只有mobileNo的配置生效。 - 原配置从消息头(
headers)中获取参数,但NotificationGateway的sendMsg方法是将SMSData对象作为消息体(payload)传递,而非存入消息头,因此无法从headers中取到参数值。
修改后的核心配置
调整outbound()方法,修正参数映射的来源与映射方式:
@Bean @ServiceActivator(inputChannel = "httpOutRequest") public MessageHandler outbound() { log.info("Inside HTTPConfig :: outbound() invoked "); HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler( "http://localhost:9090/Gateway/rest?msg={msg}&mobileNo={mobileNo}", restTemplate()); handler.setHttpMethod(HttpMethod.GET); handler.setExpectedResponseType(String.class); handler.setExpectReply(true); ExpressionParser expressionParser = new SpelExpressionParser(); // 构建完整的参数映射,从消息体(payload)中提取SMSData的属性值 Map<String, Expression> uriVariables = new HashMap<>(); uriVariables.put("msg", expressionParser.parseExpression("payload.msg")); uriVariables.put("mobileNo", expressionParser.parseExpression("payload.mobileNo")); handler.setUriVariableExpressions(uriVariables); return handler; }
原理说明
- 调用
NotificationGateway.sendMsg(smsData)时,smsData会被封装为Spring Integration的Message对象,其中smsData作为消息的payload。 - 通过SpEL表达式
payload.msg和payload.mobileNo,直接从消息体中提取SMSData的属性值,填充到目标URL的参数占位符中。 - 最终目标REST API会收到
GET请求,URL参数为msg=This is my message&mobileNo=00123456987,与你提供的JSON参数完全对应。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

