জাভা মেল ব্যবহার করে সংযুক্তিগুলি ডাউনলোড করুন


96

এখন যে আমি সমস্ত বার্তা ডাউনলোড করেছি এবং সেগুলিতে সংরক্ষণ করি

Message[] temp;

আমি কীভাবে সেই বার্তাগুলির প্রত্যেকটির সংযুক্তির তালিকা পেতে পারি

List<File> attachments;

দ্রষ্টব্য: কোনও তৃতীয় পক্ষের লিবস নেই, দয়া করে কেবল জাভামেল।

উত্তর:


111

ব্যতিক্রম পরিচালনা ছাড়া, তবে এখানে যায়:

List<File> attachments = new ArrayList<File>();
for (Message message : temp) {
    Multipart multipart = (Multipart) message.getContent();

    for (int i = 0; i < multipart.getCount(); i++) {
        BodyPart bodyPart = multipart.getBodyPart(i);
        if(!Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()) &&
               StringUtils.isBlank(bodyPart.getFileName())) {
            continue; // dealing with attachments only
        } 
        InputStream is = bodyPart.getInputStream();
        // -- EDIT -- SECURITY ISSUE --
        // do not do this in production code -- a malicious email can easily contain this filename: "../etc/passwd", or any other path: They can overwrite _ANY_ file on the system that this code has write access to!
//      File f = new File("/tmp/" + bodyPart.getFileName());
        FileOutputStream fos = new FileOutputStream(f);
        byte[] buf = new byte[4096];
        int bytesRead;
        while((bytesRead = is.read(buf))!=-1) {
            fos.write(buf, 0, bytesRead);
        }
        fos.close();
        attachments.add(f);
    }
}

4
তবে এক মিনিট অপেক্ষা করুন, আমরা ফাইলটি সংরক্ষণের আগে (বডি পার্ট.জিটডিপজিশন () == পার্ট.এটিচএএমটি) {if কিনা তা পরীক্ষা করে দেখার কথা না, যাতে এটি ইমেলের মূল অংশটি সংরক্ষণ না করে?
ফোলোনে

8
StringUtils.isBlank () ব্যবহার করার চেয়ে পড়া কি স্বাভাবিক হবে না! StringUtils.isNotBlank?
কুচি

এই উত্তর নেস্টেড মাল্টিপার্ট সংযুক্তিগুলি বিবেচনা করে না (উদাহরণস্বরূপ থান্ডারবার্ড সাধারণত ব্যবহৃত হয়)। নেস্টেড মাল্টিপার্ট সংযুক্তিগুলি সন্ধানের জন্য, @ মফি উত্তর দেখুন।
রুসলান স্টেলমাচেনকো

4
স্নিপেটটি হ'ল একটি সুরক্ষা লঙ্ঘন। এটি হাইলাইট করার জন্য আমি স্নিপেট সম্পাদনা করেছি।
rzwitserloot

4
অবশ্যই, এবং তার জন্য ধন্যবাদ। এই স্নিপেটটি কেবল এটি কীভাবে করা যায় তা প্রদর্শনের জন্য ছিল, স্বাভাবিকভাবেই এটি কোনও প্রোডাকশন কোড নয়
ডেভিড রবিনউইজ

33

প্রশ্নটি খুব পুরানো, তবে এটি কারও সাহায্য করবে। আমি ডেভিড রবিনোভিটসের উত্তরটি প্রসারিত করতে চাই।

if(!Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()))

সমস্ত প্রত্যাশা যেমনটি আপনি প্রত্যাশা করেন তা ফেরত দেওয়া উচিত নয়, কারণ আপনার এমন মেল থাকতে পারে যেখানে মিশ্র অংশটি সংজ্ঞায়িত স্বভাব ছাড়াই রয়েছে।

   ----boundary_328630_1e15ac03-e817-4763-af99-d4b23cfdb600
Content-Type: application/octet-stream;
    name="00000000009661222736_236225959_20130731-7.txt"
Content-Transfer-Encoding: base64

সুতরাং এই ক্ষেত্রে, আপনি ফাইলের নামও পরীক্ষা করতে পারেন। এটার মত:

if (!Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()) && StringUtils.isBlank(part.getFileName())) {...}

সম্পাদনা

উপরে বর্ণিত শর্তটি ব্যবহার করে পুরো কার্যকরী কোড রয়েছে .. কারণ প্রতিটি অংশ অন্য অংশগুলিকে আবদ্ধ করতে পারে এবং সংযুক্তিটি নীড়যুক্ত করা উচিত, পুনরাবৃত্তি সমস্ত অংশের মধ্য দিয়ে যেতে ব্যবহার করা হয়

