Loading

使用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);

}

 

这样就能将配置文件中接收地址传来的参数转发到转发地址中去。

posted @ 2018-08-22 16:15  hackyo  阅读(7463)  评论(1编辑  收藏  举报