본문 바로가기

Java Mail/Gmail SMTP & JavaMail

Gmail SMTP Server를 이용한 메일전송 예제 (무료 SMTP & Authentication)

Gmail, Authentication in JavaMail


JavaMail_Intro_송수신_html_첨부.ppt

JavaMail 1.4.3
:http://java.sun.com/products/javamail/downloads/index.html 

javamail-1.4.3.zip


JavaMail 1.4.4 http://www.oracle.com/technetwork/java/index-138643.html
javamail1_4_4.zip


JAF 1.1.1: http://java.sun.com/products/javabeans/jaf/downloads/index.html

JavaMail 1.5
http://www.oracle.com/technetwork/java/javamail/javamail145-1904579.html
JAF는 Java SE 6이상의 버전을 사용할 경우 이미 포함되어 있으므로 다운로드할 필요가 없다.

javamail1_4_5.zip


웹프로젝트에서 Tomcat과 JavaMail API를 사용하는 경우에 간혹 Tomcat에서 javax.mail.Authenticator 클래스를 찾지 못하는 현상이 있을 수 있는데, 이때는 mail.jar, activation.jar Tomcat/common/lib/ 안에 복사해 주면 된다.

Gmail 에서 제공하는 SMTP 사용을 위한 Gmail 계정 설정 참고 http://micropilot.tistory.com/category/Java%20Mail/Gmail%20Account


Gmail.java

import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
import java.io.*;
import java.util.*;
import java.security.Security;

public class Gmail
{
 public static void main(String[] args) 
 {
  Properties p = new Properties();
  p.put("mail.smtp.user", "gmail_id@gmail.com"); // Google계정@gmail.com으로 설정
  p.put("mail.smtp.host", "smtp.gmail.com");
  p.put("mail.smtp.port", "465");
  p.put("mail.smtp.starttls.enable","true");
  p.put( "mail.smtp.auth", "true");

  p.put("mail.smtp.debug", "true");
  p.put("mail.smtp.socketFactory.port", "465"); 
  p.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 
  p.put("mail.smtp.socketFactory.fallback", "false");

  //Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

  try {
   Authenticator auth = new SMTPAuthenticator();
   Session session = Session.getInstance(p, auth);
   session.setDebug(true); // 메일을 전송할 때 상세한 상황을 콘솔에 출력한다.

   //session = Session.getDefaultInstance(p);
   MimeMessage msg = new MimeMessage(session);
   String message = "Gmail SMTP 서버를 이용한 JavaMail 테스트";
   msg.setSubject("Gmail SMTP 서버를 이용한 JavaMail 테스트");
   Address fromAddr = new InternetAddress("gmail_id@gmail.com"); // 보내는 사람의 메일주소
   msg.setFrom(fromAddr);
   Address toAddr = new InternetAddress("paran_id@paran.com");  // 받는 사람의 메일주소
   msg.addRecipient(Message.RecipientType.TO, toAddr); 
   msg.setContent(message, "text/plain;charset=KSC5601");
   System.out.println("Message: " + msg.getContent());
   Transport.send(msg);
   System.out.println("Gmail SMTP서버를 이용한 메일보내기 성공");
  }
  catch (Exception mex) { // Prints all nested (chained) exceptions as well 
   System.out.println("I am here??? ");
   mex.printStackTrace(); 
  } 
 }

 private static class SMTPAuthenticator extends javax.mail.Authenticator {

  public PasswordAuthentication getPasswordAuthentication() {
   return new PasswordAuthentication("gmail_id", "gmail_pwd"); // Google id, pwd, 주의) @gmail.com 은 제외하세요
  }
 } 
}




GoogleTest.java(다수에게 메일을 전송하는 경우)

