17 9月 2007

Spring MVC Validation (Client side)

1. maven2 configuration
        <dependency>
            <groupid>org.springmodules</groupid>
            <artifactid>spring-modules-validation</artifactid>
            <version>0.8a</version>
        </dependency>
2.spring applicationContext.xml
 <bean id="validatorFactory"
  class="org.springmodules.validation.commons.DefaultValidatorFactory">
  <property name="validationConfigLocations">
   <list>
    <value>/WEB-INF/validator-rules.xml</value>
    <value>/WEB-INF/validation.xml</value>
   </list>
  </property>
 </bean>
 <bean id="beanValidator"
  class="org.springmodules.validation.commons.DefaultBeanValidator">
  <property name="validatorFactory" ref="validatorFactory" />
 </bean>
3.Download validator-rules.xml from SpringModules sample Download spring modules and you can use validator-rules.xml in spring-modules-validation-commons-samples-src.zip as sample 4.Use spring modules validation tag library. web.xml
 <jsp-config>
  <taglib>
   <taglib-uri>http://www.springmodules.org/tags/commons-validator</taglib-uri>
   <taglib-location>/WEB-INF/tld/spring-commons-validator.tld</taglib-location>
  </taglib>
 </jsp-config>
jsp
<%@ taglib uri="http://www.springmodules.org/tags/commons-validator" prefix="validator" %>
5.Create validation.js web.xml
 <servlet>
        <servlet-name>javascript</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>javascript</servlet-name>
        <url-pattern>/validation.js</url-pattern>
    </servlet-mapping>
create javascript-servlet.xml
 <bean id="urlMapping"
  class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property name="mappings">
   <props>
    <prop key="/validation.js">
     staticJavascriptController
    </prop>
   </props>
  </property>
 </bean>

 <bean id="staticJavascriptController"
  class="org.springframework.web.servlet.mvc.ParameterizableViewController">
  <property name="viewName">
   <value>/common/validator.jsp</value>
  </property>
 </bean>
create validation.jsp
<%@ page language="java" contentType="javascript/x-javascript" %>
<%@ taglib uri="http://www.springmodules.org/tags/commons-validator" prefix="validator" %>

<validator:javascript dynamicJavascript="false" staticJavascript="true"/>
6.Setting validation.xml and modify jsp form tag jsp form sample
  <form:form commandName="member" onsubmit="return validateLoginForm(this);">
   <form:errors path="*" />
   <table>
    <tr>
     <td>
      Account
     </td>
     <td>
      <form:input path="account"/>
     </td>
    </tr>
    <tr>
     <td>
      Password
     </td>
     <td>
      <form:password path="password"/>
     </td>
    </tr>
    <tr>
     <td>
      <input type="submit">
     </td>
    </tr>
   </table>
  </form:form>
  
  <validator:javascript formName="loginForm" staticJavascript="false"/>
validation.xml
<form-validation>
    <formset>
        <form
                name="loginForm">
            <field
                    property="account"
                    depends="required">
                <arg
                        key="prompt.account"/>
            </field>
            <field
                    property="password"
                    depends="required">
                <arg
                        key="prompt.password"/>
            </field>
        </form>
    </formset>
</form-validation>

11 9月 2007

Update: Run Weblogic on MacOSX

1.Create a new domain: run $BEA_HOME/common/bin/config.sh 2.Update memory usage setting: edit your_domain/bin/setDomainEnv.sh add USER_MEM_ARGS="-Xms512m -Xmx1024m -XX:MaxPermSize=128m"

10 9月 2007

Run Weblogic Server on MacOSX

1. for installation
#java -Dos.name=unix -jar server900_generic.jar

2. for execution
add -Dcom.sun.xml.namespace.QName.useCompatibleSerialVersionUID=1.0 as JAVA_OPTIONS

14 8月 2007

艾蘭治療分工

