2010/07/30

命不好+雨男命

今天原定要去拿昨天下定的KHS T3B
但是...聽完簡易使用說明跟檢查車況後,準備牽車出去,就...
2010-07-30_14-08-25_955.jpg
下大雨,一分鐘內路面全濕,我看也不用騎回去了
只能相約明天再見,臨走前還是拍了兩張照片做紀念(?!)

2010-07-30_14-07-16_143.jpg
最前面的紅車就是我的

2010-07-30_14-07-32_596.jpg
加裝的大盤護蓋是用超不低調的紅色,所以水壺用黑色低調一點CC

明天早上要拿攜車袋準備,下大雨也要扛回來啦!

2010/07/28

Servlet & JSP 留言版:列出所有留言 - DB連線

準備來寫第一個功能:列出所有留言
但是列出留言需要到DB抓資料出來,抓出來又要放在哪?
似乎沒有這麼簡單可以靠一隻Servlet完成;所以在此之前需要先完成兩件事情
  1. 連接DB
  2. 準備Model

連接DB

這個範例是使用Mysql做為DB,請先參考上一篇完成DB的設定
因為DB連線非常多地方用的到,所以可以單獨出來為一隻Class這樣可以重複使用
請在Eclipse下新增一個Java Class,我叫它DBConn.java 

DBConn.java
========
package cc.asper;
import java.sql.*;

public class DBConn {
    private String url = "jdbc:mysql://localhost:3306/guestbook?useUnicode=true&characterEncoding=utf8";
    private String user = "user";
    private String passwd = "123456";
    private Connection conn = null;
    public void DBconn(){
       
    }
   
    public Connection getConnection() throws Exception{
        if( conn == null ){
            try{
                Class.forName("com.mysql.jdbc.Driver");
             conn = DriverManager.getConnection(url, user, passwd);               
            }catch(Exception ex){
                throw ex;
            }
        }
        return conn;
    }
   
    public void close() throws Exception{
        try{
            if(conn != null) conn.close();
        }catch(Exception ex){
            throw ex;
        }finally{
            conn = null;
        }
    }
}

說明:
這隻Class有兩個方法:
geConnection() : 取得連線,如果連線存在則直接回傳,否則建立一個
close() : 關閉連線 

連線資訊建立,說明如下:
  1. 連線資訊:指定三個變數(url, user, passwd),把DB的連線資訊存在變數中。
  2. url 變數:格式為 jdbc: DB_type :// DB_address : DB_port / DB_name ? 其他參數。
  3. 其他參數:useUnicode=true&characterEncoding=utf8,設定該DB連線為Unicode編碼。

開始建立連線

  1. Class.forName("com.mysql.jdbc.Driver");
    指定使用Mysql Driver,Driver需到官網下載 jar 檔案後放至於WEB-INF\lib下,才可使用。
  2. conn = DriverManager.getConnection(url, user, passwd);
    把設定好的參數丟進上數方法內即可取得連線
  3. 建立、關閉連線都需包在 Try / Catch 內捕捉錯誤
  4. 回傳conn

關閉連線

建議先檢查是否不為 null 才使用 conn.close() 關閉。
再將conn設為null;

寫好DBConn.java後,在需要連接DB前,將其實體化後呼叫getConnection()即可,
範例:
DBconn dbcon = new DBConn();

//實體化一個DBConn物件,並指定到dbcon變數,該變數為DBConn類別。
conn = dbcon.getConnection();     //取得DB連線資源

◎關於如何使用SQL語法Query資料,會在建立Model時說明。
至此已經準備好DB連線的物件;

但是怎樣操作DB存取資料,回傳的資料要擺哪,擺好的資料要怎麼給Servlet處理等,就要介紹Model了...

2010/07/27

Servlet & JSP 留言板:架構

設計一個簡單的留言板來做Servlet & JSP的練習專案
這個留言板有三大主功能
  1. 新增留言
  2. 顯示所有留言
  3. 管理功能

但是入門當然要從最簡單開始,所以這個留言板沒有
  • 上傳圖片、檔案
  • 留言列表搜尋,分頁、排序等
  • 留言沒有回復功能
  • 管理沒有做登入驗證,也就是單純練習修改、刪除

不過還是有幾個可以說嘴的設計
  • 主頁面設計,ASP叫Master Page。只將變動的頁面嵌入設計好的頁面中
  • 錯誤頁面。
  • MVC
  • EL與JSTL使用(很淺的使用)

