目前分類:POJO (4)

瀏覽方式: 標題列表 簡短摘要
有一陣子沒用 java mail了,都有點忘了呵呵;java mail 經過幾年也有了一些容易感覺出來的變化

相同的:
一樣要用到 jaf 這個 framework (activation.jar) 跟 mail.jar (也可用單獨的 imap.jar, pop3.jar, smtp.jar.. 等);只是版本變新了

不同的:
選擇變多了,多了 jakarta 的 common-email-xxx.jar (分類在 common 專案中),感覺上好像有讓 java mail 變好用了 :-)

以下是直接用 java mail 的 code, 最原始的來源好像是用 java 附的 sample 中的一支 mail class 去改的

public String Send() {
String errMsg = null;

// create some properties and get the default Session
Properties props = System.getProperties();
props.put("mail.smtp.smtpServer", smtpServer);

Session session = Session.getDefaultInstance(props, null);
session.setDebug(debug);

try {
// create a message
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(from));
InternetAddress[] address = {new InternetAddress(to)};
msg.setRecipients(Message.RecipientType.TO, address);

if (cc != null) {
InternetAddress[] addressCC = {new InternetAddress(cc)};
msg.setRecipients(Message.RecipientType.CC, addressCC);
}
msg.setSubject(subject);

// create the Multipart and its parts to it
Multipart mp = new MimeMultipart();

// create and fill the first message part
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setContent(msgContext,"text/html");

mp.addBodyPart(mbp1);

if (attach.isEmpty()==false) {
for (Enumeration e=attach.elements(); e.hasMoreElements();) {
String file = (String)e.nextElement();

file = attFilePath + file;
FileDataSource fds = new FileDataSource(file);

// create the second message part
MimeBodyPart mbp2 = new MimeBodyPart();
mbp2.setDataHandler(new DataHandler(fds));
mbp2.setFileName(fds.getName());
mp.addBodyPart(mbp2);
}
}

// add the Multipart to the message
msg.setContent(mp);

// set the Date: header
msg.setSentDate(new Date());

// send the message
Transport.send(msg);

errMsg = "true";

}
catch (MessagingException mex) {
mex.printStackTrace();
Exception ex = null;
if ((ex = mex.getNextException()) != null) {
errMsg = "message : " + ex.toString();
}
}

return errMsg;
}


以下是用 common-email 的 code