治療職業預設 聖A,聖B,牧師 (0)常備狀態 聖A開冰抗 聖B開火抗 魔耗3000即喝大藍 (1)艾蘭施放火球,冰箭或秘法 近戰斷法,而因為艾蘭應該一次只對一個人放火球,冰箭或秘法,所以對失血的人員,牧師上盾,聖A及聖B各連續兩個聖光閃現, 視情狀再上恢復與否. 原因: 一個治療量1600以上的聖閃,在不暴擊的情形下,至少可以加到1350,所以1350*4=5400,應該足以補滿失血, 而且聖閃只耗魔180,較牧師的快補來的省魔 (2)奧爆 向牆跑時,聖A及聖B除了解除自身緩速狀態外,並儘可能解身邊附近近戰職業(戰士,賊)的緩速狀態,以便結束後回去斷法 有失血的可以自行繃帶,奧爆結束後,所有遠程人員不要在原地施法或開打,都離開牆邊到內圈,以免失血時無法補血 (3)艾蘭喝水變羊後的炎球 起身後近戰職業吃石頭+喝大紅約可回復(2400+2500),法系只吃石頭, 聖A對牧上保護祝福,開無敵,啟發加神恩,開始唱聖光大補,優先補牧師,獵人,近戰,法系 聖B先補術士,再補法,聖A,近戰 牧師對聖B放盾,上群補,再補法系,近戰 (4)水元素自出現到消失之前 聖B可以準備開無敵,啟發,神恩,可以的話全部唱大補,優先補術士(視情形用保護),近戰 聖A則快補大補並用,主要顧牧師及法系 牧師則以群補,盾及恢復為主

14 4月 2007

行旅、旅行

今天看到商業周刊裡蔣勳談宋代極簡美學,有許多的角度不是單純的欣賞作品,而是提及了時代的現象,普世的想法,作者個人的心境,較之其他的文章來說,實在有趣不少。 其中提到一段“宋朝人知道,不能自大到認為可以征服宇宙,我們只是宇宙的過客,所以,用「行旅」,而不是「旅行」。人要尊敬自然,要留下謙卑“。 行旅則視我為客,旅行則視我為主,簡單的序順不同,卻有截然不同的感觸,再來看這幾幅畫,感覺就完全不同了。 看完文章,欣賞完畫,在心頭重覆的,竟只有「行旅、旅行」…

13 3月 2007

Dependency checking mechanism

Dependency checking mechanism 在使用Spring的dependency injection功能時,有不少人會希望使用constructor injection,主要是因為這樣同時可以確保所有的dependency都一定會被設定到,但我個人比較偏好使用method injection,一方面這樣比較好使用mock object來做測試,一方面我也不喜歡看到一長串難以分別順序的constructor,而且如果要新增一個subclass,那同時也要extends一個至少一樣長的Constructor... Spring forum最近發起了一個新的投票 How do you ensure required dependencies are set?,看看大家最常用的Dependency檢核機制是什麼,目前看來還是以Annotation @Required, implements InitializingBean後以assert檢查及Constructor injection三者略多,當然也有不少票是投給完全不檢查的... 因為我習慣使用method injection,所以在允許的環境下(一定要用JDK5),我也喜歡用@Required來檢查,如果環境不允許,我就會變成完全不檢查... 以spring提供的例子來看@Required的用法 在要檢查Dependency的setter method加上@Required
public class SimpleMovieLister {
 // the SimpleMovieLister has a dependency on the MovieFinder
 private MovieFinder movieFinder;
 // a setter method so that the Spring container can 'inject' a MovieFinder
 @Required
 public void setMovieFinder(MovieFinder movieFinder) {
  this.movieFinder = movieFinder;
 }
}
然後還需要在xml中加入
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
做為執行檢查@Required之用 如果原本開發系統已經有類似的Annotation,或是不想之後一定要使用Spring,可以使用自定的Annotation
package org.elliot.jdk;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Mandatory {

}
在xml只要加入像下列config即可使用自訂的Annotation達成相同的效果
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor">
 <property name="requiredAnnotationType" value="org.elliot.jdk.Mandatory"/>