MVC設計模式:
M為Model,負責資料的處理、商業邏輯的處理;
V為View,負責網頁畫面的呈現,JAVA中是使用JSP來表現;
C為Controller,負責程式的流程控制、參數前置處理(丟給Model前)、網頁畫面顯示(轉給JSP);

這隻留言板會用到的MVC檔案(新手這裡看得懂就不是新手了XD)

Controller:
  • List.java: 留言列表,就只是顯示留言
  • AddPost.java:新增留言用,包含顯示表單與檢查輸入後寫入DB。
  • Admin.java:管理用,可修改與刪除留言。


我覺得難易順序是由上而下,也會依照這個順序介紹
套件定義是cc.asper.servlet

Model:
  • Guestbook.java:留言板的物件,此為單筆留言使用
  • GuestbookList.java:同樣是留言版物件,只是它是多筆Guestbook的集合,所以多個List

套件定義是cc.asper.model (寫完我覺得Model是最難寫的,V跟C相比簡單多了)

View:
  • list.jsp:留言列表用
  • form.jsp:新增留言表單
  • master.jsp:管理介面
  • index.jsp:主頁面
  • error.jsp:錯誤頁面

DB結構
使用Mysql,此例DB只有一個表單作為紀錄留言用
資料庫名稱叫guestbook,留言表格叫record(我取名很沒創意(攤手) ),結構為
名稱型態描述備註
snint流水號自動增加
titlevarchar(50)主旨
namevarchar(20)留言者
texttext內容
datedatetime時間

WOW~我第一次用表格,好難用= =
結構參考用,一切從簡,也請設定存取該DB的帳號

後記
這篇排版的好漂亮喔,相比第一篇像被輾過的感覺XD

2010/07/24

Servlet & JSP: Servlet內的方法

Servlet Class 簡介

Eclipse幫我們產生的Code內主要有一大塊與三小塊
最外層的public Class Hello extends HttpServlet...
因為Hello這隻繼承 (extends) 了 HttpServlet 所以才可以當作Servlet使用(好像是廢話)

內有三個Method
public Hello()  <= 建構式,Class在實體化時會執行(我沒用過)
protected void doGet , doPost
這兩個是HTTP最常使用的傳送方法,其他還有一堆

GET與POST

一般打入URL網址,都是使用GET方法
GET傳送的資料會顯示於網址列,例如http://127.0.0.1/Hello?param=123&param2=456
Servlet收到後會使用doGet方法處理,並可接收到兩個參數 param 與 param2

POST傳送的資料在網址列看不到,通常用於Form表單的資料傳送;資料的保密性較高,可傳送的資料大小較大
當Servlet收到後會使用doPost方法處理
在Hello World 中,程式瑪是寫在doGet中,
代表當瀏覽器向Server要求http://127.0.0.1/gb/Hello時,Servlet會執行doGet內的程式碼;
反之,如使用Form表單並以POST方式傳送給Servlet,則會執行doPost內的程式碼。

Request, Response

有注意到doGet與doPost都有傳入HttpServletRequest request, HttpServletResponse response這兩個參數嘛?
這兩個參數大概可以稱為Servlet的主角,大部分的程式碼都是需要這兩個主角來演出
Request:瀏覽器傳給伺服器的要求
如網址傳來的參數, Session, Cookie等都是透過 request取得
EX: request.getParameter("name");  取得name的參數值
Response:要傳給瀏覽器的資訊
如要顯示於網頁的文字, 要求瀏覽器跳到其他頁面等
EX: response.sendRedirect("error.html");  要求瀏覽器跳轉到error.html頁面


在Hello World中使用了PrintWriter來輸出文字
PrintWriter out = response.getWriter();
之後就可以使用out物件來輸出文字到網頁上
out.println("Hello World");
println 表示列印文字到網頁上後換行
(換行指的是在原始碼中換行,要在HTML中換行請加上<br/>)

關於Servlet大概只想到這些

2010/07/23

[抱怨] 新生南路自行車道施工

2010-07-23_12-49-54_70.jpg
過個馬路還要繞一大圈
跟車子的距離不到30公分,非常危險

2010-07-23_12-50-18_250.jpg
走過去又繞一大圈,還直接跟車子對看,哪天不小心擦到大概就在路邊喘了

