星期六, 5月 31, 2008

PHP Tutorial - Eclipse + PDT

Eclipse 大概是目前最火熱的一個 IDE 了,而 PHP 可能是目前最火紅的 Web Application 開發環境,因此在 Eclipse 上面開發 PHP 的 Project PDT (PHP Development Tools) 也就跟著出現了。 

剛剛在網路上看到有人錄製了兩段簡單的 Tutorial,有興趣的人可以看看,還不錯的影片簡介。


More......

星期五, 5月 30, 2008

blog 編輯器



剛剛在網路上看到有人整理了 15 個 blog 編輯器清單,原來現在已經有這麼多的 blog editor 了。前年我還花錢在 OSX 平台上買了一個 ecto 編輯器,結果...後來 blogger 改版,ecto 作者卻是一直沒有跟上速度,一轉眼現在已經免費的 blog editor 一堆了,現在我看會花錢買的人應該很少了。

我自己現在習慣使用 Windows Life Writer,Windows Life Writer 不僅僅支援自己的 MSN Spaces,幾乎目前 popular 的 blog 平台都有支援,加上又是免費的,因此,我個人是最推薦 Windows Life Writer。
More......

星期四, 1月 10, 2008

開始 Ruby on Rails 之旅



發現自己真的是對於寫部落格很沒有持續性。一方面也是下班以後就很不想要寫這些東西,尤其是要把一些東西整理出來也是很花時間的事情。我手上還有一大堆東西要看,一大堆東西要寫...不過寫部落格的好處是可以把一些過程記錄下來,以後如果還需要使用到的話,就可以直接查詢了。還是把記憶力多拿來記憶一些其他事情吧!



最近兩三個禮拜我開始在看 Ruby On Rails 的東西,不過也不單單只有 RoR,還有 Java 類似 RoR 的一個 Framework,Grails。Grails 其實是個很不錯的東西,因為它可以說是擷取 RoR 的優點,而又可以兼顧到目前的 JVM 相容性,換句話說,目前 Java 的一些好用 packages 都還可以繼續沿用。Grails 還有搭配了一個新的 Script 語言 - Groovy,所以不僅看了 Grails 也把一本 Groovy 的書籍看得差不多了。結果最後還是決定使用 RoR -_-



RoR 最令人驚艷的部份就是可以快速的開發出 Web Application 雛形。當然除了這個好處之外,RoR 的 ActiveRecord 已經把 Database 整合到 Framework 裡面,因此在開發一些 Database Driven 的應用程式上,RoR 的確是可以加速開發的速度。另外對於 AJAX 的整合部份,RoR 也是比 Java 目前的一些 Framework 好。



因此會陸續開始 RoR 的筆記心得了....


More......

星期五, 5月 04, 2007

Spring Framework 筆記 (五)

寫 Web Form 程式在以往最麻煩的地方就是 Form Validation 部份。早期都只能透過 Javascript 來做 client 端的 validation,但是 Javascript 驗證的缺點就是不好維護,而且要做到 reuse 也相對是比較難一些;Spring 在 Form Validation 方面也提供了一套 validcation 的機制,可以輕鬆的達到 Form Validcation。

 

我們使用一個註冊的 Form 來做例子,提供一個 Register Form 讓使用者可以輸入要申請的帳號以及密碼 (得要輸入兩次以便驗證兩次是否都一樣),而申請的帳號如果是 "jacky",就秀出已經註冊過的訊息;若是密碼兩次輸入不一樣,同樣也會秀出密碼不一樣的錯誤訊息。

 

Form HTML 為:

 

<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta http-equiv="Content-Language" content="zh-tw" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled 1</title>
</head>

<body>

<form method="post" action="register.do">
<table>
<tr>
<td>account:</td>
<td><input name="login" type="text" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input name="passwd" type="password" /></td>
</tr>
<tr>
<td>Password Again:</td>
<td><input name="passwd2" type="password" /></td>
</tr>

<tr>
<td><input name="Submit1" type="submit" value="Register" /></td>
<td></td>
</tr>
</table>
</form>

</body>

</html>

延伸之前例子的 Member Java Bean,多加入了 passwd2 以及 email attribute。

 



package com.esolution.Model;

