使用Spring-Integration实现http消息转发
目标:接收来自华为云的服务器报警信息,并转发到钉钉的自定义机器人中
使用Spring-Integration不仅节省了很多配置,还增加了可用性。
更多关于Spring-Integration的介绍可参照官网:http://spring.io/projects/spring-integration。
样例已上传至Github:https://github.com/hackyoMa/spring-integration-http-demo
项目基于Spring Boot2.0。
依赖:
<dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-http</artifactId> <scope>compile</scope> <exclusions> <exclusion> <artifactId>jackson-module-kotlin</artifactId> <groupId>com.fasterxml.jackson.module</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency>
配置文件application.properties:
server.port=8080
receive.path=/receiveGateway
forward.path=https://oapi.dingtalk.com/robot/send?access_token=xxx
主类:
package com.integration.http; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ImportResource; @SpringBootApplication @ImportResource(locations = "classpath:http-inbound-config.xml") public class HttpApplication { public static void main(String[] args) { SpringApplication.run(HttpApplication.class, args); } }
接收配置http-inbound-config.xml(放置resources目录):
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration" xmlns:int-http="http://www.springframework.org/schema/integration/http" xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:property-placeholder location="classpath:config/application.properties"/> <bean id="serviceActivator" class="com.integration.http.ServiceActivator"> </bean> <int-http:inbound-gateway request-channel="receiveChannel" path="${receive.path}" supported-methods="POST"> <int-http:cross-origin/> </int-http:inbound-gateway> <int:channel id="receiveChannel"/> <int:chain input-channel="receiveChannel"> <int:service-activator ref="serviceActivator"/> </int:chain> </beans>
发送配置http-outbound-config.xml(放置resources目录):
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration" xmlns:int-http="http://www.springframework.org/schema/integration/http" xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:property-placeholder location="classpath:config/application.properties"/> <int:gateway id="requestGateway" service-interface="com.integration.http.RequestGateway" default-request-channel="requestChannel"/> <int:channel id="requestChannel"/> <int-http:outbound-gateway request-channel="requestChannel" url="${forward.path}" http-method="POST" expected-response-type="java.lang.String" charset="UTF-8"/> </beans>
激活器(对转发信息过滤和修改)
ServiceActivator.java:
package com.integration.http; import com.alibaba.fastjson.JSONObject; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHandler; import org.springframework.messaging.MessagingException; import org.springframework.messaging.support.GenericMessage; import java.io.UnsupportedEncodingException; import java.text.SimpleDateFormat; import java.util.Date; public class ServiceActivator implements MessageHandler { private final static Log logger = LogFactory.getLog(ServiceActivator.class); private final static SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private JSONObject formatNotificationMsg(JSONObject payload) { String subject = payload.getString("subject"); String content = payload.getString("message"); long sendTime = Long.parseLong(payload.getString("timestamp")); JSONObject params = new JSONObject(); params.put("msgtype", "markdown"); JSONObject message = new JSONObject(); message.put("title", subject); message.put("text", "# 通知-" + subject + " \n**" + content + "** \n*" + SDF.format(new Date(sendTime)) + "*"); params.put("markdown", message); return params; } private JSONObject formatSubscriptionConfirmationMsg(JSONObject payload) { String type = payload.getString("type"); String subject; String content; if ("SubscriptionConfirmation".equals(type)) { subject = "确认订阅"; content = "确认订阅请点击此处"; } else { subject = "取消订阅成功"; content = "再次订阅请点击此处"; } String subscribeUrl = payload.getString("subscribe_url"); long sendTime = Long.parseLong(payload.getString("timestamp")); JSONObject params = new JSONObject(); params.put("msgtype", "markdown"); JSONObject message = new JSONObject(); message.put("title", subject); message.put("text", "# 通知-" + subject + "\n**[" + content + "](" + subscribeUrl + ")**\n*" + SDF.format(new Date(sendTime)) + "*"); params.put("markdown", message); return params; } @Override public void handleMessage(Message<?> message) throws MessagingException { try { JSONObject payload = JSONObject.parseObject(new String((byte[]) message.getPayload(), "UTF-8"), JSONObject.class); logger.info("接收参数:" + payload.toJSONString()); String type = payload.getString("type"); if ("Notification".equals(type)) { payload = formatNotificationMsg(payload); logger.info("发送参数:" + payload.toJSONString()); Message<?> toSend = new GenericMessage<>(payload.toJSONString(), message.getHeaders()); activator(toSend); } else if ("SubscriptionConfirmation".equals(type) || "UnsubscribeConfirmation".equals(type)) { payload = formatSubscriptionConfirmationMsg(payload); logger.info("发送参数:" + payload.toJSONString()); Message<?> toSend = new GenericMessage<>(payload.toJSONString(), message.getHeaders()); activator(toSend); } else { logger.info("不支持的消息类型:" + type); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } private void activator(Message<?> message) { ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("http-outbound-config.xml"); RequestGateway requestGateway = context.getBean("requestGateway", RequestGateway.class); String reply = requestGateway.echo(message); logger.info("发送回执:" + reply); context.close(); } }
请求网关(发送请求):
RequestGateway.java:
package com.integration.http; import org.springframework.messaging.Message; public interface RequestGateway { String echo(Message<?> message); }
这样就能将配置文件中接收地址传来的参数转发到转发地址中去。