如果只圍個一兩天還可以接受,都快兩個禮拜了
不然在中間放個木板給行人走安全多了
台北市內的自行車道怎麼都這麼顧人怨

JAVA Web: Servlet & JSP 筆記分享

最近這個月開始接觸JAVA的Web,我也不知道這樣稱呼是否正確,
簡單說就是用JAVA來寫動態網頁,跟PHP或ASP一樣的功能
會開始學JAVA WEB的原因是因為想更深入物件導向加上MVC設計模式的撰寫方法
感謝我身邊已經再用JAVA開發的朋友,這一個月被我猛烈攻擊

這個分類主要把我這個月學到的心得與實際寫的一個留言板
整理一下當作備忘錄,程式BUG一定不少,而且考慮的不甚周嚴,新進JAVA的人可以參考
不過是筆記,所以預期會非常的亂,請做好心理準備。

事前準備

JDK(Java Development Kit)
要執行Eclipse至少需要JRE(Java Runtime Environment),但是建議直接安裝JDK,因JDK內含有JRE,東西都傳便便比較不會有杯具發生。JDK Download
IDE(Integrated Development Environment 整合開發環境)
好的IDE可以讓你程式錯誤的機率少很多,我是使用Eclipse IDE for Java EE Developers
下載後直接解壓縮到你喜歡的位子,免安裝;可以執行表示JAVA安裝是OK的。
我是解壓縮到D:\下,重灌OS不會被影響。
Server
我使用Resin,另外也有Tomcat;Resin的好處是,程式更動後不用重新啟動SERVER就可以執行。( 程式更動後要重新啟動SERVER ?! 這啥鬼)

恩,我當初也這樣想,但是JAVA就是這樣,如果程式有變動,就必須重啟SERVER,或是手動叫伺服器重新檢查程式碼;Tomcat就是這樣;如果小修個地方就要重啟,非常的麻煩,所以朋友推薦使用Resin,程式有更動都不用重啟。

註:這裡指的Server為Container加上HTTP Server,執行Servlet & JSP需要有Container來處理;HTTP Server則是負責與使用者(瀏覽器)的溝通;我在看Container時也被搞得一頭霧水,所以這裡簡略帶過XDD
安裝方法很簡單,直接解壓縮到你喜歡的位子(這句話好像看過),執行SERVER比較麻煩,每個版本都不太一樣 囧

3.1.6   執行檔在 Resin-3.1.6\httpd.exe
3.1.10 執行檔在 Resin-3.1.10\win32\resin.exe
4.0.8   執行檔在 Resin-4.0.8\resin.exe



如果要以服務(Service)方式在背景跑
3.1.6 在Resin-3.1.6\ 以命令提示字元執行 httpd -install 即可,服務內就會出現一個Resin Web Server
3.1.10 在Resin-3.1.10\ 以命令提示字元執行 resin -install 即可


4.0.8 執行 Resin-4.0.8\Setup.exe 按一下Install即可



Eclipse專案設定


由於Eclipse可以跑一個SERVER直接測試,但是效能...
所以Eclipse只拿來編輯,測試程式直接使用安裝好的Resin來測試
  1. 新增一個叫 Dynamic Web Project 專案,目錄預設即可。

  2. 請在Resin目錄內的webapps下建立與專案同名的資料夾(不同名應該也行,但是何必搞死自己)
    Resin會幫忙生出WEB-INF資料夾,請不要砍掉(關於這個資料夾要幹嘛的,之後會說明)

  3. 請回到Eclipse,把WebContent刪除(讓Eclipse直接使用Server的目錄,存檔完就不用複製檔案了)
  4. 在專案上右鍵
    新增資料夾 >
    打開Advance >
    選擇Link to folder in the file system,將其指到剛剛在Webapps下建立的目錄
    將Folder name改為Webcontent,然後Finish

    (有沒有覺得有圖真好)
  5. 接下來要設定一些編譯的參數,不設定的話Eclipse就跟筆記本沒兩樣 囧。
  6. 在專案上按右鍵 >Properties>JAVA Build Path
  7. Source內
    砍掉GB/src
    Add folder >選擇Webcontent\WEB-INF\classes (是只選Classes)



  8. Libraries內
    Add Exrernal JARs > 選擇Resin\lib\resin.jar

  9. 收工!


第一支Sevlet程式