</bean>

07 3月 2007

記得

是不是有這樣的一首歌,這樣的一些人, 總在人聲漸歇時在思緒裡緩緩地浮起? 我還記得 --梁靜茹 絲路 十年後的今天遇見你 年少輕狂已遠去 成熟穩重也保持距離 沉默裡千言萬語 時光回到那年夏天 公車站前你笑容滿面 拍拍我的頭 說你好嗎? 一句問候填滿青春 別人的話都聽不見 歲月凝結在你的視線 我還記得那年傾盆大雨 狼狽奔跑穿越幾條街 握緊的雙手 為愛的不顧一切 我還記得那年你的聲音 耳邊迴盪那一句誓言 你吻我的臉 都是我心中 收藏一生的快樂 漸漸我們都有新朋友 多久不再並肩走 忙忙碌碌看人生匆匆 忘記了年輕的夢 好想回到那年夏天 教室門前你笑容滿面 拍拍我的頭 說妳別哭 考壞一次不是末日 未來還有很長的路 我們要一起去看世界 我還記得那年晴空萬里 那一道飛機雲的弧線 蜿蜒著思念 寫下故事的總結 我還記得那年你的年輕 刻在從前最美的時間 在我生命裡 你不曾告別 不曾走遠 與你重逢前一個夜晚 往事在夢中上演 終要去體驗 真實人生的殘缺 我還記得那年晴空萬里 那一道飛機雲的弧線 蜿蜒著思念 寫下故事的總結 我還記得那年你的年輕 刻在從前最美的時間 在我生命裡 你不曾告別 不曾走遠

True Colors

True Colors - Cyndi Lauper You with the sad eyes don't be discouraged oh I realize it's hard to take courage in a world full of people you can lose sight of it all and the darkness inside you can make you fell so small But I see your true colors shining through I see your true colors and that's why I love you so don't be afraid to let them show your true colors true colors are beautiful like a rainbow Show me a smile then don't be unhappy, can't remember when I last saw you laughing if this world makes you crazy and you've taken all you can bear you call me up because you know I'll be there And I'll see your true colors shining through I see your true colors and that's why I love you so don't be afraid to let them show your true colors true colors are beautiful like a rainbow 這大概是我iTunes裡撥放次數最高的歌曲,間歇而有力的簡單節奏,略帶沙啞而獨特的嘶喊,鼓舞著總是略帶遲疑的我----做自己。

05 3月 2007

Struts2 Note -- (3)Action Method Invocation

Action method invocation 在Struts中使用DispatchAction及設定parameter來操做同一個Action的不同Method,可以減去不少的Action數量. 在Struts2中,可以使用wildcard來達成.如下列這個Action. MyAction.java
public class MyAction extends ActionSupport {
 public String input() {
  return "patha";
 }
 
 public String output() {
  return "pathb";
 }
}
然後在struts.xml中以"*"來代表特定組合的文字,再以"{num}"取用. struts.xml
<package name="myaction" namespace="/struts2" extends="struts-default">
 <action name="myaction_*" method="{1}" class="MyAction">
  <result name="patha">
   /jsp/inputResult.jsp
  </result>
  <result name="pathb">
   /jsp/outputResult.jsp
  </result>
 </action>
</package>
這樣的話執行 http://localhost:8080/mystruts/struts2/myaction_input.action 會呼叫MyAction.input()->patha 而下列的URL http://localhost:8080/mystruts/struts2/myaction_output.action 會呼叫MyAction.output()->pathb 看起來便利性上兩者相差不遠,不過wildcard的用途還不止如此....

Gerneric Sample

善用Generic可以減少相當多的程式碼,基本上一定會用的是在DAO及Service中 BaseDao
public interface BaseDao<T, ID extends Serializable> {
 public T get(ID id);
 
 public void save(T entity);

 public void delete(T entity);

 public List findAll(String[] ascProperties, String[] descProperties);
 