public class Member {

private String login;
private String passwd;

private String passwd2;

private String email;

public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPasswd2() {
return passwd2;
}
public void setPasswd2(String passwd2) {
this.passwd2 = passwd2;
}


}

修改 URL Mapping 的設定:


<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.htm">


springappController


</prop>


<prop key="/login.do">


springappSimpleFormController


</prop>
<prop key="/register.do">


memberRegisterController


</prop>
</props>
</property>
</bean>


 


 接著因為我們需要 spring 將 form 上面的欄位資料跟 JavaBean binding 在一起,所以需要 spring taglib 來做 data binding:


 


 


<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
<%@ taglib prefix="spring" uri="/spring" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta http-equiv="Content-Language" content="zh-tw" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled 1</title>
</head>

<body>


<spring:bind path="command.*">
<font color="red">

<c:forEach items="${status.errorMessages}" var="error">
<strong><c:out value="${error}"/></strong><br>
</c:forEach>

</font>
</spring:bind>


<form method="post" action="register.do">
<spring:bind path="command">
<table>
<tr>
<td>account:</td>
<td><input name="login" type="text" value="<c:out value='${command.login}'/>"/></td>
</tr>
<tr>
<td>Password:</td>
<td><input name="passwd" type="password" value="<c:out value='${command.passwd}'/>"/></td>
</tr>
<tr>
<td>Password Again:</td>
<td><input name="passwd2" type="password" value="<c:out value='${command.passwd2}'/>"/></td>
</tr>
</spring:bind>


<tr>
<td><input name="Submit1" type="submit" value="Register" /></td>
<td></td>
</tr>
</table>
</form>


</body>


</html>


在上面 JSP Code 中 spring:bind tag 分成兩個部分,錯誤訊息顯示以及 data binding。spring data binding 會使用一個 Command Class 來存 data,而該 command class default 的名稱是 command;例如在上面的例子就是使用 spring:bind tag 將 login、passwd、passwd2 三個 form 欄位跟 Command class binding 在一起 (該 Command class 的名稱叫做 command):若是使用者的輸入驗證沒通過 command.login 、command.passwd、command.passwd2 都會秀出之前使用者輸入的值。至於錯誤訊息顯示的部分 spring 會把錯誤資訊放在 status 變數中。


接著要撰寫 validator 程式:


package com.esolution.Validator;

import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import com.esolution.Model.*;

public class RegisterValidator implements Validator {

public boolean supports(Class clazz) {
return Member.class.isAssignableFrom(clazz);
}

public void validate(Object obj, Errors errors) {
Member member = (Member)obj;
if("jacky".equalsIgnoreCase(member.getLogin())){
errors.rejectValue("login", "existed",null,"The Account is existed");
}

if(! member.getPasswd().equals(member.getPasswd2())){
errors.rejectValue("passwd2", "passwordNotMatch",null, "Passwords does not match");
}

}

}


 Validator 程式主要是要 implemtn Validator  Interface,實做 supports 以及 validate methods:supports 主要是要判別傳進來的 class 參數是否是 Member 或繼承自 Member 的 class;validate method 主要是根據使用者在 form 上面輸入的值來做 validate;在上述程式中我們判斷兩個:一個是假設如果輸入的 login 欄位資料是 jacky,就秀出該帳號已經存在的訊息;若是兩次輸入的密碼不一樣,就秀出密碼不一致的訊息。


rejectValue method 資料如下:


void rejectValue(String field,
String errorCode,
Object[] errorArgs,
String defaultMessage)



field - the field name (may be null or empty String)
errorCode - error code, interpretable as a message key
errorArgs - error arguments, for argument binding via MessageFormat (can be null)
defaultMessage - fallback default message

 

修改 controller 的設定:(加入 validator、formView、commandClass、successView 資料) <bean id="memberRegisterController" class="com.esolution.Controller.MemberRegisterController">
<property name="formView">
<value>register</value>
</property>
<property name="commandClass">
<value>com.esolution.Model.Member</value>
</property>

<property name="successView">
<value>success</value>
</property>

<property name="validator">
<bean class="com.esolution.Validator.RegisterValidator"/>
</property>
</bean>

 




More......

