ในตัวอย่างที่เขียนนี้เป็นแค่หน้ากรอก ขื่อผู้ใช้เข้ามา แล้วลง ชื่อ และ เวลาที่เข้าใช้ใน database
จะช้าไปใย เราก็เริ่มกันเลยดีกว่า
เริ่มจาก create project ในรูปแบบของ web แล้วเราจะได้ โครงสร้าง แล้วเพิ่ม file ต่าง ๆ ลงไปตามนี้
ในที่นี้ create project ด้วย netbean maven ดังนั้นก็ไม่ต้องคิดมากถ้ามีอะไรบางอย่างวางแปลกที่ไป
อย่าไปสนใจ เอาไว้แค่ดูคร่าว ๆ ว่ามี file อะไรบ้างที่จำเป็นแค่นั้นพอ
> Web App
>>> Web Pages
>>>>> WEB-INF
>>>>> - applicationContext.xml
>>>>> - datasource.xml
>>>>> - faces-config.xml
>>>>> - glassfish-web.xml
>>>>> - hibernate.xml
>>>>> - web.xml
>>> - hello.xhtml
>>> - index.jsp
>>> - welcome.xhtml
>>> Source Packages
>>>>> com.mycompany.projecttracking.jsfbean
>>>>> - HellowWorldBean.java
>>>>> com.mycompany.projecttracking.model
>>>>> - BeanEntity.java
>>>>> - WelcomeLog.java
>>>>> com.mycompany.projecttracking.service
>>>>> - WelcomeLogDao.java
>>>>> - WelcomeLogDaoImpl.java
>>> Project Files
>>> - pom.xml
ในตอนแรก เพื่อให้ง่ายต่อผู้ใช้ maven เรามา add depandency กันก่อนดีกว่า ส่วนผู้ที่ไม่ได้ใช้ maven เราเรามาบอกอีกทีว่าใช้ .jar อะไรบ้าง ในขั้นต่อไปนะ
org.springframework spring-core 3.0.5.RELEASE org.springframework spring-context 3.0.5.RELEASE org.springframework spring-aop 3.0.5.RELEASE org.springframework spring-aspects 3.0.5.RELEASE org.springframework spring-asm 3.0.5.RELEASE org.springframework spring-jdbc 3.0.5.RELEASE org.springframework spring-beans 3.0.5.RELEASE org.springframework spring-context-support 3.0.5.RELEASE org.springframework spring-instrument 3.0.5.RELEASE org.springframework spring-expression 3.0.5.RELEASE org.springframework spring-webmvc 3.0.5.RELEASE org.springframework spring-tx 3.0.5.RELEASE org.springframework spring-orm 3.0.5.RELEASE jar org.springframework spring-test 3.0.5.RELEASE org.springframework spring-web 3.0.5.RELEASE org.springframework.security spring-security-core 3.0.5.RELEASE org.springframework.security spring-security-web 3.0.5.RELEASE org.springframework.security spring-security-config 3.0.5.RELEASE org.springframework.security spring-security-taglibs 3.0.5.RELEASE org.hibernate hibernate-core 3.3.2.GA org.hibernate ejb3-persistence 1.0.1.GA org.hibernate hibernate-entitymanager 3.3.2.GA org.hibernate hibernate-annotations 3.3.1.GA org.hibernate hibernate-commons-annotations 3.3.0.ga javax.sql jdbc-stdext 2.0 javax.transaction jta 1.0.1B mysql-connector mysql-connector-java-5.1.5-bin SNAPSHOT log4j log4j 1.2.14 org.aspectj aspectjrt 1.6.10 com.sun.faces jsf-api 2.1.1-b04 com.sun.faces jsf-impl 2.1.1-b04 jstl jstl 1.1.2 javax javaee-web-api 6.0 compile junit junit 4.8.1 test slf4j slf4j-log4j12 1.5.8 com.oracle ojdbc6 11.2.0.2.0
กรณีที่ไม่ต้องการให้ run test ตอน deploy ให้เพิ่ม tag ส่วนนี้เข้าไป ใน build
อันนี้ใช้ตอนที่ test ของเรามี environment บางอย่างที่อาจทำให้ error ตอน run แต่ถ้าบางคนไม่เคยเขียน test เลยก็ไม่ต้องใช้ก็ได้นะครับ เข้าใจว่างานเร่งไม่มีเวลาเขียนกัน หรือเขียนไปก็ไม่เคยใช้ เหอ ๆ
org.apache.maven.plugins maven-surefire-plugin true surefire-it integration-test test true
ส่วนผู้ที่ไม่ได้ใช้ maven ก็ add .jar file ดังต่อไปนี้ (จริง ๆ อาจไม่ต้องขนาดนี้ แต่ copy มาจาก jar ที่ได้จาก maven ข้างบน แล้วไม่มีเวลามาตัดให้ว่าอันใหนใช้จริง ต้องขอโทษด้วยครับ ^^")
aspectjrt-1.6.10.jar
ejb3-persistence-1.0.1.GA.jar
hibernate-annotations-3.3.1.GA.jar
hibernate-commons-annotations-3.3.0.ga.jar
hibernate-core-3.3.2.GA.jar
hibernate-entitymanager-3.3.2.GA.jar
javaee-web-api-6.0.jar
jdbc-stdext-2.0.jar
jsf-api-2.1.1-b04.jar
jsf-impl-2.1.1-b04.jar
jstl-1.1.2.jar
jta-1.0.1B.jar
log4j-1.2.14.jar
mysql-connector-java-5.1.5-bin-SNAPSHOT.jar
ojdbc6-11.2.0.2.0.jar
slf4j-log4j12-1.5.8.jar
spring-aop-3.0.5.RELEASE.jar
spring-asm-3.0.5.RELEASE.jar
spring-aspects-3.0.5.RELEASE.jar
spring-beans-3.0.5.RELEASE.jar
spring-context-3.0.5.RELEASE.jar
spring-context-support-3.0.5.RELEASE.jar
spring-core-3.0.5.RELEASE.jar
spring-expression-3.0.5.RELEASE.jar
spring-instrument-3.0.5.RELEASE.jar
spring-jdbc-3.0.5.RELEASE.jar
spring-orm-3.0.5.RELEASE.jar
spring-security-config-3.0.5.RELEASE.jar
spring-security-core-3.0.5.RELEASE.jar
spring-security-taglibs-3.0.5.RELEASE.jar
spring-security-web-3.0.5.RELEASE.jar
spring-test-3.0.5.RELEASE.jar
spring-tx-3.0.5.RELEASE.jar
spring-web-3.0.5.RELEASE.jar
spring-webmvc-3.0.5.RELEASE.jar
antlr-2.7.6.jar
aopalliance-1.0.jar
asm-1.5.3.jar
asm-attrs-1.5.3.jar
aspectjweaver-1.6.8.jar
cglib-2.1_3.jar
commons-collections-3.1.jar
commons-logging-1.1.1.jar
dom4j-1.6.1.jar
ehcache-1.2.3.jar
hibernate-3.2.6.ga.jar
javassist-3.4.GA.jar
persistence-api-1.0.jar
slf4j-api-1.5.8.jar
spring-security-acl-3.0.5.RELEASE.jar
xml-apis-1.0.b2.jar
junit-4.8.1.jar
ขั้นตอนแรกที่จำเป็นต้องทำคือ แก้ไข file : web.xml
contextConfigLocation /WEB-INF/applicationContext.xml org.springframework.web.context.ContextLoaderListener org.springframework.web.context.request.RequestContextListener javax.faces.PROJECT_STAGE Development javax.faces.FACELETS_SKIP_COMMENTS true com.sun.faces.expressionFactory com.sun.el.ExpressionFactoryImpl Faces Servlet javax.faces.webapp.FacesServlet 1 Faces Servlet *.xhtml 30 index.jsp
และ faces-config.xml ประกาศไว้ก่อนยังไม่ได้ใช้อะไรในตอนนี้มาก
org.springframework.web.jsf.el.SpringBeanFacesELResolver
ต่อมาเป็น config spring context : applicationContext.xml
<import resource="/datasource.xml" /> <import resource="/hibernate.xml" /> <context:annotation-config/> <context:component-scan base-package="com.mycompany.projecttracking" />
ต่อมาเป็น config database (ในที่นี้ต่อเข้าเครื่องตัวเองครับ ใช้ oracle 11g xe free) : datasource.xml
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" /> <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" /> <property name="username" value="SYSTEM" /> <property name="password" value="system" />
ต่อมาเป็น config hibernate : hibernate.xml
config ในที่นี้ table database จะถูกสร้างเองเมื่อ run web app อันดับต่อไป ก็เป็นส่วน service แต่ในที่นี้เขียน dao แล้วต่อตรงไปเลย แบบว่าให้สั้น ๆ ไว้ก่อน เพราะทำเป็น ตัว demo เล่น ๆ เฉย ๆ ส่วนเรื่องวิธีเขียน service ก่อน เข้า dao ไปดูบทเก่า ก่อนหน้านี้มีเคยเขียนไว้ BaseEntity.java<property name="dataSource" ref="dataSource" /> <property name="schemaUpdate" value="true"/> <property name="packagesToScan" value="com.mycompany.projecttracking.model"/> org.hibernate.dialect.OracleDialect true false
package com.mycompany.projecttracking.model;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
@MappedSuperclass
public class BaseEntity implements Serializable {
@Column
private String createBy;
@Column
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
private Date createDate;
@Column
private String updateBy;
@Column
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
private Date updateDate;
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
}
WelcomeLog.java
package com.mycompany.projecttracking.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
@Entity
@Table(name="WELCOME_LOG")
public class WelcomeLog extends BaseEntity{
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_WCL_GEN")
@SequenceGenerator(name = "SEQ_WCL_GEN", sequenceName = "SEQ_WCL")
private Long id;
@Column
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
WelcomeLogDao.java
package com.mycompany.projecttracking.service;
public interface WelcomeLogDao {
public void log2DB(String name);
}
WelcomeLogDaoImpl.java
package com.mycompany.projecttracking.service;
import com.mycompany.projecttracking.model.WelcomeLog;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;
@Repository("welcomeLogDao")
public class WelcomeLogDaoImpl implements WelcomeLogDao{
@Autowired
private HibernateTemplate hibernateTemplate;
@Override
public void log2DB(String name) {
WelcomeLog wl = new WelcomeLog();
wl.setCreateBy("SYSTEM");
wl.setCreateDate(new Date());
wl.setUsername(name);
hibernateTemplate.save(wl);
}
}
ในส่วนของ spring ที่ทำหน้าที่ service มีแค่นี้ จากนั้นก็มาในส่วน jsf
ส่วนแรกก็คงเป็นหน้า web จะ create เป็น .xhtml
hello.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!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"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
Hello from Facelets.<br />
<h:form prependId="false">
Your name : <h:inputText value="#{hwBean.username}"></h:inputText><br />
<h:commandButton value=" == OK == " action="welcome.xhtml"></h:commandButton>
</h:form>
</h:body>
</html>
welcome.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!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"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<h:outputText value="#{hwBean.message}" />
</h:form>
</h:body>
</html>
ต่อจากนั้นก็สร้าง bean ที่ทำการผูก action ให้หน้า web
HelloWorldBean.java
package com.mycompany.projecttracking.jsfbean;
import com.mycompany.projecttracking.service.WelcomeLogDao;
import java.io.Serializable;
import org.springframework.context.annotation.Scope;
import javax.inject.Inject;
import javax.inject.Named;
@Named("hwBean")
@Scope("request")
public class HelloWorldBean implements Serializable {
private String username;
private String message;
@Inject
private WelcomeLogDao welcomeLogDao;
public void setMessage(String message){
this.message = message;
}
public String getMessage(){
return message;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.message = "Welcome : " + username;
this.username = username;
welcomeLogDao.log2DB(username);
}
}
เราจะเห็น annotation @Named และ @Inject ในส่วนของ jsf นี้ ซึ่งจริง ๆ เป็น มาตรฐานของ jee เลย แล้ว spring ก็มีวิธีใช้ annotation ตัวนี้แทน @Repository และ @AutoWierd ด้วย ซึ่งจะทำให้เป็นไปในแนวทางเดียวกัน ทั้ง app ที่เราเขียนขึ้น
เอาไว้คราวหน้าจะเขียนเรื่องการใช้ annotation มาตรฐานตัวนี้มาแทน annotation spring เดิม นี้อีกที
หลังจากนั้น ก็ run web app กันเลย
เราก็จะเข้า url : http://localhost:8080/{Web App}/hello.xhtml
ในที่นี้ {Web App} ก็คือชื่อ project ที่เราตั้งไว้
เมื่อเราเข้ามาที่หน้าแรก ก็จะใช้กรอก Your name : [ ]
หลักจากนั้น กดปุ่ม [ == OK == ]
ก็จะย้ายไปที่หน้า welcome.xhtml
Welcome : { ชื่อ ที่กรอกที่หน้า hello.xhtml }
data ก็จะถูก save ลงใน database ที่ชื่อ table WELCOME_LOG
เริ่มต้นง่าย ๆ เพียงเท่านี้ก่อน คราวหน้าคงจะลงไปในส่วน ajax on jsf กัน