測試一下設定是不是正確,直接寫的Hello World最準了!
  1. 新增一Servlet
    Package可以隨意,但要使用xxx.xxx.xxx的形式,我是用asper.test.sevlet
    Class name只要第一個字大寫即可,這裡用Hello
    Finish
  2. Eclipse已經用範本建立部分內容了,裡面做啥的下回分解
  3. 請在protected void doGet... 內打入下列程式碼
    PrintWriter out = response.getWriter();
    out.println("Hello World");
  4. 如果PrintWriter下畫紅線,表示Eclipse不知道這哪來的,請把滑鼠移到上面

    請點 Import 'PrintWriter' (Java.io)  <=引入lib
  5. 理論上應該沒有紅色XX在旁邊,表示沒有錯誤可以執行了
  6. 此時要建立另一個檔案web.xml,放在 gb/Web-INF/ 下,稱為網站描述檔,告訴SERVER如何執行這個網站
    <?xml version="1.0" encoding="ASCII"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
       <servlet>
        <servlet-name>Hello</servlet-name>
        <servlet-class>asper.test.servlet.Hello</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>Hello</servlet-name>
        <url-pattern>/Hello</url-pattern>
      </servlet-mapping>
    </web-app>

  7. 請打開瀏覽器,輸入http://127.0.0.1:8080/gb/Hello,應該就會看到Hello World了

發生了甚麼事情


做了如此多事情之後,才可以跑出一行Hello World是不是覺得很沮喪開心呢? 來了解一下到底花生省魔術
  1. Resin接收到瀏覽器想要要求http://127.0.0.1:8080/gb/hello 這個網頁
  2. 於是他到Webapps下的gb內尋找有沒有hello這個檔案,發現它沒有副檔名,猜測他應該是Servlet,所以再去找WEB-INF內的web.xml
  3. 發現web.xml內有<url-pattern>發現相符的 /Hello,然後在<servlet-name>發現名稱叫做Hello
  4. 然後根據名子叫做Hello的找到它的class叫做
    <servlet-class>asper.test.servlet.Hello</servlet-class>
  5. 再找到Web-INF\classes\asper\test\servlet\Hello.java 編譯成 Hello.class 後執行
  6. 很複雜,我知道

WEB-INF幹嘛的?


這裡面擺的都是瀏覽器無法直接存取的檔案,也就是無法用 http://127.0.0.1/gb/WEB-INF/ 去存取
這裡面我會用到的只有classes, lib目錄與web.xml
classes拿來放寫好的servlet, Java Bean, etc... 目錄就是依照套件名稱(package name)來建立
EX: asper.test.servlet.Hello => classes\asper\test\servlet\Hello.java
lib拿來放其他的函式庫,例如SQL Driver, JSTL, etc...
如果有不想被直接存取的檔案也可以放這

這一篇內容好多


大推的書
http://www.oreilly.com.tw/product2_java.php?id=a236
看完這本之後會對servlet非常了解,沒看之前一直不懂servlet到底怎麼運作,為啥要一堆奇怪的檔案跟難懂的規則
缺點是非常的貴!但是很值得

http://www.books.com.tw/exep/prod/booksfile.php?item=0010444080
這本跟上面那本內容十分的類似,但是我怎麼看怎麼不懂;但是看完深入淺出之後這本兩天就可以翻完了(灑花)

http://www.books.com.tw/exep/prod/booksfile.php?item=0010256594
這本還在看,範例碼的部分有點多,但是對新手來說很實用
作者把SERVLET內容整理的很有條理,初學者可以拿來當第一本書

2010/07/21

[單車] 大稻埕-碧潭


週二跟阿舍相約騎單車到碧潭,天氣真的好到爆炸!

路線圖



兩台一樣的車一起出去 科科

2010/07/19

新竹行


講去新竹講很久了,一方面想出去走走,一方面大學同學一堆在新竹工作
就當同學會加郊遊

搭七點半的莒光號大概九點到新竹
先到十八尖山爬完很沒挑戰的山之後,跟隨鳳梨的腳步到了北埔老街
但是這兩個地方都沒有拍照的動力~_~

吃完很有名的客家菜後,到了北埔冷泉 = =
滿坑滿谷的人群是怎樣= =


然後到處都是警告牌,不意外的到處都是人;非常強烈的對比

接下來非常怕熱的回到市區,到85度C坐了快兩個小時才動