 public List findByExample(T entity, String[] ascProperties, String[] descProperties);
 
 public int countByExample(T entity);
}
HibernateBaseDao
public abstract class HibernatetBaseDao<T, ID extends Serializable> extends
  HibernateDaoSupport {

 private Class domainClass;

 public HibernatetBaseDao() {
  this.domainClass = (Class) ((ParameterizedType) getClass()
    .getGenericSuperclass()).getActualTypeArguments()[0];
 }

 public void delete(T entity) {
  this.getHibernateTemplate().delete(entity);
 }

 @SuppressWarnings("unchecked")
 public List findAll(String[] ascProperties, String[] descProperties) {
  Criteria criteria = this.getSession().createCriteria(this.domainClass);
  this.addOrderToCriteria(criteria, ascProperties, descProperties);
  return criteria.list();
 }

 @SuppressWarnings("unchecked")
 public List findByExample(T entity, String[] ascProperties,
   String[] descProperties) {
  Criteria criteria = this.getSession().createCriteria(this.domainClass);
  Example example = Example.create(entity);
  criteria.add(example);
  this.addOrderToCriteria(criteria, ascProperties, descProperties);
  return criteria.list();
 }

 @SuppressWarnings("unchecked")
 public T get(ID id) {
  return (T) this.getHibernateTemplate().get(this.domainClass, id);
 }

 public void save(T entity) {
  this.getHibernateTemplate().saveOrUpdate(entity);
 }

 public int countByExample(T entity) {
  Criteria criteria = this.getSession().createCriteria(this.domainClass);
  if (null != entity) {
   Example example = Example.create(entity);
   criteria.add(example);
  }
  return ((Integer) criteria.setProjection(Projections.rowCount()).list()
    .iterator().next()).intValue();
 }

 protected void addOrderToCriteria(Criteria criteria,
   String[] ascProperties, String[] descProperties) {
  if (null != ascProperties && 0 < ascProperties.length) {
   for (String property : ascProperties) {
    criteria.addOrder(Order.asc(property));
   }
  }
  if (null != descProperties && 0 < descProperties.length) {
   for (String property : descProperties) {
    criteria.addOrder(Order.desc(property));
   }
  }
 }

 public Class getDomainClass() {
  return domainClass;
 }

 public void setDomainClass(Class domainClass) {
  this.domainClass = domainClass;
 } 
}
BaseManager
public interface BaseManager<T, ID extends Serializable> {
 public T get(ID id);
 public void save(T entity);
 public void delete(T entity);
 public void delete(ID id);
 public List findAll();
 public List findAll(String[] ascProperties, String[] descProperties);
 public List findByExample(T entity);
 public List findByExample(T entity, String[] ascProperties, String[] descProperties);
 public int count();
 public int countByExample(T entity);
}
AbstractBaseManager
public abstract class AbstractBaseManager<T, ID extends Serializable, DAO extends BaseDao<T, ID>> {
 private DAO baseDao;

 public T get(ID id) {
  return baseDao.get(id);
 }

 public void save(T entity) {
  this.baseDao.save(entity);
 }

 public void delete(T entity) {
  this.baseDao.delete(entity);
 }

 public void delete(ID id) {
  this.baseDao.delete(this.get(id));
 }

 public List findAll() {
  return this.findAll(new String[0], new String[0]);
 }

 public List findAll(String[] ascProperties, String[] descProperties) {
  return this.baseDao.findAll(ascProperties, descProperties);
 }

 public List findByExample(T entity) {
  return this.findByExample(entity, new String[0], new String[0]);
 }

 public List findByExample(T entity, String[] ascProperties,
   String[] descProperties) {
  return this.findByExample(entity, ascProperties, descProperties);
 }

 public int count() {
  return this.countByExample(null);
 }

 public int countByExample(T entity) {
  return this.baseDao.countByExample(entity);
 }

 public DAO getBaseDao() {
  return baseDao;
 }