import java.security.Security;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class GoogleTest {

 private static final String SMTP_HOST_NAME = "smtp.gmail.com";
 private static final String SMTP_PORT = "465";
 private static final String emailMsgTxt = "Gmail SMTP 서버를 사용한 JavaMail 테스트";
 private static final String emailSubjectTxt = "Gmail SMTP 테스트";
 private static final String emailFromAddress = "cwisky@yahoo.com";
 private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
 private static final String[] sendTo = { "cwisky@navy.com"}; // 수신자가 다수일 경우를 가정해서 배열을 사용함


 public static void main(String args[]) throws Exception {

  Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

  new GoogleTest().sendSSLMessage(sendTo, emailSubjectTxt, emailMsgTxt, emailFromAddress);
  System.out.println("Sucessfully Sent mail to All Users");
 }

 public void sendSSLMessage(String recipients[], String subject,
 String message, String from) throws MessagingException {
  boolean debug = true;

  Properties props = new Properties();
  props.put("mail.smtp.host", SMTP_HOST_NAME);
  props.put("mail.smtp.auth", "true");
  props.put("mail.debug", "true");
  props.put("mail.smtp.port", SMTP_PORT);
  props.put("mail.smtp.socketFactory.port", SMTP_PORT);
  props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
  props.put("mail.smtp.socketFactory.fallback", "false");

  Session session = Session.getDefaultInstance(props,
   new javax.mail.Authenticator() {

    protected PasswordAuthentication getPasswordAuthentication() {
     return new PasswordAuthentication("gmail_id", "gmail_pwd");
    }
   }
  );

  session.setDebug(debug);

  Message msg = new MimeMessage(session);
  InternetAddress addressFrom = new InternetAddress(from);
  msg.setFrom(addressFrom);

  InternetAddress[] addressTo = new InternetAddress[recipients.length];
  for (int i = 0; i < recipients.length; i++) {
   addressTo[i] = new InternetAddress(recipients[i]);
  }
  msg.setRecipients(Message.RecipientType.TO, addressTo);

  // Setting the Subject and Content Type
  msg.setSubject(subject);
  msg.setContent(message, "text/plain;charset=KSC5601");
  Transport.send(msg);
 }
}


GMail SMTP 서버를 이용하여 텍스트와 첨부파일을 전송하는 예제 프로그램

package mail;

import java.io.File;
import java.security.Security;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class GmailSMTP {

 private static final String SMTP_HOST_NAME = "smtp.gmail.com";
 private static final String SMTP_PORT = "465";
 private static final String emailMsgTxt = "Gmail SMTP 서버를 사용한 JavaMail 테스트";
 private static final String emailSubjectTxt = "Gmail SMTP 테스트";
 private static final String emailFromAddress = "google_id@gmail.com";
 private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
 private static final String[] sendTo = { "paran_id@paran.com"};


 public static void main(String args[]) throws Exception {

  Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

  new GmailSMTP().sendSSLMessage(sendTo, emailSubjectTxt, emailMsgTxt, emailFromAddress);
  System.out.println("Sucessfully Sent mail to All Users");
 }

 public void sendSSLMessage(String recipients[], String subject,
 String message, String from) throws MessagingException {
  boolean debug = true;

  Properties props = new Properties();
  props.put("mail.smtp.host", SMTP_HOST_NAME);
  props.put("mail.smtp.auth", "true");
  props.put("mail.debug", "true");
  props.put("mail.smtp.port", SMTP_PORT);
  props.put("mail.smtp.socketFactory.port", SMTP_PORT);
  props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
  props.put("mail.smtp.socketFactory.fallback", "false");

  Session session = Session.getDefaultInstance(props,
   new javax.mail.Authenticator() {

    protected PasswordAuthentication getPasswordAuthentication() {
     return new PasswordAuthentication("gmail_id", "gmail_pwd");
    }
   }
  );

  session.setDebug(debug);

  Message msg = new MimeMessage(session);
  InternetAddress addressFrom = new InternetAddress(from);
  msg.setFrom(addressFrom);

  InternetAddress[] addressTo = new InternetAddress[recipients.length];
  for (int i = 0; i < recipients.length; i++) {
   addressTo[i] = new InternetAddress(recipients[i]);
  }
  msg.setRecipients(Message.RecipientType.TO, addressTo);

  // Setting the Subject and Content Type
  msg.setSubject(subject);

  /*텍스트만 전송하는 경우 아래의 2라인만 추가하면 된다. 
  * 그러나 텍스트와 첨부파일을 함께 전송하는 경우에는 아래의 2라인을 제거하고  
  * 대신에 그 아래의 모든 문장을 추가해야 한다.
  **/
  
  //msg.setContent(message, "text/plain;charset=KSC5601");
  //Transport.send(msg);
  
  /* 텍스트와 첨부파일을 함께 전송하는 경우에는 위의 2라인을 제거하고 아래의 모든 라인을 추가한다.*/
  // Create the message part
  BodyPart messageBodyPart = new MimeBodyPart();
 
  // Fill the message
  messageBodyPart.setText("테스트용 메일의 내용입니다.");
  Multipart multipart = new MimeMultipart();
  multipart.addBodyPart(messageBodyPart);
 
  // Part two is attachment
  messageBodyPart = new MimeBodyPart();
  File file = new File("C:/append.txt");
  FileDataSource fds = new FileDataSource(file);
  messageBodyPart.setDataHandler(new DataHandler(fds));

  String fileName = fds.getName(); // 한글파일명은 영문으로 인코딩해야 첨부가 된다.
  fileName = new String(fileName.getBytes("KSC5601"), "8859_1");
  messageBodyPart.setFileName(fileName);

  multipart.addBodyPart(messageBodyPart);
 
  // Put parts in message
  msg.setContent(multipart);
 
  // Send the message
  Transport.send(msg);
 
  System.out.println("E-mail successfully sent!!"); 
 }
}



