如何从包含SOAP消息字符串的MIME附件中提取SOAP消息
从MIME附件中提取SOAP消息的方法
根据你提供的MIME结构,这里有两种实用的提取方式:手动临时处理和编程批量处理,具体如下:
一、手动提取(适合临时单条处理)
如果只是偶尔处理一条消息,手动操作非常直接:
- 第一步:定位到以
------=_Part_开头的MIME分隔线,找到包含Content-Type: application/soap+xml; charset=utf-8的那个部分 - 第二步:提取该部分中从
<s:Envelope>开始到</s:Envelope>结束的所有内容,注意不要包含分隔线和Content-Type等头信息 - 小提示:SOAP消息的换行不影响XML结构,直接把拆分的行拼接起来即可正常使用
二、编程提取(适合批量或自动化处理)
如果需要处理大量这类消息,用代码解析MIME结构是更高效的方式,这里给出两种主流语言的实现示例:
Python实现(使用标准库email)
Python的标准email模块可以完美解析MIME多部分消息,不需要额外安装依赖:
import email from email.policy import default # 替换为你的实际MIME内容字符串 mime_content = """------=_Part_10_182815722.1522086113658 Content-Type: application/soap+xml; charset=utf-8 <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"> <s:Header> ..... </s:Header> <s:Body> ... </s:Body> </s:Envelope> ------=_Part_10_182815722.1522086113658 Content-Type: application/octet-stream Content-ID: <6357420601498...""" # 解析MIME消息 msg = email.message_from_string(mime_content, policy=default) # 遍历所有MIME部分,寻找SOAP类型的内容 for part in msg.walk(): if part.get_content_type() == "application/soap+xml": # 自动解码并按指定字符集转换为字符串 soap_msg = part.get_payload(decode=True).decode(part.get_content_charset() or "utf-8") print("提取到的SOAP消息:") print(soap_msg) break
Java实现(使用Apache Mime4j)
如果用Java处理,可以使用Apache Mime4j库(需先在项目中引入对应依赖):
import org.apache.james.mime4j.MimeException; import org.apache.james.mime4j.parser.MimeStreamParser; import org.apache.james.mime4j.stream.BodyDescriptor; import org.apache.james.mime4j.stream.Field; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; public class SoapMessageExtractor { public static void main(String[] args) throws IOException, MimeException { // 替换为你的实际MIME内容字符串 String mimeContent = "你的MIME内容字符串"; InputStream inputStream = new ByteArrayInputStream(mimeContent.getBytes()); MimeStreamParser parser = new MimeStreamParser(); parser.setContentHandler(new org.apache.james.mime4j.parser.ContentHandler() { private boolean isSoapPart = false; @Override public void field(Field field) throws MimeException { // 标记当前部分是否为SOAP类型 if ("Content-Type".equalsIgnoreCase(field.getName()) && field.getBody().startsWith("application/soap+xml")) { isSoapPart = true; } } @Override public void body(BodyDescriptor bd, InputStream is) throws MimeException, IOException { if (isSoapPart) { // 读取并拼接SOAP消息内容 byte[] buffer = new byte[1024]; int bytesRead; StringBuilder soapBuilder = new StringBuilder(); while ((bytesRead = is.read(buffer)) != -1) { soapBuilder.append(new String(buffer, 0, bytesRead, bd.getCharset())); } System.out.println("提取到的SOAP消息:"); System.out.println(soapBuilder.toString()); } } // 实现其他未用到的接口方法 @Override public void startHeader() throws MimeException {} @Override public void endHeader() throws MimeException {} @Override public void startMultipart() throws MimeException {} @Override public void endMultipart() throws MimeException {} @Override public void startMessage() throws MimeException {} @Override public void endMessage() throws MimeException {} @Override public void startBodyPart() throws MimeException {} @Override public void endBodyPart() throws MimeException {} @Override public void raw(InputStream is) throws MimeException, IOException {} }); parser.parse(inputStream); } }
注意事项
- 部分MIME消息的最后一条分隔线会带有
--,表示消息结束,标准解析库会自动识别,无需额外处理 - 如果SOAP部分设置了
Content-Transfer-Encoding(比如base64),代码中的自动解码逻辑会正确还原原始内容 - 字符集要以Content-Type头中的
charset参数为准,避免出现乱码问题
内容的提问来源于stack exchange,提问作者JackTheKnife
相关产品推荐
相关产品推荐