 public void setBaseDao(DAO baseDao) {
  this.baseDao = baseDao;
 }

}
這樣每新增一個Domain Class要做基本的CRUD時,僅需要這樣宣告
public interface MasterDao extends BaseDao<Master, String> {

}
public class MasterDaoImpl extends HibernatetBaseDao<Master, String> implements MasterDao {
 public MasterDaoImpl() {
  super();
 }
}
public interface MasterManager extends BaseManager<Master, String> {

}
public class MasterManagerImpl extends AbstractBaseManager<Master, String, MasterDao> implements
  MasterManager {

}
雖然Service與DAO間Method重覆性太高,但是維持了架構的一致性,雖然不是很滿意,還好目前使用Generic減少了重覆的Code,還算是可以接受.

03 3月 2007

Tomcat Note -- (1)

最近常用的OpenSource更新項目不少,繼Maven2、Struts2後,Tomcat也發佈了Stable的6.0.10版本,之前還是測試時,沒有特別去關心,反正5.5還是很夠用,直到6.0.10才有點興趣。 這版有些不同,Log4j已經不是預設的Log Library,若要用還請下載Source Code的Distribution,再依docs/logging.html中的說明產生需要的component。 另一點,Apache Tomcat Native library仍然未放入其中,所以需的的人除了下載APR自行compile外,也可以至HEAnet下載放入$CATALINA_HOME/bin下即可。

02 3月 2007

Struts2 Note -- (2)整合Spring2

2.0.6與之前版本整合的設定 2.0.6與之前版本的整合方式有很大不同,而整合的Spring版本也從1.2.8到了2.0.1 2.0.6將org.apache.struts2.spring.StrutsSpringObjectFactory自struts2-core移至struts2-spring-plugin, 所以必需要加入struts2-spring-plugin的Library.使用Maven2的可以這樣設定 pom.xml
<dependency>
 <groupId>org.apache.struts</groupId>
 <artifactId>struts2-spring-plugin</artifactId>
 <version>2.0.6</version>
</dependency>
2.0.6與之前的版本皆需在struts.propertis中設定
struts.objectFactory = spring
struts2-spring-plugin中除了org.apache.struts2.spring.StrutsSpringObjectFactory這個主要java外, 另外有的就是一個struts-plugin.xml,設定了struts.objectFactory真正使用的Class struts-plugin.xml
<struts>
    <bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" />
    
    <!--  Make the Spring object factory the automatic default -->
    <constant name="struts.objectFactory" value="spring" />

    <package name="spring-default">
        <interceptors>
            <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
            <interceptor name="sessionAutowiring" class="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor"/>
        </interceptors>
    </package>    
</struts>
2.0.6與之前版本整合的差異 之前的版本是這樣整合的
org.apache.struts2.dispatcher.Dispatcher
 private void init(ServletContext servletContext) {
  .......................
  if (Settings.isSet(StrutsConstants.STRUTS_OBJECTFACTORY)) {
   String className = (String) Settings.get(StrutsConstants.STRUTS_OBJECTFACTORY);
   if (className.equals("spring")) {
    className = "org.apache.struts2.spring.StrutsSpringObjectFactory";
   }
  }
  .......................
 }
很明顯的有硬來的嫌疑 2.0.6則是分為了幾個部份
org.apache.struts2.dispatcher.Dispatcher
 public void init() {
  init_DefaultProperties(); // [1]
  init_TraditionalXmlConfigurations(); // [2]
  init_LegacyStrutsProperties(); // [3]
  .......................
  init_AliasStandardObjects() ; // [4]
  .......................
 }
[1]載入了org/apache/struts2/default.properties [2]利用了StrutsXmlConfigurationProvider來載入struts-default.xml,struts-plugin.xml,struts.xml三個xml, 其中就包含了struts2-spring-plugin的struts-plugin.xml,這樣就能取得 <constant name="struts.objectFactory" value="spring" /> <bean ... name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" /> 這兩項設定 [3]載入struts.properties,透過手動設定的struts.objectFactory = spring, 就可以明白要載入的ObjectFactory Class是哪一個了 [4]此時才真正載入所有指定的Class 這樣做得確是較之前的方式好上不少,但是xml的設定檔就只能有這三個struts-default.xml,struts-plugin.xml,struts.xml 特別是struts-plugin.xml,如果自己還要寫Plugin或是希望同時能使用兩種不同的Plugin,都會遇到設定的問題.

