cuốn sách gpt4 ai đã làm

JavaMail vận chuyển các tin nhắn MIME nhị phân lớn (rfc3030)

In lại Tác giả: Vũ trụ không gian Thời gian cập nhật: 2023-11-04 13:13:05 25 4
mua khóa gpt4 Nike

Tôi cần trao đổi với một trong các máy chủ thư bằng cách sử dụng RFC3030Đối với tin nhắn mime lớn. Bài tập ban đầu: Tôi cần sử dụng RFC3030 nếu kích thước tin nhắn MIME> 80MB.

Làm cách nào để hiểu rằng JavaMail không thể thực hiện việc này "ngay lập tức"?

Có lẽ tôi có thể tạo một số trình xử lý hoặc tiện ích mở rộng cho JavaMail triển khai RFC3030?

Xin hãy giúp đỡ. Tôi không biết phải làm gì.

câu trả lời hay nhất

xem nhanhSMTPTransportXác nhận: JavaMail cũ đơn giản không hỗ trợ BDAT, nó luôn cố gắng gửi bằng lệnh DATA, như sau:

this.message.writeTo(data(), ignList);
kết thúcData();

Nếu bạn không ngại (và không có lý do pháp lý nào để không làm như vậy) sửa đổi các lớp JDK cốt lõi, bạn có thể ghi đè các phương thức data() và finishData() vì cả hai đều được bảo vệ (mã nguồn từ đây ):

/**
* Gửi lệnh DATA tới máy chủ SMTP và trả về
* một OutputStream mà dữ liệu sẽ được ghi vào.
*
* @kể từ JavaMail 1.4.1
*/
Dữ liệu OutputStream được bảo vệ() ném MessagingException {
khẳng định Thread.holdsLock(this);
issueSendCommand("DATA", 354);
dataStream = new SMTPOutputStream(serverOutput);
trả về luồng dữ liệu;
}

/**
* Chấm dứt dữ liệu đã gửi.
*
* @kể từ JavaMail 1.4.1
*/
protected void finishData() ném IOException, MessagingException {
khẳng định Thread.holdsLock(this);
dataStream.ensureAtBOL();
issueSendCommand(".", 250);
}

để hỗ trợRFC3030 , tôi khuyên bạn trước tiên nên đệm toàn bộ tin nhắn vào ByteArrayĐầu raStream ở giữa. Bạn cần nó để xác định kích thước của tin nhắn cần gửi. nếu "nhỏ" -> thực thi SMTPTransportsẽ làm được. Nếu "lớn", hãy chia byte thành các khối và gửi chúng tới BDATphong cách. Tôi khuyên bạn nên kết thúc bằng độ dài 0 CUỐI CÙNG BDATvà mã

protected void finishData() ném IOException, MessagingException {
khẳng định Thread.holdsLock(this);
dataStream.ensureAtBOL();
issueSendCommand("BDAT 0 CUỐI CÙNG", 250);
}

--biên tập--

Đây là cách tiếp cận đầu tiên rất đơn giản, có rất nhiều điều cần phải làm tốt hơn. Điều quan trọng nhất là luồng đầu ra Việc triển khai sẵn sàng để chặntin nhắn.writeTo() Trong quá trình gửi khối dữ liệu liên tục lấp đầy nó. Việc đệm một byte lớn[] chỉ để chia nó thành các khối sau này là rất rất tệ về mặt chiếm dụng bộ nhớ. Nhưng đọc theo cách này sẽ dễ dàng hơn vì tất cả việc phân đoạn và gửi đều diễn ra ở một nơi. Lưu ý rằng ví dụ này sử dụng sự phản chiếu để truy cập máy chủĐầu ra Các trường trong OracleSMTPTransport . Do đó, với bất kỳ phiên bản JavaMail mới nào, nó có thể bị lỗi bất cứ lúc nào mà không có bất kỳ cảnh báo nào. Ngoài ra, việc xử lý ngoại lệ của tôi hiện không tuân theo RFC-3030 vì nếu BDAT không thành công thì RSET sẽ không được thực hiện.

gói de.janschweizer;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
nhập java.io.StringReader;
nhập java.lang.reflect.Field;

import javax.mail.MessagingException;
nhập javax.mail.Session;
nhập javax.mail.URLName;

nhập com.sun.mail.smtp.SMTPOutputStream;

lớp công khai SMTPTransport mở rộng com.sun.mail.smtp.SMTPTransport {

// Chúng tôi có thể có bản sao của riêng mình - nó chỉ được sử dụng trong các phương thức mà chúng tôi ghi đè.
luồng dữ liệu SMTPOutputStream riêng tư;

bao ByteArrayOutputStream riêng tư;

public SMTPTransport(Phiên phiên, URLName urlname, Chuỗi chuỗi, boolean bool) {
siêu (phiên, tên url, chuỗi, bool);
}

public SMTPTransport(Phiên phiên, URLName urlname) {
siêu (phiên, tên url);
}

Dữ liệu OutputStream được bảo vệ() ném MessagingException {
khẳng định(Thread.holdsLock(this));
if(!supportsExtension("CHUNKING")) {
trả về super.data();
}
baos = new ByteArrayOutputStream();
this.dataStream = new SMTPOutputStream(baos);
trả lại this.dataStream;
}

protected void finishData() ném IOException, MessagingException {
khẳng định(Thread.holdsLock(this));
if(!supportsExtension("CHUNKING")) {
super.finishData();
return;
}
this.dataStream.ensureAtBOL();
dataStream.flush();
BufferedReader br = BufferedReader mới(StringReader mới(Chuỗi mới(baos.toByteArray())));

thử {
// Hack phản ánh BAD
Trường fServerOutput = com.sun.mail.smtp.SMTPTransport.class.getDeclaredField("serverOutput");
fServerOutput.setAccessible(true);
OutputStream os = (OutputStream)fServerOutput.get(this);

// Làm Chunky
ByteArrayOutputStream bchunk = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(bchunk);
Chuỗi dòng = br.readLine();
số dòng int = 0;
while(line != null) {
pw.println(dòng);
if(++số dòng % 5000 == 0) {
pw.flush();
byte[] chunk = bchunk.toByteArray();
sendChunk(os, chunk);
bchunk = new ByteArrayOutputStream();
pw = PrintWriter mới(bchunk);
}
dòng = br.readLine();
}
pw.flush();
byte[] chunk = bchunk.toByteArray();
sendLastChunk(os, chunk);
} catch (Exception e) {
ném MessagingException mới ("ReflectionError", e);
}
}

void void sendChunk(OutputStream os, byte[] chunk) ném MessagingException, IOException {
sendCommand("BDAT "+chunk.length);
os.write(chunk);
os.flush();
int rc = readServerResponse();
nếu(rc != 250) {
ném MessagingException mới ("Có gì đó không ổn");
}
}

void void sendLastChunk(OutputStream os, byte[] chunk) ném MessagingException, IOException {
sendCommand("BDAT "+chunk.length+" LAST");
os.write(chunk);
os.flush();
int rc = readServerResponse();
nếu(rc != 250) {
ném MessagingException mới ("Có gì đó không ổn");
}
}
}

Với META-INF/javamail.providers này

giao thức=smtp; loại=vận chuyển; lớp=de.janschweizer.SMTPTransport nhà cung cấp=Jan Schweizer;

Về việc JavaMail truyền các tin nhắn MIME nhị phân lớn (rfc3030), chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/33777595/

25 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress