部落客廣告聯播

2007年7月31日 星期二

Java Script 經典封裝

恩... 這篇跟JAVA沒什麼關係,但對寫web app的人或許多少有用.....

就是一些滿炫目的JavaScript程式:

Java Script 經典封裝

(文源自於 PCOnline)
拿來套用還滿方便的,站在巨人的肩膀上....

2007年7月27日 星期五

POI筆記:關於建立comment時,由HSSFSheet取得的HSSFPatriarch

當我們要使用POI HSSF在xls檔裡寫comments,第一步就是要取的容器HSSFPatriarch。
但每個HSSFSheet只能有一個HSSFPatriarch,如果你仔細看HSSFSheet的java doc就能發現其 createDrawingPatriarch()方法:
Creates the toplevel drawing patriarch. This will have the effect of removing any existing drawings on this sheet.
意思就是說在同一張sheet上若重複呼叫這個方法,則之前的所有圖形(comment註解也算是)都會被移掉。所以說囉 ,每個sheet只要呼叫一次就好了,不然就會只有最後一個圖形會存在囉,其他的就都被移掉了....

找了好久才知道的...................

POI筆記:比較將輸出XLS裡面的HSSFCellStyle是否相同

在使用POI HSSF輸出excel xls檔時,不管要設定儲存格的字型、底色、數字格式等,都需要透過HSSFCellStyle的使用,但當我們在程式將Workbook寫出成xls檔之前,若要判別某個cell的style和另一個cell的style是否相同時,可不能直接使用
(hssfCell1.getStyle()==hssfCell2.getStyle())


(hssfCell1.getStyle().equals(hssfCell2.getStyle()))

來做判斷喔! (這樣判斷有時會相等有時又不相等,完全取決於實做程式的判斷,所以不是正確用法)

正確的用法應該是要比較style的index值:
(hssfCell1.getStyle().getIndex()==hssfCell2.getStyle().getIndex()) 

來做比較才對喔!!

咦~~ 愛注意......

2007年7月24日 星期二

Resin Eclipse WTP 外掛 [Resin Eclipse WTP plugin]

雖然lomboz內建支援的Servlet Container眾多,但還是有遺珠之憾,如果工作上必要的container不在支援之列,便要尋找適合的plugin。
Resin便是其中之一。

網海遍尋許久,終於在Gunnar’s Weblog 找到了能和lomboz完美整合的外掛。
這是由Gunnar自己所寫的外掛,非常感激~~

關於介紹及安裝方法,可參照Gunnar的網頁,如果你用eclipse3.3可用eclipse的線上更新機制,至於線上更新的網址也在Gunnar的網頁中可找到。
而如果你的eclipse是3.2版(現在的最新穩定版本lomboz即是eclipse3.2),在Gunnar的網頁上The old version is still available here下載到。

由於我所使用為resin3.10 pro版,有些內附lib的jar檔案和plugin jar內的resin.serverdef不同故做了小小的修正:
在此提供連結分享給各位。
如果對各位有幫助的話,請不用謝我,麻煩請寫信謝Gunnar。(他應該只看的懂英文)

-------------------------------------------------------------------------------------------
Although there are many servlet containers be supported in lomboz, but some were not.
If the container which you will work with ,you'll need to find a plug-in.
Resin is one of them.

By searching over the net, I found a good plugin on Gunnar’s Weblog at last.
This plug-in was wrote by Gunnar himself. Thanks to him.

The introduction and installation guide about this plug-in could be found on the same Gunnar’s Weblog page.
If you are using Eclipse 3.3, you could install plugin inside eclipse through Gunnar's update site.
And if you are using Eclipse3.2(like the lomboz 3.2.2), you should the old version of plug-in. It can found on the same page.

Because I'm using resin 3.10 pro,some jar files in resin's lib directory is not the same with resin.serverdef in plugin's jar file.
So, I made a little modification to it.
If you are using the same version of resin with me, you could download the plug-in here.

If this article give helps to you , Please say thanks to Gunnar through e-mail.

為何要避免在JSP中處理二元串流?

故事起源於我要使用POI輸出報表,原有的報表乃是用JSP+ jsp custom tag來產生的。

當然用POI輸出XLS檔,使用Servlet當然是首選,這在網路上許多前輩也常提,但總不是很深切的了解為何?

由於許多報表運算邏輯都放在custom tag裡,故愚笨的我選擇為了能共用tag所以在JSP中配合custom tag和script let來產生XLS檔,但前前後後遇到了不少問題。

在單純的JSP(不包含EL及custom tag狀況)中,來處理要輸出的Stream若遇到狀況,似乎還不難解決,但若JSP中包含了custom tag就複雜多了,況且有些問題再script let強加補強就算能用,移到了別的container還是有不能跑的可能,這涉及到各個container將JSP轉譯java servlet的實做程式不同。

首先是JSP buffer的問題,我們知道當JSP寫到Response的資料到達buffer值時即會flush到客戶端去(假設autoFlush=true),每個container預設的JSP buffer size不同。
然而在JSP裡要將二元資料寫到串流前,通常都要將先前JSP轉譯成java後裡頭的out.print(" \t\n");之類的東西清掉,才不會在資料頭出現奇奇怪怪的東西,所需要使用out.clear() 之類的做清除的動作,但如果在執行out.clear()之前buffer就已經被flush過了,那麼就會IOException,不要的out.print(" \t\n");也早就被輸出了,為了這個問題,可以透過JSP的Directive來將buffer設大點,暫時解決。

第二,在我的JSP最後段是workbook.write(response.getOutputStream); response.flush(); 但在Tomcat中執行,出現了錯誤,由於Tomcat算是廣為使用,到處有人可問,所以不用一天的時間我就早到了解決方法,在我的JSP最後再加上 out=response.pushBody( );就解決了。打開java檔查看乃是Tomcat的實作在jsp頁面後會再對out做處理,但我們提前將整個response給flush掉了,所以只要再push一個新的JspWriter給out就能解決了。

第三,當程式移植到了Resin時,問題就來的,輸出的Excel檔會是一堆空白,然後再活頁簿往下拉發現許多亂碼。同樣的我們將該JSP頁面經由Resin轉譯成的servlet來觀察問題所在,發現Resin實做會將每個TagSupport的endTag()後方加上out.flush( );[相對Tomcat沒有],故會在之前就輸出許多的空白和escape character,為了解決這個問題,於是將custom tag由TagSupport改用BodyTagSupport來實做,並且在JSP頁面上每一個custom tag結尾加上pageContext.clear( );
,恩,又是暫時解決!!

第四,程式到了另一個或許你也沒聽過的container - Novell Silver Stream,好玩,輸出的XLS完全空白,同樣觀察java檔,然而,到現在對於這問題還是一無所獲!! 無法解決......


上面寫了這麼大串,或許那都不重要,但我卻真正體會不要再JSP中處理Stream的意義了!!
恩... 好樣,最後還是要用servlet寫...........................
( 哭 ) 浪費我好多時間阿...................................................

2007年7月22日 星期日

CSS中文參考文件 - 淺顯易懂

Cascading Style Sheets (串接樣式表)的基本介紹

VPN連線同時不能上網 ...... 鬼屁!!

恩... 好樣的... 哪管是換了幾百個工作,只要還在科技產業,加班是必免不了的!!

大公司、小公司 都一樣,不一樣的是,大公司有網管,精心準備好了VPN,不用勞路奔波,在家就可以加班了,這樣至少「Ki Mo tzi」還會好點!

連上了VPN後,乖乖,其他網站都開不了囉!連我的Flash Get也都滿江紅了! 根本是完全斷線了!
我的電腦躲在IP分享器後,經由HI Net ADSL上線,不知其他人是否也有相同問題,難道是神要我專心一意的工作,(別想邊工作邊Shopping),恩..謝謝保佑,但這不合乎人性。

搜尋了網路(Google似乎成為我所有問題第一個想問的),就在某論壇的某大大(這是別人的稱呼,我倒不大習慣,假...)貢獻(我不認識你,但是謝謝你),關鍵的設定正如下圖:


步驟都在上面的,就不用多說了吧!!

站在大大的肩膀上,成為別人的大大!!

2007年7月18日 星期三

JSP中 關於IE6開啟附件時的問題(A problem about direct open excel file from IE won't woks)

故事是這樣的:
工作上使用POI將資料寫出讓user下載,當Excel寫出response後,IE會提示使用者「開啟」或是「儲存」檔案,問題就在於使用者按下儲存正常順利,但若按下開啟,便會出現如下圖示:


好笑的是,用FireFox不會,聽說用IE7也不會,那麼算是IE6的Bug囉!!

又跑去Google神殿拜神,滿地的預測籤詩讓我找到了答案。

以下是我的原始JSP程式:




<%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5"%>
<%@page import="org.apache.poi.hssf.usermodel.*,org.apache.poi.hssf.util.*,java.io.*" autoFlush="true" buffer="10240kb"%>
<%@taglib uri="report" prefix="report" %>
<%

response.setHeader( "Content-disposition" , "attachment; filename=ProjectScorecardReport.xls" );
response.setContentType("application/vnd.ms-excel");
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);


HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("MajorScorecardYearReport");

//..... more here

wb.write(response.getOutputStream());
response.flushBuffer();
out.clear();
out = pageContext.pushBody();
%>



而我找到的答案告訴我,要解決這bug非常簡單,只要多設幾個http header即可:

response.setDateHeader("Expires", 0);
response.setHeader("Pragma", "public");
response.setHeader("Cache-Control", "max-age=0");

把這三行程式加入後,果然成功了!
不管PHP或ASP或其他CGI語言,都可用相同方法設定Header即可解決,因為問題出在IE!

================================================================

It's a short story:
I need to export reports to Excel xls files by using POI library in my JSP page.
When everything went on well, there was some problem when user who was using IE6 will get an error message when they directly opened XLS file, like thihs:
And it won't appear if the user's browser is FireFox or IE7. So,it is a bug of IE6 baldly.

After searching through Google,I got a useful solution to solve this bug.

Below is my original JSP file:




<%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5"%>
<%@page import="org.apache.poi.hssf.usermodel.*,org.apache.poi.hssf.util.*,java.io.*" autoFlush="true" buffer="10240kb"%>
<%@taglib uri="report" prefix="report" %>
<%

response.setHeader( "Content-disposition" , "attachment; filename=ProjectScorecardReport.xls" );
response.setContentType("application/vnd.ms-excel");
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);


HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("MajorScorecardYearReport");

//..... more here

wb.write(response.getOutputStream());
response.flushBuffer();
out.clear();
out = pageContext.pushBody();
%>


It's really simple to solve this bug , you just need to add three lines of code to set related http headers:

response.setDateHeader("Expires", 0);
response.setHeader("Pragma", "public");
response.setHeader("Cache-Control", "max-age=0");

After Adding these codes , It works well without any problem.
And you can use the same method to set these three header to resolve the problem in PHP or ASP. Because this problem is a Bug of IE6.

2007年7月12日 星期四