28 2月 2007

Struts2 Note -- (1)struts-tags.tld

Struts2發佈了2.0.6,下載後沒有注意到一件事,自2.0.6後的版本,struts-tags.tld要自 source code中經maven2 build後才會產生,所以找了老半天還有點火…,還好看了一下core/src/main/resources/META-INF/README.txt,才發現這個版本是要透過maven2才能產生struts-tags.tld,只好自行run mvn來做了,需要的話可以參考Building with Maven,遇上了OutOfMemoryError別忘了為Maven2加上個MAVEN_OPTS=-Xmx512m參數來執行。 我個人是有裝Maven2,所以問題不大,不過如果是希望下載後就能使用而且沒有需求使用Maven2的朋友,還是可能會感到些許不便吧。

27 2月 2007

First Struts2 Project with Eclipse and Maven2

一個基本的Eclipse Struts Project至少需要以下的設定 pom.xml
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>org.elliot</groupId>
 <artifactId>firststruts</artifactId>
 <packaging>war</packaging>
 <name>firststruts</name>
 <version>1.0-SNAPSHOT</version>
 <url>http://maven.apache.org</url>
 <build>
  <sourceDirectory>${basedir}/src/main/java</sourceDirectory>
  <testSourceDirectory>
   ${basedir}/src/test/java
  </testSourceDirectory>
  <resources>
   <resource>
    <directory>${basedir}/src/main/resources</directory>
   </resource>
  </resources>
  <testResources>
   <testResource>
    <directory>${basedir}/src/test/resources</directory>
   </testResource>
  </testResources>
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
     <source>1.5</source>
     <target>1.5</target>
    </configuration>
   </plugin>

   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.0.2</version>
    <configuration>
     <warName>firststruts</warName>
    </configuration>
   </plugin>
  </plugins>
 </build>
 <dependencies>
  <dependency>
   <groupId>org.apache.struts</groupId>
   <artifactId>struts2-core</artifactId>
   <version>2.0.6</version>
  </dependency>
 </dependencies>
 <repositories>
  <repository>
   <id>Struts2</id>
   <name>Struts2</name>
   <snapshots>
    <enabled>true</enabled>
   </snapshots>
   <url>
    http://people.apache.org/repo/m2-snapshot-repository
   </url>
  </repository>
 </repositories>
</project>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
 xmlns="http://java.sun.com/xml/ns/j2ee" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 <display-name>firststruts</display-name>
 <filter>
  <filter-name>struts2</filter-name>
  <filter-class>
   org.apache.struts2.dispatcher.FilterDispatcher
  </filter-class>
 </filter>
 <filter-mapping>
  <filter-name>struts2</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
 <jsp-config>
  <taglib>
   <taglib-uri>/struts-tags</taglib-uri>
   <taglib-location>/WEB-INF/struts-tags.tld</taglib-location>
  </taglib>
 </jsp-config>
</web-app>
resources還需要有struts.properties struts.devMode = true struts.enable.DynamicMethodInvocation = false 然後實做自己的Action extends from com.opensymphony.xwork2.ActionSupport 加入到struts.xml中即可 struts.xml
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="first" namespace="/" extends="struts-default">
        <action name="first" class="org.elliot.action.FirstAction">
            <result name="Success">/jsp/first/firstActionResult.jsp</result>
        </action>
    </package>
</struts>

26 2月 2007

Blogger 上顯示程式碼