public static void send(Hashtable ht, Staff me, ArticleForm form,

String host, String serv, String contextPath) {

HtmlEmail email = new HtmlEmail();
email.setHostName(host);

try {
String subject = ((ArticleForm) form).getCreator() + " 發佈訊息";
email.setSubject(subject);

StringBuffer msg = new StringBuffer("");
msg.append("");
msg.append(((ArticleForm) form).getTitle());
msg.append("... (按我)");
msg.append("
");
msg.append("
");
log.debug(msg.toString());

email.setHtmlMsg(zhtw2en(msg.toString()));
String sender = me.getEmail() + Tokens.EMAIL_SEP + serv;
log.debug(sender);

email.setFrom(sender, "Me");
email.addCc(sender);

List list = new Vector();
Set set = ht.keySet();
Iterator it = set.iterator();
while (it.hasNext()) {
String s = (String) it.next();
Staff u = (Staff) ht.get(s);
if (u.getName().equals(me.getName()))
continue;

// log.debug(u.getEmail() + "," + u.getIp());
if ((u.getEmail() != null) && (u.getEmail().length() > 0)) {
String em = u.getEmail() + Tokens.EMAIL_SEP + serv;
log.debug(em);

try {
list.add(new InternetAddress(em));
} catch (AddressException e) {
log.error(e);
}
}
}
email.setTo(list);
email.send();
} catch (EmailException e) {
log.error("mail:" + e);
}
}
二段 code 都是用 mail 寄送 html 格式的訊息,另
1。要下載 jaf & mai.jar 參考資料:JavaWorld (sun 網站也有)
2。要執行 mail 的 class 要加入 jaf & mail 的 jar file 在 CLASSPATH
3。在 code 中直接用中文實在不是好習慣,因為在 cross platform 時會有問題

identical 發表在 痞客邦 留言(0) 人氣()

其實很少寫需要單獨執行的 java 程式,有幾個原因吧
1。因為我都是開發 web application
2。java 要在 console 下執行實在很麻煩
3。tool 用多了(我都是用 eclipse, 也用過幾天 Gel),要改用 vi or notepad 都有點太...
anyway, 還是有需要的時候

有關於 Running JAR-Packaged Software
要於 jar file 中加入特定的資訊
1.先建立一個 text file (ex.mainClass) , 並將
"Main-Class: myClassName " 或其他資訊加入
ps. 如果執行時要使用其他的 jar file 裡,要另外加入:
"Class-Path: extendJar...."
2.再用 jar 這支 tool 來產生 jar file,語法如下:
jar cmf mainClass jarName.jar classList
3.完成以上的步驟我們就有可執行的 jar file 了
java -jar jarName.jar

參考資料:sun 網站,忘了 url, sun forum

後記:eclipse 好像有一個選項可以在產生 jar file 的時候一併加入 Main-Class 印像中好像用過,呵呵

identical 發表在 痞客邦 留言(0) 人氣()

終於正式使用 jfreechar 了,真的好用

這是成果,不過遇到了一些困擾

  • tomcat+struts+tile+jfreechart 使用 response.getOutputStream() 會有問題
  • 使用 FileOutputStream 要注意路徑與會產生檔案的問題

    第一個問題是因為 struts+tile 的關係,應該是 tile 產生 html 的方式在的不同,所以我只好先產生圖檔再去 refer 它,但也因此產生第二個問題

    第二個問題比較麻煩,路徑的話只要
    servlet.getServletContext().getRealPath("");
    就可取得實際位置,再找個目錄放檔案;但產生的 temp 就不知道要如何處理了,困擾

        public synchronized final static String draw(ArrayList lst, String path) {

            if ((lst == null) || (lst.isEmpty())) {
                return "";
            }

            int i = 0;
            String title = "";
            DefaultCategoryDataset dataset = new DefaultCategoryDataset();
            Iterator it = lst.iterator();
            while (it.hasNext()) {
                ChartForm chr = (ChartForm) it.next();
                if (chr.getCnt() > 0) {
                    String s = chr.getDay().substring(
                        chr.getDay().indexOf("月") + 1,
                        chr.getDay().indexOf("日"));
                    dataset.setValue(chr.getCnt(), chr.getM(), s);
                } else {
                    dataset.setValue(chr.getCnt(), chr.getM(), "");
                }

                i++;
                if (i == 1) {
                    title = chr.getDay()
                    .substring(0, chr.getDay().indexOf("月") + 1);
                }
            }
            // dataSet.setCategories(xAxisData);
            title += "家數圖";

            PlotOrientation plot = PlotOrientation.VERTICAL;
            JFreeChart chart = null;
            chart = ChartFactory.createBarChart(title, "日期", "家數",
                    dataset, plot, false, false, false);

            Date d = new Date();
            String s = d.toString();
            s = path + File.separator + "jpg" + File.separator
                    + s.replaceAll(" ", "_").replaceAll(":", "_")
                     + ".jpg";
            System.out.println(s);
            File f = new File(s);
            try {
                FileOutputStream ostream = new FileOutputStream(f);

                ChartUtilities.writeChartAsJPEG(
                    ostream, chart, 400, 300);

                ostream.close();
            } catch (IOException e) {

            }

            return f.getName();
        }
  • identical 發表在 痞客邦 留言(0) 人氣()

    有人說需要為發明之母,我深深的認同

    總是覺得人類的生活上有些方式或說邏輯總是一再的重覆,只是方式或是媒介有所改變

    最近忽然感覺到 blog 的重要性了,以前沒寫日記或筆記的習慣經常重覆要找類似的資料或是邏輯,就以最近要用 java 套表時,那種深深的痛苦,唉喲,真是讓我感觸良多 :-)

    研究了二天的 javax.print, java.awt.print 又不能征服它,又做了重覆的苦工,呵呵, Orz

    它有一堆的 attribute 但...,網路上可用的資料實在太少了,IPS 從二年前 (2005) Draft 0.1 到現在(2007.3) 我再去找,它仍舊是那一份 Alpha Draft,呵呵

    不過也因為這樣才發現自己中 google 毒很深,因為一但在 google 上找不到太多相關資料時,你就知道這件事很不樂觀了,呵呵 (不過仍舊有可能是我不夠會用 google 大神)

    by the way 它實際上的做為是

    • implements java.awt.print.Printable
    • 實做 public int print(Graphics g, PageFormat pf, int pageIndex)
    • 我是在 construct 中呼叫 print()

     

    設定紙張的方式有二

    • java.awt.print.PageFormat
    • javax.print.attribute.HashPrintRequestAttributeSet

    這些基本上都相當的清楚明白,不過不幸的是我要用的是一般的 132 columns 的紙張,事情怪異的就在於二年前寫的程式在之前的 NB (xp) 上 run 的很好,也可正常的套表;但我將程式移到開發用的 pc 上就有辦法正常的工作了,唉...


    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.print.PageFormat;
    import java.awt.print.Printable;
    import java.awt.print.PrinterException;
    import java.awt.print.PrinterJob;

    import javax.print.PrintService;
    import javax.print.attribute.HashPrintRequestAttributeSet;
    import javax.print.attribute.PrintRequestAttributeSet;
    import javax.print.attribute.standard.JobName;
    import javax.print.attribute.standard.MediaSizeName;
    import javax.print.attribute.standard.OrientationRequested;

    import org.apache.log4j.Logger;

    public class SizebyName implements Printable {

    private static final Logger log = Logger.getLogger(SizebyName.class);

        public SizebyName() {
            PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
            aset.add(MediaSizeName.JIS_B4);
            aset.add(OrientationRequested.LANDSCAPE);
            aset.add(new JobName("JobName", null));

            PrinterJob pj = PrinterJob.getPrinterJob();

            PrintService[] services = PrinterJob.lookupPrintServices();
            if (services.length > 0) {
                try {
                    pj.setPrintService(services[1]);
                    pj.setPrintable(this);
                    pj.print(aset);
                } catch (PrinterException e) {
                    log.error(e);
                }
            }
        }

        public int print(Graphics g, PageFormat pf, int pageIndex)
                    throws PrinterException {

            if (pageIndex == 0) {
                Graphics2D g2d = (Graphics2D) g;
                g2d.translate(pf.getImageableX(), pf.getImageableY());
                g2d.setColor(Color.black);
                g2d.drawString("中文字", 250, 600);
                g2d.drawString("地址地址地址地址地址", 250, 700);

                return Printable.PAGE_EXISTS;
            } else {
                return Printable.NO_SUCH_PAGE;
            }
        }
    }

    依我用 vb 的經驗紙張應該用 us std Fanfold 的大小就可以了,但 javax.print 似乎沒有這樣的尺寸,也有一位朋友在 sun 的 forum 上問過但沒人回覆 (不過,這有時是思考的方向錯了) ,我記得 2005 年時我是用 java.awt.print.PageFormat + java.awt.print.Paper ,將 Paper.setImageableArea() 設成 us std Fanfold (約為14"*11" 的大小) 再去印表即可,but not this time.

    identical 發表在 痞客邦 留言(0) 人氣()