筆記:Jakarta HttpClient library (Notes: Jakarta HttpClient library)

  1. 需要四個Jar檔:
    • commons-httpclient.jar
    • commons-lang.jar
    • commons-logging.jar
    • commons-codec.jar
  2. 簡單範例:

    import org.apache.commons.httpclient.HttpClient;
    import org.apache.commons.httpclient.methods.GetMethod;

    public class test{
    public static void main(String[] args)
    {
    try{
    HttpClient client=new HttpClient();
    GetMethod method=new GetMethod("http://www.hinet.net");
    int resultCode=client.executeMethod(method);
    if(resultCode==200)
    System.out.println(method.getResponseAsString());
    }catch(Exception e)
    {}
    }
    }
  3. HttpClient類別依賴
    • HttpConnectionManager介面
      • SimpleHttpConnectionManager
      • MultithreadedConnectionManager:需要同時做多個連結,預設連線pool是每個host有兩個,可調整最大數為20
    • HttpClientParams類別
  4. HttpMethod-->HttpMethodBase --> GetMethod、PostMethod等。(位於org.apache.commons.httpclient.methods)
  5. org.apache.commons.httpclient.auth.AuthScheme的實作有:
    • BasicScheme
    • DigestScheme
    • NTLMScheme
  6. AuthState:
    • 提供authentication處理狀態
    • 更換authentication scheme
  7. AuthPolicy
  8. CredentialsProvider:
    • 用來向使用者要求憑證
  9. AuthChallengeParser、AuthChallengeProcessor:
    • 在authentication處理中解析response header
    • 處理在header中的盤問(challenge)
  10. authendication處理相關Exception:
    • AuthChallengeException
    • MalformedChallengeException
    • InvalidCredentialsException
    • CredentialsNotAvaliableException
  11. org.apache.commons.httpclient.cookie package裡包含用來處理在HttpClient物件裡heder的cookie。
  12. org.apache.commons.httpclient.params裡包含有許多HttpClient重要物件的參數,比如說HttpClientParams就是用來設定HttpClient類別物件的類別。
  13. 以下程式碼,可將送出的request中header的browser資訊修改掉:

    HttpClient client=new HttpClient();
    client.getParams().setParameter("http.useragent", "java browser");

  14. 用GetMethod取回GIF圖檔:


  15. import java.io.FileOutputStream;

    import org.apache.commons.httpclient.HostConfiguration;
    import org.apache.commons.httpclient.HttpClient;
    import org.apache.commons.httpclient.URI;
    import org.apache.commons.httpclient.methods.GetMethod;
    import org.apache.commons.httpclient.protocol.Protocol;


    public class test {


    public static void main(String[] args) {
    try {
    HttpClient client=new HttpClient();
    client.getParams().setParameter("http.useragent", "java browser");
    GetMethod method=new GetMethod();
    method.setURI(new URI("http://tw.yimg.com/i/tw/dictionary/masthead_logo.gif"));
    HostConfiguration hostConfig=new HostConfiguration();
    hostConfig.setHost("tw.yimg.com",null,80,Protocol.getProtocol("http"));
    int result=client.executeMethod(hostConfig,method);
    System.out.printf("result code=%d",result);
    byte[] gif=method.getResponseBody();
    FileOutputStream fos=new FileOutputStream("c:\\image.gif");
    fos.write(gif);
    fos.close();
    } catch (Exception e) {
    // TODO: handle exception
    }


    }

    }

    在這個範例程式,如果要抓下來的圖檔很大,可以用method.getResponseBodyAsStream()取得InputStream後直接寫入檔案,就不用放在記憶體中了。
  16. 上面都是用GetMethod執行,可改用PostMethod,而原本給GetMethod的建構子或setUrl方法的字串中的參數,可用PostMethod物件的addParameter( )即可。
  17. 若要以HttpClient做上傳資料動作,可改用MultiPartMethod物件。
  18. PutMethod主要用來把檔案放上server,DeleteMethod則相反。
  19. HttpClient預設使用SimpleHttpConnectionManager,若需同時發出多個作業,要改用MultiThreadedHttpConnectionManager。
  20. multiThread範例:

    import java.io.BufferedOutputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;

    import org.apache.commons.httpclient.HttpClient;
    import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
    import org.apache.commons.httpclient.methods.GetMethod;
    import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
    import org.apache.commons.httpclient.params.HttpConnectionParams;


    public class MultiThread extends Thread {

    private HttpClient client;
    private GetMethod method;

    public MultiThread(HttpClient client,GetMethod method)
    {
    this.client=client;
    this.method=method;
    }

    public static void main(String[] args) {
    MultiThreadedHttpConnectionManager mcm=new MultiThreadedHttpConnectionManager();
    HttpConnectionManagerParams params=new HttpConnectionManagerParams();
    params.setDefaultMaxConnectionsPerHost(10);
    mcm.setParams(params);

    HttpClient client=new HttpClient(mcm);
    GetMethod method1=new GetMethod("http://www.sun.com/images/l2/l2_phone_pda.gif");
    GetMethod method2=new GetMethod("http://www.sun.com/images/l2/l2_swingap.gif");
    GetMethod method3=new GetMethod("http://java.sun.com/javase/images/dukejdk6_100x88.gif");

    new MultiThread(client,method1).start();
    new MultiThread(client,method2).start();
    new MultiThread(client,method3).start();
    }

    @Override
    public void run() {
    try{
    client.executeMethod(method);

    String filePath="c:\\"+method.getURI().getName();
    InputStream input=method.getResponseBodyAsStream();
    BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(filePath));
    int data;
    while((data=input.read())>=0)
    bos.write(data);

    input.close();
    bos.close();

    }catch(Exception e)
    {
    System.out.println(e);
    }
    }

    }

  21. HttpClient支援NTLM、Digest、Basic三種authentication。
  22. authentication範例1

    import org.apache.commons.httpclient.*;
    import org.apache.commons.httpclient.auth.*;
    import org.apache.commons.httpclient.method.*;

    public class authExam{
    public static void main(String[] args) throws Exception{
    HttpClient client=new HttpClient();
    HostConfiguration host=client.getHostConfiguration();
    host.setHost(new URI("http://localhost:8080",true));

    GetMethod method=new GetMethod("protectedArea/protect.jsp");
    try{
    int code=client.executeMethod(host,method);
    if (code==HttpStatus.SC_UNAUTHORIZED)
    {
    Crenditals cred=new UsernamePasswordCrenditals("tomcat","tomcat");
    AuthScope scope=new AuthScope(host.getHost(),host.getPort());
    client.getState().setCrentials(scope,cred);
    client.executeMethod(host,method);
    }
    }catch(Exception e){}
    }
    }
  23. authentication 範例2

    public class authExam2{
    public static void main(String args[]) throws Exception
    {
    HttpClient client=new HttpClient();
    HostConfiguration host=client.getHostConfiguration();
    host.setHost(new URI("http://localhost:8080",true));

    Credentials cre=new UsernamePasswordCredential("tomcat","tomcat");
    AuthoScope scope=new AuthScope(host.getHost(),host.getPort());
    client.getState().setCredentials(scope,cre);

    try{
    client.executeMethod(new GetMethod("http://localhost/protectedArea");)
    }
    catch(Exception e){}
    }
    }
  24. 讀取Cookie
    client.getState( ).getCookies( );

2007年7月4日 星期三

Java存取MS Office檔案格式函式庫Apache POI (Java library for Accessing MS Office format files)

Java存取MS Office檔案格式函式庫Apache POI
(Java library for Accessing MS Office format files)

最常被用來存取Excel XLS檔案,
此外還有提供對Word及power point及visio檔案格式有限的存取,
請見官方網站
使用文件可在此取得。(建議閱讀)

Normally used for accessing Excel XLS files,
and have the limited ability to access Word,power point and visio files,
see Official Site here
and documents here

2007年7月3日 星期二

製作網頁超實用的[色碼表] (Color code table for HTML Design)

製作網頁超實用的[色碼表]
(Color code table for HTML Design)

在這裡,寫web application時很實用的...
(Press Here)


----------------------------------------
When you designing web pages, it is banausic having such a color table for look up by hand.

The Link is Here