星期四, 5月 03, 2007

Spring Framework 筆記 (四)

在 Web Application 裡面,Form 是一個非常重要的元素,透過 Form,使用者可以 submit 資料到後端的程式。另外 Form 的資料要如何的對應到後端的資料庫 Table 資料、Form 上面資料的資料驗證等等都是在 Form 的處理上需要考慮到的 issues。Spring 已經內建了不少實用的 Controller,其中有一個是 SimpleFormController。

底下是 Spring 一部份的 class diagram,從裡面可以看到 Controller 端,最上層是 Controller Interface,包含單一的 method - handleRequest。首先先看一下 SimpleFormController 的部分 Source Code:


public class SimpleFormController extends AbstractFormController {

private String formView;

private String successView;

protected ModelAndView onSubmit(
HttpServletRequest request, HttpServletResponse response, Object command, BindException errors)
throws Exception {

return onSubmit(command, errors);
}

...
}



 



 


上面的 Source Code 可以看出來,SimpleFormController 繼承自 AbstractFormController,而且它需要formView、successView 以及 command object。formView 可以視為呈現該 form 的頁面,successView 可以視為是 form submit 成功之後,會導向過去的成功頁。至於 Command object 可以視為是把 form 上面的欄位包裝起來的一個 object。而 onSubmit method 是當 form 點了 submit button 之後會 fire 的 method,也是我們需要覆寫的部分。


假設現在我們需要設計一個 login form,裡面只有兩個欄位,一個是 login name 另外一個是 password 欄位,我們需要做 login 以及 password 的檢查,若是檢查成功,則將使用者導到 success.jsp,若是失敗則秀出錯誤訊息。這個簡單的 form HTML soruce 如下:





<html>
<head><title>Spring Login Test</title></head>
<body>

<form name="loginForm" method="POST" action="login.do">
Login: <input name="login" type="text" > <br/>
Password: <input name="passwd" type="password"> <br/>

<input type="submit" value="login">
</form>

</body>
</html>


 


上面是一個非常典型的 Form 程式,包含了一個 login 欄位,以及 password 欄位,而 submit action 是 login.do,而我們現在要使用 spring SimpleFormController 來處理這個 Form。


因為我們設定的 form action 是 login.do,因此我們需要在 web.xml 上面設定 *.do 類型的檔案由 spring 處理:


 


<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

除此之外,我們得要設定 URL mapping,將 login.do mapping 到處理該 submition 的 spring controller。


 


<!-- URL Mapping Defination -->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.htm">springappController</prop>
<prop key="/login.do">springappSimpleFormController</prop>
</props>
</property>
</bean>

 


就如同上面 SimpleFormController source code 所示,我們需要一個 command object 來包含 form 上面的 element,因此我們先產生一個 JavaBean 包括兩個欄位,login 以及 passwd:


 


package com.esolution.Model;

public class Member {

private String login;
private String passwd;

public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}


}



 

接著設定 Spring 設定檔,將 Controller 的 property 填入:<bean id="springappSimpleFormController" class="com.esolution.Controller.SpringappSimpleFormController">

<property name="formView">
   <value>login</value>
</property>


<property name="commandClass">
    <value>com.esolution.Model.Member</value>
</property>


<property name="successView">
    <value>success</value>
</property>
</bean>

 


首先我們需要一個繼承自 SimpleFormController 的 Controller,也就是上面的 springappSimpleFormController,接著我們需要設定它的 formView、commandClass、以及 successView 。formView 代表我們的 form 頁面為 login.jsp、command class 為 Member JavaBean,成功之後會導向 success.jsp。 接著讓我們撰寫 com.esolution.Controller.SpringappSimpleFormController:


 



package com.esolution.Controller;

import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.validation.*;

import javax.servlet.http.*;
import java.util.*;

import com.esolution.Model.*;

