1. SpringBoot 使用IBM MQ


此次主要介紹mq相關分享

目標:可以與MQ互動(接收/互動)

必須知識:

  • java 8
  • spring系列
  • MVC 分層抽離
  • mq的基礎知識
  • 可能需要會通靈,解釋性資訊不多XD

spring boot核心應用為以下

  1. spring starter
  2. spring web
  3. ibm mq
    <parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>2.7.11</version>
     <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
     <groupId>com.ibm.mq</groupId>
     <artifactId>com.ibm.mq.allclient</artifactId>
     <version>9.3.2.1</version>
    </dependency>
    

分享片段程式

mq靜態參數
IMB_MQ_PROPERTY.class

public enum IMB_MQ_PROPERTY {
    WMQ_HOST_NAME("localhost"),
    WMQ_PORT("1414"), // ibm mq default port
    WMQ_CHANNEL("自訂頻道"),
    WMQ_QUEUE_MANAGER("此MQ管理者");

    private final String value;

    IMB_MQ_PROPERTY(String value) {
        this.value = value;
    }
    @Override
    public String toString() {
        return this.value;
    }
    public int toInt() {
        return Integer.parseInt(this.value);
    }
}

mq設定檔
IbmConnectionConfiguration.class

@Configuration
public class IbmConnectionConfiguration {

@Bean
public Connection getIbmConnectionConfiguration() throws JMSException {
    JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
    JmsConnectionFactory cf = ff.createConnectionFactory();

    cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, IMB_MQ_PROPERTY.WMQ_HOST_NAME.toString());
    cf.setIntProperty(WMQConstants.WMQ_PORT, IMB_MQ_PROPERTY.WMQ_PORT.toInt());
    cf.setStringProperty(WMQConstants.WMQ_CHANNEL, IMB_MQ_PROPERTY.WMQ_CHANNEL.toString());
    cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
    cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, IMB_MQ_PROPERTY.WMQ_QUEUE_MANAGER.toString());
    return cf.createConnection();
}

}

互動介面
JmsMessageProcesser介面省略
僅JmsMessageProcesserImpl.class

@Service
public class JmsMessageProcesserImpl implements JmsMessageProcesser {


    @Autowired
    Connection connection;

    // 簡易發送Message
    @Override
    public void sendMsg(String queueName, String context) throws JMSException {
        try {
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            Destination destination  = session.createQueue("queue:///"+queueName);
            MessageProducer producer = session.createProducer(destination);
            TextMessage message = session.createTextMessage(context);
            connection.start();
            producer.send(message);
        }catch (JMSException jmsex) {
            jmsex.printStackTrace();
        }
        finally {
            connection.close();
        }
    }
}

// 簡易接收Message
@Override
public String readMessage(String queueName) throws JMSException {
    List<String> result = new ArrayList<>();
    Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    Queue queue = session.createQueue("queue:///" + queueName);
    connection.start();
    log.debug("Browse through the elements in queue");
    try (QueueBrowser browser = session.createBrowser(queue)) {
        MessageConsumer consumer = session.createConsumer(queue);
        Enumeration<?> e = browser.getEnumeration();
        while (e.hasMoreElements()) {
            e.nextElement();
            result.add(getMsg(consumer.receive()));
        }
    }
    log.debug("Done");
    return new Gson().toJson(result);
}

private String getMsg(Message receivedMessage) throws JMSException {
    if (receivedMessage instanceof BytesMessage) {
        TextMessage textMessage = (TextMessage) receivedMessage;
        log.debug("Received message '"
                + textMessage.getText() + "'");
        return textMessage.getText();
    }
    if (receivedMessage instanceof TextMessage) {
        TextMessage textMessage = (TextMessage) receivedMessage;
        log.debug("Received message: " + textMessage.getText());
        return textMessage.getText();
    }
   throw new JMSException("Received message is nullable");
}

透過RestfulApi介面接收/發送
JMSController.class

@RestController
@RequestMapping(value = "/api/jms")
public class JMSController {

@Autowired
JmsMessageProcesser jmsMessageProcesser;


/**
 * test push msg to IBM MQ.
 * ref:
 * Put and Get Messages to IBM MQ from java code
 * https://stackoverflow.com/questions/49660593/put-and-get-messages-to-ibm-mq-from-java-code
 * using newly kit cau runnable from ref code
 * @return the web rest response
 * @throws JMSException the jms exception
 */
@GetMapping("/send-jms-test")
public WebRestResponse<String> send() throws JMSException {
    long uniqueNumber = System.currentTimeMillis() % 1000;
    String context = "Simple Requestor: Your lucky number yesterday was " + uniqueNumber;
    String queueName = "自定義佇列";
    jmsMessageProcesser.sendMsg(queueName, context);
    return WebRestResponse.success(context);
}

/**
 * test get msg to IBM MQ.
 * ref:
 * JMS QueueBrowser Example
 * https://examples.javacodegeeks.com/java-development/enterprise-java/jms/jms-queuebrowser-example/
 * using newly kit can runnable from ref code (pure way)
 * @return all queue msg
 * @throws JMSException the jms exception
 */
@GetMapping("/get-jms-test")
public WebRestResponse<String> get() throws JMSException {
    String queueName ="自定義要接收/讀取的助列(QUEUE)";
    return WebRestResponse.success(jmsMessageProcesser.readMessage(queueName));
}

}

補充:

  1. 需要有mq服務才能讓專案連上MQ與其互動 建議可以使用containter方便又快速
  2. WebRestResponse自定義的JSON
  3. Gson 序列化使用(JSON)

主要是給自己的一個紀錄,也分享給有需要的夥伴
註解部分有提及一些參考的連結,有興趣可以點進去看看喔

這是一個心血來潮,產生的文章
若有喜歡或交流的部分都歡迎在下方留言,多多關照。

#mq #ibm







你可能感興趣的文章

【THM Walkthrough】Exploiting Active Directory (1)

【THM Walkthrough】Exploiting Active Directory (1)

React-router-dom 實作與原理解析

React-router-dom 實作與原理解析

2. SpringBoot使用jms整合IBM MQ

2. SpringBoot使用jms整合IBM MQ






留言討論