위의 내용으로 오류가 발생한다면 아래처럼......

package mail;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;

import java.io.*;
import java.util.*;
import java.security.Security;

public class GMail
{
 public static void main(String[] args) 
 {
  Properties p = new Properties();
  p.put("mail.smtp.user", "myid@gmail.com"); // Google계정 아이디@gmail.com으로 설정
  p.put("mail.smtp.host", "smtp.gmail.com");
  p.put("mail.smtp.port", "465");
  p.put("mail.smtp.starttls.enable","true");
  p.put( "mail.smtp.auth", "true");

  p.put("mail.smtp.debug", "true");
  p.put("mail.smtp.socketFactory.port", "465"); 
  p.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 
  p.put("mail.smtp.socketFactory.fallback", "false");

  //Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

  try {
   Authenticator auth = new SMTPAuthenticator();
   Session session = Session.getInstance(p, auth);
   session.setDebug(true); // 메일을 전송할 때 상세한 상황을 콘솔에 출력한다.

   //session = Session.getDefaultInstance(p);
   MimeMessage msg = new MimeMessage(session);
   String message = "Gmail SMTP 서버를 이용한 JavaMail 테스트";
   msg.setSubject("Gmail SMTP 서버를 이용한 JavaMail 테스트");
   Address fromAddr = new InternetAddress("google아이디@gmail.com"); // 보내는 사람의 메일주소
   msg.setFrom(fromAddr);
   Address toAddr = new InternetAddress("수신자아이디@paran.com");  // 받는 사람의 메일주소
   msg.addRecipient(Message.RecipientType.TO, toAddr); 
   /*
   msg.setContent(message, "text/plain;charset=KSC5601");
   System.out.println("Message: " + msg.getContent());
   Transport.send(msg);
   */
   BodyPart messageBodyPart = new MimeBodyPart();
   
   // Fill the message
   messageBodyPart.setText("Java Mail API를 이용하여 첨부파일을 테스트합니다.");
   Multipart multipart = new MimeMultipart();
   multipart.addBodyPart(messageBodyPart);
  
   // Part two is attachment
   messageBodyPart = new MimeBodyPart();
   File file = new File("C:/log.txt");
   FileDataSource fds = new FileDataSource(file);
   messageBodyPart.setDataHandler(new DataHandler(fds));
   messageBodyPart.setFileName(fds.getName());
   multipart.addBodyPart(messageBodyPart);
  
   // Put parts in message
   msg.setContent(multipart, "text/plain;charset=KSC5601");
  
   // Send the message
   Transport.send(msg);
   System.out.println("Gmail SMTP서버를 이용한 메일보내기 성공");
  }
  catch (Exception mex) { // Prints all nested (chained) exceptions as well 
   System.out.println("I am here??? ");
   mex.printStackTrace(); 
  } 
 }