public List<InputStream> getAttachments(Message message) throws Exception {
    Object content = message.getContent();
    if (content instanceof String)
        return null;        

    if (content instanceof Multipart) {
        Multipart multipart = (Multipart) content;
        List<InputStream> result = new ArrayList<InputStream>();

        for (int i = 0; i < multipart.getCount(); i++) {
            result.addAll(getAttachments(multipart.getBodyPart(i)));
        }
        return result;

    }
    return null;
}

private List<InputStream> getAttachments(BodyPart part) throws Exception {
    List<InputStream> result = new ArrayList<InputStream>();
    Object content = part.getContent();
    if (content instanceof InputStream || content instanceof String) {
        if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()) || StringUtils.isNotBlank(part.getFileName())) {
            result.add(part.getInputStream());
            return result;
        } else {
            return new ArrayList<InputStream>();
        }
    }

    if (content instanceof Multipart) {
            Multipart multipart = (Multipart) content;
            for (int i = 0; i < multipart.getCount(); i++) {
                BodyPart bodyPart = multipart.getBodyPart(i);
                result.addAll(getAttachments(bodyPart));
            }
    }
    return result;
}

এক্সপ্রেশন ফাইল খালি বা জন্য পরীক্ষা করে null। এটা কি ঠিক?
কের্তিভাসন

অক্টোপাস: হ্যাঁ একটি CharSequence খালি নয় কিনা তা পরীক্ষা করে (""), নাল নয় এবং কেবল সাদা স্থান নয়।
মেফি

আরে আপনি কীভাবে তালিকা <ইনপুটস্ট্রিম> কে তালিকায় <ফাইল> রূপান্তর করবেন তা বলতে পারেন?
কুমুদা

কুমুন্ডা: হাই, আপনার সেই তালিকাটি পুনরাবৃত্তি করা উচিত এবং org.apache.commons.io.FileUtils.copyInputStreamToFile (ইনপুটস্ট্রিম উত্স, ফাইল গন্তব্য) এবং প্রতিটি ফাইল অন্য সংগ্রহের সাথে যুক্ত করা উচিত। আপনি যদি পেয়ারা ব্যবহার করেন তবে তালিকা (ট্রান্সফর্ম) (...) যাচাই করুন যা আপনি পুনরাবৃত্তির ইনস্টড ব্যবহার করতে পারেন (প্রতিটি ফাইলের উদাহরণটি কীভাবে শুরু করতে হবে তার উপর নির্ভর করে)
mefi

9

আপনি সংযুক্তি ফাইলটি সংরক্ষণ করুন এমন কোডের জন্য কিছু সময় বাঁচানোর জন্য:

জাভাক্স মেল সংস্করণ 1.4 এবং এর পরে, আপনি বলতে পারেন

// SECURITY LEAK - do not do this! Do not trust the 'getFileName' input. Imagine it is: "../etc/passwd", for example.
// bodyPart.saveFile("/tmp/" + bodyPart.getFileName());

পরিবর্তে

    InputStream is = bodyPart.getInputStream();
    File f = new File("/tmp/" + bodyPart.getFileName());
    FileOutputStream fos = new FileOutputStream(f);
    byte[] buf = new byte[4096];
    int bytesRead;
    while((bytesRead = is.read(buf))!=-1) {
        fos.write(buf, 0, bytesRead);
    }
    fos.close();

4
স্পষ্টতই bodyPart প্রথমে রূপান্তর করা উচিত MimeBodyPart, যেমন:((MimeBodyPart) bodyPart).saveFile("/tmp/" + bodyPart.getFileName());
ইয়ার

5

আপনি সাধারণভাবে আইপি এবং কমন্স ল্যাং বরাবর অ্যাপাচি কমন্স মেল এপিআই মাইমেসেজেজ পার্সার - getAttachmentList () ব্যবহার করতে পারেন ।

MimeMessageParser parser = ....
parser.parse();
for(DataSource dataSource : parser.getAttachmentList()) {

    if (StringUtils.isNotBlank(dataSource.getName())) {}

        //use apache commons IOUtils to save attachments
        IOUtils.copy(dataSource.getInputStream(), ..dataSource.getName()...)
    } else {
        //handle how you would want attachments without file names
        //ex. mails within emails have no file name
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.