public class SpringappSimpleFormController extends SimpleFormController {

public ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object Command, BindException errors) throws Exception
{

Member memberForm = (Member)Command;
Map model = errors.getModel();
model.put("login", memberForm.getLogin());
model.put("passwd", memberForm.getPasswd());


return new ModelAndView(this.getSuccessView(),model);

}


}


 當使用者在 login.jsp 輸入帳號密碼之後,按下 submit 之後,會進入 SpringappSimpleFormController 的 onSubmit method,而根據 JSP 上面的 spring binding,以及 spring 設定檔設定該 command class 為 Member JavaBean,因此我們只要把 Command 轉型為 Member JavaBean,我們就可以直接取出使用者輸入的值了。在這邊我們只是把值取出之後,傳送到 sucessView 頁面。


 


 


More......

星期三, 5月 02, 2007

聲活派知識隨意貼


這是一個聲活派新推出的服務,可以讓使用者將喜歡的書籍以及試聽貼到自己的部落格上。只要將每本書的知識隨意貼語法貼到 blog 上面,就可以擁有該本書的書封以及試聽了。

 

我上面貼著這本書,QBA - 問題背後的問題,是一本很不錯的好書。整本書非常的袖珍,內容沒有很多,但是卻都可以切中主題。花短短的時間,就可以把這本書看完了,極力推薦大家去看看。

 


More......

星期二, 5月 01, 2007

Spring Framework 筆記 (三)

上面的簡單例子可以簡單的描繪出 Spring Framework 在 Web Application 開發上所需要具備的一些元素。因此以 bottom-up 的方式,講完了例子,再反推回去看實際的 Spring Web Application 架構。

底下這張架構圖可以去對應上面的例子,DispatcherServlet 就是例子裡面的 springapp (org.springframework.web.servlet.DispatcherServlet),這個是控制著 Spring Web MVC 的起始點。

HandllerMapping 就是我們在例子裡面使用到的 urlmapping,指定對應到符合某些條件的 request 由哪支程式來做處理 (另外還可以加入一些前置或後置處理的 process)。

Contoller 就是 MVC 架構中的 'C',也就是上面例子裡面的 springappController。

ViewResolver 負責將 ViewName 解析到相對應的 View。

傳統的 JSP/Servlet 處理模式大概就是由 JSP 負責 View 的部分,由 Servlet 負責 Controller 部分,而 Servlet 會繼承自 HttpServlet,並且會覆寫 doPost 或 doGet methods,處理完之後,再 forward 或是 redirect 到結果頁面。在轉到結果頁面的過程中,若是 Servlet 有一些處理的資料需要讓結果頁面來呈現,就會透過 Session 或 HTTPServletRequest 傳遞資料。另外 Model 的部分就是使用 JavaBean 來包裝這些 Domain Model 的資料。

 

 

 

Spring MVC 架構主要也是架構在上述的 JSP MVC Model 2 架構,不過 Spring 將上面的 Model 包裝成一個 Framework,增加開發的 reuse 以及 pluggable 特性。

底下是 Spring Controller Interface 的程式碼,這只是一個 Interface,定義了 Contoller 該有的行為,handleRequest。handleRequest 的作用跟 HTTPServlet 裡面的 doPost 以及 doGet 類似,而最後回傳的是一個 ModelAndView 的 Object。ModelAndView 先不看程式碼,由上述的 JSP MVC Model 2 架構就可以很清楚的看出, ModelAndView 的主要作用在哪了。

 



public interface Controller {

ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;

}



 


再回頭看之前的 springappController 程式碼:

 



public class SpringappController implements Controller {

private String viewFileName;
protected final Log logger = LogFactory.getLog(getClass());

public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

logger.info("SpringappController - returning hello view");

String now = (new java.util.Date()).toString();

return new ModelAndView(getViewFileName(), "now", now);
}

public String getViewFileName() {
return viewFileName;
}

public void setViewFileName(String viewFileName) {
this.viewFileName = viewFileName;
}



}


主要就是 implement Controller Interface,把 handleRequest method 給實際 implement 出來,最後的 ModelAndView 的 View 部分就是從 Setter Injection 指定給 springappController 的 view name,以及現在日期的 model 資料 - now。


 至於 URL mapping 以及 View Resolover 部分,都是直接使用 Spring 內建的 SimpleUrlHandlerMapping 以及 JstlView。除了 SimpleURLHandlerMapping 之後,Spring 還內建了其他的 URM Mapping 方式。同樣的,除了 JstlView 之外,Spring 也可以跟其他的 presenation 架構整合。




More......