 private static class SMTPAuthenticator extends javax.mail.Authenticator {

  public PasswordAuthentication getPasswordAuthentication() {
   return new PasswordAuthentication("구글아이디", "구글암호"); // Google id, pwd
  }
 } 
}



Gmail_POP3.java (Gmail계정에 POP3프로토콜을 사용하여 접속하고 자신의 계정에 저장되어 있는 메일을 가져오는 예)

package mail;
public class GMailPOP3 {
 
    static final String USERNAME = "gmail_id@gmail.com";
    static final String PASSWORD = "00000000";
    
    public GMailPOP3() {}
    
    public static void main(String[] args) {
     
         try {
             GMailUtilities gmail = new GMailUtilities();
            gmail.setUserPass(USERNAME, PASSWORD); // Gmail 계정 메일주소, 암호
            gmail.connect();
            gmail.openFolder("INBOX");
            
            int totalMessages = gmail.getMessageCount();
            int newMessages = gmail.getNewMessageCount();
            
            System.out.println("Total messages = " + totalMessages);
            System.out.println("New messages = " + newMessages);
            System.out.println("-------------------------------");
            
            //Uncomment the below line to print the body of the message. 
            //Remember it will eat-up your bandwidth if you have 100's of messages.            
            //gmail.printAllMessageEnvelopes();
            //gmail.printAllMessages();
            POP3DTO[] dtos = gmail.getAllMessages();
            for(int i=0;i<dtos.length;i++){
             pr(dtos[i].getFrom().toString());
             pr(dtos[i].getSubject());
             pr(dtos[i].getSentDate().toString());
            }
            
        } catch(Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }
    private static void pr(String str){
     System.out.println(str);
    }
}



GmailUtilities.java

package mail;
import com.sun.mail.pop3.POP3SSLStore;
import com.sun.mail.util.BASE64DecoderStream;

import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
// 메일헤더에 포함되는 [FROM, TO, 첨부파일명]은 RFC2047으로 인코딩되어
//  전달되므로 이들 항목이 한글일 경우에는 다시 디코딩하는 것에 주의하세요.
//  예) MimeUtility.decodeText(encodeText)

public class GMailUtilities {
    
    private Session session = null;
    private Store store = null;
    private String username, password;
    private Folder folder;
    
    public GMailUtilities() { }
    
    public void setUserPass(String username, String password) {
        this.username = username;
        this.password = password;
    }
    
    public void connect() throws Exception {
        String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
        
        Properties pop3Props = new Properties();
        
        pop3Props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
        pop3Props.setProperty("mail.pop3.socketFactory.fallback", "false");
        pop3Props.setProperty("mail.pop3.port",  "995");
        pop3Props.setProperty("mail.pop3.socketFactory.port", "995");
        
        URLName url = new URLName("pop3", "pop.gmail.com", 995, "",
                username, password);
        
        session = Session.getInstance(pop3Props, null);
        store = new POP3SSLStore(session, url);
        store.connect();
    }
    
    public void openFolder(String folderName) throws Exception {
        // Open the Folder
        folder = store.getDefaultFolder();
        folder = folder.getFolder(folderName); // INBOX
        
        if (folder == null) {
            throw new Exception("Invalid folder");
        }
        // try to open read/write and if that fails try read-only
        try {
            folder.open(Folder.READ_WRITE);
        } catch (MessagingException ex) {
            folder.open(Folder.READ_ONLY);
        }
    }
    
    public void closeFolder() throws Exception {
        folder.close(false);
    }
    
    public int getMessageCount() throws Exception {
        return folder.getMessageCount();
    }
    
    public int getNewMessageCount() throws Exception {
        return folder.getNewMessageCount();
    }
    
    public void disconnect() throws Exception {
        store.close();
    }
    