一直都為了在Blogger上張貼程式的格式困擾,直到今天晃到這幾篇Blog [筆記]在文章裡顯示優質的程式碼區 at 良人的大秘寶
【Blog】文章中引用程式碼的作法 at 想要旅行的念頭停不住
才有了解決的方式,加入以下的CSS設定
CODE, .code  { 
  display: block; /* fixes a strange ie margin bug */
  font-family: Courier New; 
  font-size: 8pt; 
  overflow:auto; 
  background: #f0f0f0 url(http://chenensign.googlepages.com/BG_CODE.gif) left top repeat-y;
  border: 1px solid #ccc;
  padding: 10px 10px 10px 21px;
  max-height:200px;
  line-height: 1.2em;
}

CMD, .cmd {
  display: block; /* fixes a strange ie margin bug */
  font-family: Courier New; 
  font-size: 8pt; 
  overflow:auto; 
  color: #ccc;
  background: #000 url(http://chenensign.googlepages.com/BG_CMD.gif) left top repeat-y;
  border: 1px solid #ccc;
  padding: 10px 10px 10px 21px;
  max-height:200px;
  line-height: 1.2em;
}
這樣只要在程式碼區域前後加上 <pre class="code"> </pre>就可以顯示較為明顯的程式碼了!

08 2月 2007

Hibernate Annotations - One-to-One mappedBy的影響

One-to-One mappedBy的影響 Hibernate Annotations的說明
The association may be bidirectional. In a bidirectional relationship, one of the sides (and only one) has to be
the owner: the owner is responsible for the association column(s) update. To declare a side as not responsible
for the relationship, the attribute mappedBy is used. mappedBy refers to the property name of the association on
the owner side.
在Hibernate中雙向的Relationship的維護上,必定有一方為Owner來記錄此Relationship. 而mappedBy就是為了宣告其本身不負責記錄Relationship,交由另一方記錄所使用的annotation attribute. Bidirectional 的 One-to-One通常還是有主從的概念,以下列Person為主,Passport為從來看 (1)將mappedBy設在Person(從)上
public class Person implements Serializable {
 @Id
 @GeneratedValue(generator = "uuid-gen")
 @GenericGenerator(name = "uuid-gen", strategy = "uuid")
 @Column(length = 32)
 private String id;
 
 @OneToOne(cascade= CascadeType.ALL)
 private Passport passport;
}
public class Passport implements Serializable {
 @Id
 @GeneratedValue(generator = "uuid-gen")
 @GenericGenerator(name = "uuid-gen", strategy = "uuid")
 @Column(length = 32)
 private String identificationCode;
 
