- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我需要与其中一台邮件服务器进行交换,使用 RFC3030对于大型 mime 消息。原来的任务是:如果MIME消息大小> 80MB,我需要使用RFC3030。
我怎么理解,JavaMail 不能“从盒子里”做到这一点?
也许我可以为 JavaMail 创建一些实现 RFC3030 的处理程序或扩展?
请帮忙。我不知道该怎么办。
最佳答案
快速浏览SMTPTransport
确认:普通的旧 JavaMail 不支持 BDAT,它总是尝试使用 DATA 命令发送,如下所示:
this.message.writeTo(data(), ignoreList);
finishData();
如果您不害怕(并且没有法律理由不这样做)修改核心 JDK 类,您可以重写方法 data() 和 finishData(),因为它们都受到保护(源代码来自 here ):
/**
* Send the <code>DATA</code> command to the SMTP host and return
* an OutputStream to which the data is to be written.
*
* @since JavaMail 1.4.1
*/
protected OutputStream data() throws MessagingException {
assert Thread.holdsLock(this);
issueSendCommand("DATA", 354);
dataStream = new SMTPOutputStream(serverOutput);
return dataStream;
}
/**
* Terminate the sent data.
*
* @since JavaMail 1.4.1
*/
protected void finishData() throws IOException, MessagingException {
assert Thread.holdsLock(this);
dataStream.ensureAtBOL();
issueSendCommand(".", 250);
}
为了支持RFC3030 ,我建议您首先将整个消息缓冲到 ByteArrayOutputStream
中。您需要它来确定要发送的消息的大小。如果“小”-> 执行 SMTPTransport
会做。如果“大”,则将字节分割成 block 并将它们发送到 BDAT
风格。我建议以 0 长度结束 LAST
BDAT
和代码
protected void finishData() throws IOException, MessagingException {
assert Thread.holdsLock(this);
dataStream.ensureAtBOL();
issueSendCommand("BDAT 0 LAST", 250);
}
--编辑--
这是一个非常简单的第一种方法,还有很多事情需要做得更好。最重要的是 outputStream
的即用即分块实现message.writeTo()
期间发送数据 block 不断地填充它。填充一个大字节[]只是为了稍后将其分割成 block ,这在内存占用方面是非常非常糟糕的。但这种方式更容易阅读,因为所有分块和发送都发生在一个地方。请注意,此示例使用反射来访问 serverOutput
Oracle 中的字段SMTPTransport
。因此,对于任何新版本的 JavaMail,它都可能随时崩溃而不会发出任何警告。另外,我的异常处理暂时不遵循 RFC-3030,因为如果 BDAT 失败,则不会执行 RSET。
package de.janschweizer;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.lang.reflect.Field;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.URLName;
import com.sun.mail.smtp.SMTPOutputStream;
public class SMTPTransport extends com.sun.mail.smtp.SMTPTransport {
//We can have our own copy - it's only used in the methods we override anyways.
private SMTPOutputStream dataStream;
private ByteArrayOutputStream baos;
public SMTPTransport(Session session, URLName urlname, String string, boolean bool) {
super(session, urlname, string, bool);
}
public SMTPTransport(Session session, URLName urlname) {
super(session, urlname);
}
protected OutputStream data() throws MessagingException {
assert(Thread.holdsLock(this));
if(!supportsExtension("CHUNKING")) {
return super.data();
}
baos = new ByteArrayOutputStream();
this.dataStream = new SMTPOutputStream(baos);
return this.dataStream;
}
protected void finishData() throws IOException, MessagingException {
assert(Thread.holdsLock(this));
if(!supportsExtension("CHUNKING")) {
super.finishData();
return;
}
this.dataStream.ensureAtBOL();
dataStream.flush();
BufferedReader br = new BufferedReader(new StringReader(new String(baos.toByteArray())));
try {
//BAD reflection hack
Field fServerOutput = com.sun.mail.smtp.SMTPTransport.class.getDeclaredField("serverOutput");
fServerOutput.setAccessible(true);
OutputStream os = (OutputStream)fServerOutput.get(this);
//Do the Chunky
ByteArrayOutputStream bchunk = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(bchunk);
String line = br.readLine();
int linecount = 0;
while(line != null) {
pw.println(line);
if(++linecount % 5000 == 0) {
pw.flush();
byte[] chunk = bchunk.toByteArray();
sendChunk(os, chunk);
bchunk = new ByteArrayOutputStream();
pw = new PrintWriter(bchunk);
}
line = br.readLine();
}
pw.flush();
byte[] chunk = bchunk.toByteArray();
sendLastChunk(os, chunk);
} catch (Exception e) {
throw new MessagingException("ReflectionError", e);
}
}
private void sendChunk(OutputStream os, byte[] chunk) throws MessagingException, IOException {
sendCommand("BDAT "+chunk.length);
os.write(chunk);
os.flush();
int rc = readServerResponse();
if(rc != 250) {
throw new MessagingException("Something very wrong");
}
}
private void sendLastChunk(OutputStream os, byte[] chunk) throws MessagingException, IOException {
sendCommand("BDAT "+chunk.length+" LAST");
os.write(chunk);
os.flush();
int rc = readServerResponse();
if(rc != 250) {
throw new MessagingException("Something very wrong");
}
}
}
有了这个 META-INF/javamail.providers
protocol=smtp; type=transport; class=de.janschweizer.SMTPTransport; vendor=Jan Schweizer;
关于JavaMail 传输大型二进制 MIME 消息(rfc3030),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33777595/
如果上传的文件没有扩展名,是否必须指定 MIME 类型?换句话说,是否有默认的通用 MIME 类型? 最佳答案 对于未知类型,您可以使用application/octet-stream。 RFC 20
MIME 类型的官方 URN 是否存在? Mozilla Firefox 和其他应用程序使用诸如“urn:mimetype:text/plain”或“urn:mimetype:handler:text
我们有一个由 xyz 网站管理员部署在生产环境中的网站。以下是在两个不同实例中发生错误时 Web 控制台的两个屏幕截图。 我们时断时续地而不是始终如一地面对这个问题。此外,这种情况发生在少数用户而不是
此错误仅在 chrome 中显示。我正在搜索这个问题,但还没有找到 令人满意的解决方案。我附上了该错误的屏幕截图。请为此提出一些想法。 Error image 最佳答案 样式表的 MIME 类型应该是
当我使用 MAMP 托管我的 Drupal 站点时,出现了上述错误。我所有的 HTML 加载,但我的 CSS 没有加载。 拒绝应用来自“http://mysite/sites/default/file
错误信息: jquery.dataTables.min.js:23 未捕获类型错误:无法读取未定义的属性“长度” 在 Ha (jquery.dataTables.min.js:23) 在 HTMLTa
Raw images由相机、扫描仪等生成,通常比 JPEG 图像具有更大的后处理灵活性。 如果我从我的 Web 服务器提供这种文件,我应该使用哪种媒体类型(又名 MIME 类型)? 我对最近的佳能相机
我已经查看了大约 100 个站点,但没有找到任何内容。有些只是 mime 类型值的列表,有些只是对 RFC 的引用,或者或多或少是直接引用它们。 RFC 是难以理解的,每一个都只揭示了大象的一小部分。
我想用 image/*数据 URI 中的 MIME 类型,例如data:image/*;base64,R0lGODlhE...在 元素。 它是否完全符合标准的 MIME 类型? 它会在某些浏览器中引起
我有一个 PHP 脚本,用于下载不同类型的文件(PDF、JPEG、RAR 等)。效果很好,但是我注意到 MIME 类型存在问题。 是否有我可以安全地用于“通用目的”的通用 MIME 类型?我正在考虑所
我的程序使用自己的二进制文件类型,因此我假设我不能使用 MIME 类型文本/纯文本,因为它不是 7 位 ASCII 文件。 我应该将其命名为“application/myappname”吗? 最佳答案
我正在调试一个 MIME 解析器,它无法解析来自一个电子邮件服务的 header 。电子邮件服务包含一个 header ,该 header 由完全位于下一行的字段主体组成,如下所示: Message-
我有一个 Vue.js 项目,当我检查控制台时发现以下问题: Refused to apply style from 'http://localhost:8080/dist/cropper.min.c
friend 们,我花了一整天的时间寻找这个问题的解决方案,但我一直无法修复它。当我为生产构建它时,在开发模式下(没有缩小和其他东西)它在本地主机上运行良好,但是当我在 dist 文件夹中获取我的文件
Swagger 默认支持 application/json 作为 Content 类型。如果我想添加其他内容类型,则需要在 swagger JSON 文件中更新“生产”或“消费”字段。客户可以发送任何
我的网络服务生成并返回一个 .tex 文件。我想在 http-header 中提供正确的 mimetype。 除了here我没找到这么多,我在其中找到 application/x-tex。这是要坚持的
我需要区分不同类型的 HTML 模板,例如来自 Handlebars 模板的 FreeMarker。由于模板在数据库中(所以它们不是文件,即没有文件名或扩展名)我想使用 MIME 类型来识别它们。 对
我想知道 iWork 页面的 mime 类型是什么?以及 iWork 套件中其余软件的 mime 类型是什么?我在网上环顾四周,没有看到任何地方。 最佳答案 我最近需要这个来工作,结果只是上传了一些文
我正在构建一个 mime 类型的猜测器,我正在使用 mimetype命令来检查我的结果。对于日志文件,它返回 text/x-log .我在这些列表中没有看到这种 mime 类型: http://svn
有谁知道 Markdown 是否存在 MIME 类型?我猜是 text/plain,但是有更具体的吗? 最佳答案 tl;dr:text/markdown 自 2016 年 3 月起 2016 年 3
我是一名优秀的程序员,十分优秀!