    public void printMessage(int messageNo) throws Exception {
        System.out.println("Getting message number: " + messageNo);
        Message m = null;
        try {
            m = folder.getMessage(messageNo);
            dumpEnvelope(m);
        } catch (IndexOutOfBoundsException iex) {
            System.out.println("Message number out of range");
        }
    }
    
    public void printAllMessageEnvelopes() throws Exception {
        // Attributes & Flags for all messages ..
        Message[] msgs = folder.getMessages();
        
        // Use a suitable FetchProfile
        FetchProfile fp = new FetchProfile();
        fp.add(FetchProfile.Item.ENVELOPE);        
        folder.fetch(msgs, fp);
        
        for (int i = 0; i < msgs.length; i++) {
            System.out.println("--------------------------");
            System.out.println("MESSAGE #" + (i + 1) + ":");
            dumpEnvelope(msgs[i]);
        }
    }
    
    public void printAllMessages() throws Exception {
        // Attributes & Flags for all messages ..
        Message[] msgs = folder.getMessages();
        
        // Use a suitable FetchProfile
        FetchProfile fp = new FetchProfile();
        fp.add(FetchProfile.Item.ENVELOPE);        
        folder.fetch(msgs, fp);
        
        for (int i = 0; i < msgs.length; i++) {
            System.out.println("--------------------------");
            System.out.println("MESSAGE #" + (i + 1) + ":");
            dumpEnvelope(msgs[i]);
        }
    }

    public POP3DTO[] getAllMessages() throws Exception {
     POP3DTO[] dtos = null;
        // Attributes & Flags for all messages ..
        Message[] msgs = folder.getMessages();
        
        dtos = new POP3DTO[msgs.length];
        
        // Use a suitable FetchProfile
        FetchProfile fp = new FetchProfile();
        fp.add(FetchProfile.Item.ENVELOPE);        
        folder.fetch(msgs, fp);
        
        for (int i = 0; i < msgs.length; i++) {
         dtos[i] = new POP3DTO();
         dtos[i].setFrom(MimeUtility.decodeText(msgs[i].getFrom()[0].toString()));
         dtos[i].setSubject(msgs[i].getSubject());
         dtos[i].setSentDate(msgs[i].getSentDate());
        }
        return dtos;
    }
    
    public static void dumpEnvelope(Message m) throws Exception {     
        pr(" ");
        Address[] a;
        // FROM
        if ((a = m.getFrom()) != null) {
            for (int j = 0; j < a.length; j++)
                pr("FROM: " + MimeUtility.decodeText(a[j].toString()));
        }
        
        // TO
        if ((a = m.getRecipients(Message.RecipientType.TO)) != null) {
            for (int j = 0; j < a.length; j++) {
                pr("TO: " + MimeUtility.decodeText(a[j].toString()));                
            }
        }
        
        // SUBJECT
        pr("SUBJECT: " + m.getSubject());
        
        // DATE
        Date d = m.getSentDate();
        pr("SendDate: " +
                (d != null ? d.toString() : "UNKNOWN"));
        
        // CONTENT TYPE
        String contentType = m.getContentType();
        pr("CONTENT TYPE: " +contentType);
        
        // CONTENT
        // 단순한 구조의 메일은 MimeMessage 안에 바로 텍스트(text/plain, text/html)가 포함되는 구조로 되어있지만,
        //  대부분의 메일 내용은 JavaMail 개발자 입장에서 보았을 때 메일본문이 바로 발견되는 것이 아니라
        //  MimeMessage 내부의 Multipart 안에 몇개의 BodyPart로 구성되어 있고 각 BodyPart 안에는 첨부파일
        //  이 있으며, 어떤 BodyPart 안에는 또 다시 Multipart가 포함되고 그 안에 일반텍스(text/plain)나
        //  HTML(text/html)형식의 메일 본문이 포함되어 있는 경우도 많다.

        pr("Message.getContent()-------------------");
        pr("CONTENT: "+ m.getContent());
 
        // 첨부파일
        if( m.isMimeType("multipart/*") ) {
         System.out.println("첨부파일이 포함된 메일");
         handleMultipart(m);
         //pr(str);
        }
    }
    