十七公里海岸線之南寮魚港,在市區跟北埔時,想說新竹不是風城嗎?怎麼一點風都沒有
到海岸線才有風城的感覺= =
廣場很多人在放風箏,多個一個誇張

看得到的有章魚哥(長度很長),企鵝跟DORA(我需要你幫忙~)


很有希臘風情的地方,但是是個蚊子館= =


九月要結婚的新郎倌,這時想起廣告詞『我拍我的看法』


此行的一行人


距吃飯的時間還久,順著海岸線繼續到火力發電廠,也是海天一線??
LX3沒法縮更小,只能這樣><"


造型很特別的火力發電廠


這次可惜的是沒騎到腳踏車,看起來還蠻美的


剪影


晚餐是吃有名的新橋燒肉,但是沒做功課 本以為是吃到飽的><"
所以其實沒吃很飽~哀

晚上搭九點的國光客運,到台北也十點半了

2010/07/03

[筆記] Java Servlet URL Rewrite

Apache有mod Rewrite的套件,可以把很醜的網址整理
EX: http://127.0.0.1/welcome.php?type=signin&browser=mozilla
轉成 Http://127.0.0.1/welcome/signin/mozilla 的形式
這樣也有助於SEO的優化

但是我使用的Resin好像沒有這樣的東西可以用
好險網路上已經有人寫好Library可以用URL Rewrite
首頁: http://www.tuckey.org/urlrewrite/
以下是試用一個小時的心得


1.安裝
下載回來的壓縮檔期指只有兩個檔案:urlrewrite.xml, urlrewrite-2.6.0.jar

XML放在WEB-INF下,JAR放在WEB-INF\lib內

2.修改web.xml,加入下面這段在<webapp> ... </webapp>內
<filter>
    <filter-name>UrlRewriteFilter</filter-name>
    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
    <init-param>
        <param-name>logLevel</param-name>
        <param-value>WARN</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

原來是利用filter來做URL重寫,FILTER原來可以這樣用

3.Done!
4.打開 http://127.0.0.1/AppName/test/status 如果會轉到
    http://127.0.0.1/AppName/test/rewrite-status 就表示成功了


<rule>的使用
<from>網址傳來的樣式
<to> 要改寫的樣式
其中<to>有分好幾種轉址法,我應該只會用到redirect與forward


設定的方法
<to> : 預設就是forward,等同與使用request.getRequestDispatcher(value).forward(request,reponse);

<to type="redirect"> : 網址會改變的方式


案例:
AppName/Welcome/aaa => AppName/Welcome.do?type=aaa
<rule>
    <from>/Welcome/([a-zA-Z0-9]+)</from>
    <to>/Welcome.do?type=$1</to>
</rule>

說明:預設使用regexp來比對網址 ([a-zA-Z0-9]+)表示接受英文與數字的組合
         比對完成後會將內容存到$1作Foreard


案例:
AppName/Welcome/aaa/bbb => AppName/Welcome.do?type=aaa&mode=bbb
<rule>
    <from>/Welcome/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)</from>
    <to>/Welcome.do?type=$1&amp;mode=$2</to>
</rule>

說明:
使用兩個參數,網址是使用 & 但是在XML內不能用 & 要改用 &amp;,不然整份設定都會失效

規則更新時間
測試的時候發現規則改了都不會WORK,發現是規則沒套用,需要重開SERVER才可以生效。
即使用Resin也是一樣,後來發現是需要在web.xml設定更新時間才行

請在web.xml <filter>內新增

<init-param>
    <param-name>confReloadCheckInterval</param-name>
    <param-value>0</param-value>
</init-param>

param-value就是更新的時間
0為每次都檢查,測試的時候建議這樣設
-1為不檢查更新,為預設值



短時間只玩了幾個方法,網址轉回去的部分還沒測試
需要再設定<outbound-rule>讓網址轉成<rule>的形式,不然連結會死光
官網的說明是
Using the example above JSP's with the code
<a href="<%= response.encodeURL("/world.jsp?country=usa&amp;city=nyc")
%>">nyc</a>

will output
<a href="/world/usa/nyc">nyc</a>

Or JSTL
<a href="<c:url value="/world.jsp?country=${country}&amp;city=${city}"
/>">nyc</a>

will output
<a href="/world/usa/nyc">nyc</a>

可以用encodeURL或JSTL來自動改寫網址,乎~這樣輕鬆很多