 @OneToOne(mappedBy="passport")
 private Person owner;
}
Create Table SQL
create table Passport (identificationCode varchar(32) not null, primary key (identificationCode))
create table Person (id varchar(32) not null, version integer, name varchar(50), firstName varchar(50), lastName varchar(50), mutable bit, birthday date, age integer, modifyDate timestamp, description longvarchar, passport_identificationCode varchar(32), primary key (id))
alter table Person add constraint FK8E488775EB061869 foreign key (passport_identificationCode) references Passport
Hibernate SQL Execution
Hibernate: insert into Person (version, name, firstName, lastName, mutable, birthday, age, modifyDate, description, passport_identificationCode, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: select this_.id as id0_1_, this_.version as version0_1_, this_.name as name0_1_, this_.firstName as firstName0_1_, this_.lastName as lastName0_1_, this_.mutable as mutable0_1_, this_.birthday as birthday0_1_, this_.age as age0_1_, this_.modifyDate as modifyDate0_1_, this_.description as descrip10_0_1_, this_.passport_identificationCode as passport11_0_1_, passport2_.identificationCode as identifi1_1_0_ from Person this_ left outer join Passport passport2_ on this_.passport_identificationCode=passport2_.identificationCode
Hibernate: insert into Passport (identificationCode) values (?)
Hibernate: update Person set version=?, name=?, firstName=?, lastName=?, mutable=?, birthday=?, age=?, modifyDate=?, description=?, passport_identificationCode=? where id=? and version=?
Hibernate會將passport_identificationCode建在Person的Table中,而在Select時,會一併帶出Passport的資料 (2)將mappedBy設在Passport(主)上
public class Person implements Serializable {
 @Id
 @GeneratedValue(generator = "uuid-gen")
 @GenericGenerator(name = "uuid-gen", strategy = "uuid")
 @Column(length = 32)
 private String id;
 
 @OneToOne(mappedBy="owner",cascade= CascadeType.ALL)
 private Passport passport;
}
public class Passport implements Serializable {
 @Id
 @GeneratedValue(generator = "uuid-gen")
 @GenericGenerator(name = "uuid-gen", strategy = "uuid")
 @Column(length = 32)
 private String identificationCode;
 
 @OneToOne
 private Person owner;
}
Create Table SQL
create table Passport (identificationCode varchar(32) not null, owner_id varchar(32), primary key (identificationCode))
create table Person (id varchar(32) not null, version integer, name varchar(50), firstName varchar(50), lastName varchar(50), mutable bit, birthday date, age integer, modifyDate timestamp, description longvarchar, primary key (id))
alter table Passport add constraint FK4C60F032538A0EEB foreign key (owner_id) references Person
Hibernate SQL Execution
Hibernate: insert into Person (version, name, firstName, lastName, mutable, birthday, age, modifyDate, description, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: select this_.id as id0_1_, this_.version as version0_1_, this_.name as name0_1_, this_.firstName as firstName0_1_, this_.lastName as lastName0_1_, this_.mutable as mutable0_1_, this_.birthday as birthday0_1_, this_.age as age0_1_, this_.modifyDate as modifyDate0_1_, this_.description as descrip10_0_1_, passport2_.identificationCode as identifi1_1_0_, passport2_.owner_id as owner2_1_0_ from Person this_ left outer join Passport passport2_ on this_.id=passport2_.owner_id
Hibernate: insert into Passport (owner_id, identificationCode) values (?, ?)
Hibernate: update Person set version=?, name=?, firstName=?, lastName=?, mutable=?, birthday=?, age=?, modifyDate=?, description=? where id=? and version=?
Hibernate會將owner_id建在Passport的Table中,而在Select時,不會一併帶出Passport的資料 可能的話,應該還是將mappedBy設在(主)的那一方上,讓(從)的一方記錄relationship的欄位. 否則的話就如同Component,不如就整在同一Table裡,還可以省去join的時間.

29 1月 2007

Use xdoclet2 hibernate plugin in Maven2

(1) Add pluginRepositories element to your pom.xml
<project>
 <pluginRepositories>
  <pluginRepository>
   <id>codehaus-plugins</id>
   <url>http://dist.codehaus.org/</url>
   <layout>legacy</layout>
   <snapshots>
    <enabled>true</enabled>
   </snapshots>
   <releases>
    <enabled>true</enabled>
   </releases>
  </pluginRepository>
 </pluginRepositories>
</project>
(2) Add xdoclet2 plugin to pom.xml
<plugins>
 <plugin>
  <groupId>xdoclet</groupId>
  <artifactId>maven2-xdoclet2-plugin</artifactId>
  <executions>
   <execution>
    <id>xdoclet</id>
    <phase>generate-sources</phase>
    <goals>
     <goal>xdoclet</goal>
    </goals>
   </execution>
  </executions>
  <dependencies>
   <dependency>
    <groupId>xdoclet-plugins</groupId>
    <artifactId>
     xdoclet-plugin-hibernate
    </artifactId>
    <version>1.0.4-SNAPSHOT</version>
   </dependency>
  </dependencies>
  <configuration>
   <configs>
    <config>
     <components>
      <component>
       <classname>
        org.xdoclet.plugin.hibernate.HibernateMappingPlugin
       </classname>
      </component>
     </components>
     <params>
      <version>3.0</version>
     </params>
    </config>
   </configs>
  </configuration>
 </plugin>
</plugins>
(3) Run mvn compile

Technorati Tags: , ,