    // 첨부파일을 다루는 메소드, 첨부파일을 로컬시스템에 다운로드한다 
    //  첨부파일은 Base64 인코딩된 경우와 그렇지 않은 경우로 구분하여 스트림을 사용한다
    //  MimeMultipart 안에는 다수개의 MimeBodypart(파트)가 포함될 수 있고 각 파트 안에는
    //  텍스트(text/plain, text/html), 첨부파일, 또 다른 MimeMultipart 등이 로 존재한다.
    //  한개의 파트 안에 또 다른 멀티파트가 포함되어 있을 경우에는 그 멀티파트에 포함되어 있는
    //  것은 텍스트나 HTML 이었다.

    public static String handleMultipart(Message msg) {
        String content = null;
        try {
            String disposition;
            BodyPart part;
            Multipart mp = (Multipart) msg.getContent();   // 멀티파트 구함
            
            int mpCount = mp.getCount();
            pr("멀티파트 안의 아이템 수:"+mpCount);
            for (int m = 0; m < mpCount; m++) {
                part = mp.getBodyPart(m);      // 멀티파트내의 한개 파트 구함
                String partContentType = part.getContentType();
                disposition = part.getDisposition(); // 파트의 성격
                Object partContent = part.getContent();   // 한개 파트의 내용을 구함
                pr(m+1+"번 파트-----disposition:"+disposition);
                // 멀티파트 내의 한개 파트가  메일 본문인 경우
                if(partContentType.startsWith("text/")&& disposition==null){
                 String txtContent = part.getContent().toString();
                 pr("멀티파트 안의 본문:"+txtContent);
                 
                } // 멀티파트 내의 한개 파트가 첨부파일이고 파일명이 한글인 경우
                else if(partContent instanceof BASE64DecoderStream)
                {
                 BASE64DecoderStream ds = (BASE64DecoderStream)partContent;
                  String filename = part.getFileName();
                  // RFC 2047으로 인코딩된 문자열을 다시 디코딩한다. 
                  filename = MimeUtility.decodeText(filename);
                  pr("한글 파일명:"+filename);
                  byte[] buf = new byte[ds.available()];
                  ds.read(buf);
                  ds.close();

                  // 첨부파일을 로컬시스템에 다운로드한다
                  saveLocal(filename, buf);
                }
                else if (disposition != null && 
                  (disposition.equals(Part.INLINE)
                   ||disposition.equals(Part.ATTACHMENT)))/*첨부파일명이 영문인 경우*/
                {
                    String filename = part.getFileName();
                    filename = MimeUtility.decodeText(filename);
                    pr("영문 파일명:"+filename);
                    InputStream is = part.getInputStream();
                    byte[] buf = new byte[is.available()];
                    is.read(buf);
                    is.close();
                    saveLocal(filename, buf);
                } else { // 한개의 파트 안에 다시 멀티 파트가 포함된 경우, 대부분 텍스트나 HTML
                    if(partContent instanceof MimeMultipart){
                     MimeMultipart multipart = (MimeMultipart)partContent;
                     int cnt = multipart.getCount();
                     for(int i=0;i<cnt;i++){
                      BodyPart bp = multipart.getBodyPart(i);
                      pr("파트 안의 멀티파트 정보:"+bp.getContentType());
                      pr("파트 안의 멀티파트 내용:"+bp.getContent());
                     }
                    }
                }
            }// end of for()
        } catch (Exception ex) {
         ex.printStackTrace();
        }
        return content;
    }
    
    static String indentStr = "                                               ";
    static int level = 0;
    
    //  Print a, possibly indented, string.
    public static void pr(String s) {
        
        System.out.print(indentStr.substring(0, level * 2));
        System.out.println(s);
    }
    
    private static void saveLocal(String filename, byte[]buf){
     FileOutputStream fout = null;
     try{
      fout = new FileOutputStream("C:/append/"+filename);
      fout.write(buf);
      fout.close();
     }catch(Exception fne){
      fne.printStackTrace();
     }
    }
}