You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用JMS/ActiveMQ发送带图片、视频片段附件的MMS消息?

嘿,这个问题我之前帮不少开发者解决过——确实,绝大多数JMS入门示例都只展示文本消息,但要发送带图片、视频附件的MMS其实核心思路很清晰,就是把MMS的多部分内容打包成二进制流,通过JMS的二进制消息类型来传输。下面给你一步步拆解具体怎么做:

核心思路:用MIME多部分消息封装MMS内容

MMS本质上是多部分MIME消息,包含文本正文和二进制附件(图片、视频片段等)。我们可以先用Java的邮件API构建这种MIME结构,再把它转换成二进制流,通过JMS的BytesMessage(推荐)或BlobMessage(大附件场景)发送。

具体实现步骤

1. 构建MIME多部分消息

首先用MimeMultipart来组装文本内容和各种附件,这里需要用到Jakarta Mail(或旧版javax.mail)的API:

import jakarta.mail.BodyPart;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeBodyPart;
import jakarta.mail.internet.MimeMultipart;
import jakarta.mail.util.ByteArrayDataSource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

// 创建MIME多部分容器
MimeMultipart multipart = new MimeMultipart();

// 添加MMS文本正文
BodyPart textBodyPart = new MimeBodyPart();
textBodyPart.setText("这是一条带附件的MMS消息");
multipart.addBodyPart(textBodyPart);

// 添加图片附件
BodyPart imagePart = new MimeBodyPart();
File imageFile = new File("/path/to/your/photo.jpg");
ByteArrayDataSource imageSource = new ByteArrayDataSource(
        new FileInputStream(imageFile), "image/jpeg");
imagePart.setDataHandler(new jakarta.activation.DataHandler(imageSource));
imagePart.setFileName(imageFile.getName());
multipart.addBodyPart(imagePart);

// 添加视频片段附件
BodyPart videoPart = new MimeBodyPart();
File videoClip = new File("/path/to/your/clip.mp4");
ByteArrayDataSource videoSource = new ByteArrayDataSource(
        new FileInputStream(videoClip), "video/mp4");
videoPart.setDataHandler(new jakarta.activation.DataHandler(videoSource));
videoPart.setFileName(videoClip.getName());
multipart.addBodyPart(videoPart);

2. 用JMS BytesMessage发送MIME内容

把构建好的MIME多部分消息转换成字节数组,写入BytesMessage后发送到ActiveMQ:

import org.apache.activemq.ActiveMQConnectionFactory;
import jakarta.jms.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

// 初始化ActiveMQ连接
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
Connection connection = connectionFactory.createConnection();
connection.start();

// 创建会话和生产者
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination mmsQueue = session.createQueue("MMS_Delivery_Queue");
MessageProducer producer = session.createProducer(mmsQueue);

// 将MIME消息转为字节数组
ByteArrayOutputStream baos = new ByteArrayOutputStream();
multipart.writeTo(baos);
byte[] mmsBytes = baos.toByteArray();

// 创建BytesMessage并写入内容
BytesMessage mmsMessage = session.createBytesMessage();
mmsMessage.writeBytes(mmsBytes);
// 添加消息属性,方便接收端识别MIME类型
mmsMessage.setStringProperty("Content-Type", multipart.getContentType());

// 发送消息
producer.send(mmsMessage);

// 释放资源
producer.close();
session.close();
connection.close();

3. 接收端解析MMS消息

接收端读取BytesMessage的字节数组,再转回MimeMultipart来提取文本和附件:

import jakarta.jms.*;
import org.apache.activemq.ActiveMQConnectionFactory;
import jakarta.mail.BodyPart;
import jakarta.mail.internet.MimeMultipart;
import jakarta.mail.util.ByteArrayDataSource;
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer consumer = session.createConsumer(mmsQueue);

Message receivedMsg = consumer.receive();
if (receivedMsg instanceof BytesMessage) {
    BytesMessage bytesMsg = (BytesMessage) receivedMsg;
    byte[] mmsBytes = new byte[(int) bytesMsg.getBodyLength()];
    bytesMsg.readBytes(mmsBytes);

    // 转回MIME多部分消息
    ByteArrayDataSource dataSource = new ByteArrayDataSource(
            new ByteArrayInputStream(mmsBytes),
            bytesMsg.getStringProperty("Content-Type")
    );
    MimeMultipart receivedMultipart = new MimeMultipart(dataSource);

    // 遍历各部分提取内容
    for (int i = 0; i < receivedMultipart.getCount(); i++) {
        BodyPart part = receivedMultipart.getBodyPart(i);
        if (part.isMimeType("text/plain")) {
            System.out.println("MMS正文:" + part.getContent());
        } else if (part.isMimeType("image/*") || part.isMimeType("video/*")) {
            // 保存附件到本地
            String fileName = part.getFileName();
            FileOutputStream fos = new FileOutputStream("/path/to/save/" + fileName);
            part.getDataHandler().writeTo(fos);
            fos.close();
            System.out.println("已保存附件:" + fileName);
        }
    }
}

// 释放资源
consumer.close();
session.close();
connection.close();
关键注意事项
  • 依赖配置:确保项目引入ActiveMQ客户端和Jakarta Mail依赖(Maven示例):

    <!-- ActiveMQ客户端 -->
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-client</artifactId>
        <version>5.16.7</version>
    </dependency>
    <!-- Jakarta Mail -->
    <dependency>
        <groupId>com.sun.mail</groupId>
        <artifactId>jakarta.mail</artifactId>
        <version>2.0.1</version>
    </dependency>
    
  • 大附件优化:如果附件很大(比如几百MB的视频),建议用ActiveMQ的BlobMessage替代BytesMessage——它支持把大对象存储到文件系统或数据库,不会把整个内容加载到内存:

    BlobMessage blobMsg = session.createBlobMessage(new File("/path/to/large-mms.mime"));
    producer.send(blobMsg);
    

    注意:使用BlobMessage需要在ActiveMQ配置文件中开启相关支持。

  • 消息大小限制:ActiveMQ默认限制单条消息大小为100MB,如果你的MMS超过这个值,需要修改activemq.xml中的systemUsage配置,调整memoryUsage和storeUsage的上限。

内容的提问来源于stack exchange,提问作者sunshine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:29:01