1. Struts 0
1.6. Nhược điểm của Struts
- Nhược điểm của Struts :
• Để sử dụng MVC với chuẩn RequestDispatcher, ta cần nghiên cứu sâu với chuẩn JSP và Servlet APIs. Để sử dụng MVC với Struts, ta còn phải hiểu rõ cả framework rộng lớn và phức tạp, nó tương tự như việc tìm hiểu cả cái cốt lõi của hệ thống. Điều bất lợi này đặc biệt đáng kể với những dự án nhỏ, những dự án có ít thời gian để thực hiện, và những lập trình viên có ít kinh nghiệm; ta mất rất nhiều thời gian trong việc nghiên cứu Struts khi thực hiện đề án.
- Ít có tài liệu hỗ trợ
• So sánh với chuẩn servlet và JSP APIs, Struts có ít tài liệu hổ trợ hơn nhiều.
- Less transparent:
• Với những ứng dụng Struts, có nhiều lỗi bên dưới hơn những ứng dụng Web dựa trên ngôn ngữ Java bình thường. Vì thế, ứng dụng Struts thì:
+ Khó tìm hiểu.
+ Khó chuẩn hóa và đánh giá.
- Cứng nhắc:
• Struts khó áp dụng các phương pháp khác
2. Struts 2.0:
• Java framework để phát triển các ứng dụng web theo mô hình MVC.
• Linh hoạt cho việc chuẩn hóa dữ liệu người dùng.
• Các file cấu hình sử dụng package và namespace để quản lý tất cả các action.
• Dễ dàng tích hợp các hợp các module của nhà cung cấp thứ 3 (Hibernate, Spring, Ajax…).
• Sử dụng các Interceptor.
Phần VI
Áp dụng Struts 2.0 Framework xây dựng ứng dụng triển khai thực tế
Chương trình: Quản Lý Nhân Viên
Minh họa chức năng cập nhật tài khoản.
I. Qui trình thực hiện :
1. Các trang hiển thị (View)
Index.jsp
<%@ page language="java" pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Index page</title> <META HTTP-EQUIV="Refresh"
CONTENT="0;URL=employee/getEmployeeList.action"> </head> <body> <h1>Initializing...</h1> </body> </html>
Employee.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title> <SCRIPT type="text/javascript">
function edit()
{
alert("edit..."); document.getElementById("btnAdd").disabled = true; document.getElementById("btnSave").disabled = false;
}
</SCRIPT> </head>
<body>
<h3> Demo Struts 2.0 Framework in J2EE </h3> <s:fielderror/>
<form id="frmEmployee" name="Employee" method="post"
theme="simple">
<table border="1" width="100%"> <tr>
<td>ID</td>
<td style="width: 20%">Name</td> <td style="width: 10%">Sex</td>
<td style="width: 15%">Birthday</td> <td style="width: 15%">City</td> <td style="width: 30%">Email</td> <td style="width: 10%">Action</td> </tr>
<%-- list is property --%>
<s:iterator value="employeeList"> <tr>
<td>
<s:property value="id" /> </td>
<td>
<s:property value="name" /> </td>
<td>
<s:property value="se-x"/> </td>
<s:property value="birthday" /> </td>
<td>
<s:property value="city" /> </td>
<td>
<s:property value="email" /> </td>
<td align="center"> <s:url id="urlDelete"
action="EmployeeDelete">
<s:param name="id"
value="%{id}"/>
</s:url>
<s:a
href="%{urlDelete}">Delete</s:a>
<s:url id="urlEdit"
action="EmployeePrepareUpdate">
<s:param name="id" value="%{id}"/> </s:url>
<s:a href="%{urlEdit}"
onclick="return edit();">Edit</s:a> </td> </tr> </s:iterator> </table> </form> </body> </html>
Success.jsp
<%@ page language="java" pageEncoding="ISO-8859-1"%> <%
String path = request.getContextPath(); String basePath =
request.getScheme()+"://"+request.getServerName()+":"+req uest.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head>
<base href="<%=basePath%>">
<title>My JSP 'Success.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0">
<meta http-equiv="keywords"
content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <h1>Successful!.</h1> <br> </body> </html>
Fail.jsp
<%@ page language="java" pageEncoding="ISO-8859-1"%> <%
String path = request.getContextPath(); String basePath =
request.getScheme()+"://"+request.getServerName()+":"+req uest.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head>
<base href="<%=basePath%>">
<title>My JSP 'Fail.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0">
<meta http-equiv="keywords"
content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <h1> Invalid Employee.</h1> <br> </body> </html>
Update.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title> </head>
<body>
<form name="frmEmployee" method="post"> <table>
<tr>
<td> <s:textfield label="Name" name="name"
value="%{name}"/></td> </tr>
<tr>
<td> <s:radio label="Sex"
value="%{sex}"name="sex"
list="{'Male','Female'}"></s:radio> </td> </tr>
<tr>
<td> <s:textfield label="BirthDay"
value="%{birthday}" name="birthday"/></td> </tr>
<tr>
<td> <s:select label="City" name="city"
value="%{city}" list="{'Ho Chi Minh','Ha Noi','Da Nang'}"></s:select> </td>
</tr> <tr>
<td> <s:textfield label="Email"
name="email" value="%{email}"/></td> </tr>
<tr>
<td> <s:textarea label="History"
name="history" value="%{history}" cols="20" rows="3"
/></td>
</tr> <tr> <td>
<s:submit id="btnAdd" name="btnAdd"
value="Add" action="EmployeeAdd" theme="simple"
align="right"/>
<s:submit id="btnSave" name="btnSave"
value="Save" action="EmployeeUpdate" theme="simple"
align="right">
</s:submit>
<s:submit id="btnGetList"
name="btnGetList" value="Get Employee List"
action="getEmployeeList"/> </td> </tr> </table> </form> </body> </html>
2. Action : EmployeeAction.class package net.vietcore.demo.action; import net.vietcore.demo.bean.Employee; import net.vietcore.demo.bean.EmployeeService; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.Preparable; import com.opensymphony.xwork2.ModelDriven;
public class EmployeeAction extends ActionSupport implements ModelDriven, Preparable{
/** *
*/
private static final long serialVersionUID = 1L; private int id;
private Employee employee;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
} /*
* This method is call automatically when the Class is called. *
*/
public void prepare() throws Exception {
System.out.println("prepare() in Employee Action"); System.out.println("EmployeeID = "+id);
if (id==0){
employee = new Employee();
System.out.println("Tao moi "); }else { employee = service.findById(id); System.out.println("Tim "); } } /*
* This method is call automatically when the Class is called. *
*/
public Object getModel() {
System.out.println("getModel() in Employee Action");
return employee;
}
public String addEmployee(){
System.out.println("addEmployee() in Employee Action");
service.addEmployee(employee);
return SUCCESS;
}
public String deleteEmployee(){
System.out.println("deleteEmployee() in Employee Action"); System.out.println(employee.getId());
service.deleteEmployee(employee.getId());
return SUCCESS;
}
public String updateEmployee(){
System.out.println("updateEmployee() in Employee Action");
service.updateEmployee(employee);
}
public String execute() throws Exception{
System.out.println("execute() in Employee Action");
return SUCCESS;
}
public String input() throws Exception{
System.out.println("input() in Employee Action");
return INPUT; } } ListEmployeeAction.class package net.vietcore.demo.action; import java.util.List; import net.vietcore.demo.bean.EmployeeService; import com.opensymphony.xwork2.ActionSupport; public class ListEmployeeAction extends ActionSupport{ /**
*
*/
private static final long serialVersionUID = 1L; EmployeeService service = new EmployeeService(); private List employeeList;
public List getEmployeeList() {
System.out.println("getEmployeeList() in class ListEmployeeAction");
return employeeList;
}
public String execute() throws Exception{
System.out.println("execute() in class ListEmployeeAction");
service.addEmployeeToList();
employeeList = service.list();
return SUCCESS;
} }
3. Bean:
Employee.class
package net.vietcore.demo.bean;
public class Employee {
private int id;
private String name;
private String sex;
private String birthday;
private String city;
private String email;
private String history;
public String getBirthday() {
return birthday; }
public void setBirthday(String birthday) {
this.birthday = birthday; }
public String getCity() {
return city; }
public void setCity(String city) {
this.city = city; }
public String getEmail() {
return email; }
public void setEmail(String email) {
this.email = email; }
public String getHistory() {
return history; }
this.history = history; }
public int getId() {
return id; }
public void setId(int id) {
this.id = id; }
public String getName() {
return name; }
public void setName(String name) {
this.name = name; }
public String getSex() {
return sex; }
public void setSex(String sex) {
this.sex = sex; } } EmployeeService.class package net.vietcore.demo.bean; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import net.vietcore.demo.utils.DataUtils; public class EmployeeService {
private ArrayList<Employee> employeeList; public ArrayList<Employee> list(){
return employeeList;
}
public void addEmployeeToList(){
//System.out.println("addEmployeeToList() in Employee Action....");
int i=0;
//PreparedStatement pstmt = null;
try {
//DataUtils.connectDb();
//pstmt =
DataUtils.getConnect().prepareStatement("Select * from tblEmployee"); rs= DataUtils.Doc("Select * from tblEmployee");
//rs = pstmt.executeQuery();
employeeList = new ArrayList<Employee>(); while (rs.next()) {
i++;
Employee employee = new Employee(); employee.setId(rs.getInt("ID")); employee.setName(rs.getString("name")); employee.setSex(rs.getString("sex")); employee.setBirthday(rs.getString("birthday")); employee.setCity(rs.getString("city")); employee.setEmail(rs.getString("email")); employee.setHistory(rs.getString("history")); employeeList.add(employee); } } catch (Exception e) { //e.printStackTrace(); } System.out.println(i); }
public int addEmployee(Employee employee){
System.out.println("addEmployee method in EmployeeService class"); int ret = -1; PreparedStatement pstmt = null; try { DataUtils.connectDb(); pstmt =
DataUtils.getConnect().prepareStatement("INSERT INTO tblEmployee (Name, Sex, Birthday, City, Email, History) VALUES(?, ?, ?, ?, ?, ?)");
pstmt.setString(1, employee.getName()); pstmt.setString(2, employee.getSex()); pstmt.setString(3, employee.getBirthday()); pstmt.setString(4, employee.getCity()); pstmt.setString(5, employee.getEmail()); pstmt.setString(6, employee.getHistory());
int result = pstmt.executeUpdate(); if(result > 0)
System.out.println("Employee insert successfully"); ret = 1; } else { ret = 0; } } catch (Exception e) { e.printStackTrace(); } finally { if(pstmt != null) { try { pstmt.close(); } catch (SQLException e) { e.printStackTrace(); } } DataUtils.disconnectDb(); } return ret; }
public int updateEmployee(Employee employee){ System.out.println("updateEmployee method in EmployeeService class"); int ret = -1; PreparedStatement pstmt = null; try { DataUtils.connectDb(); pstmt =
DataUtils.getConnect().prepareStatement("UPDATE tblEmployee SET Name=?, Sex=?, Birthday=?, City=?, Email=?, History=? WHERE ID=?");
pstmt.setString(1, employee.getName()); pstmt.setString(2, employee.getSex()); pstmt.setString(3, employee.getBirthday()); pstmt.setString(4, employee.getCity()); pstmt.setString(5, employee.getEmail()); pstmt.setString(6, employee.getHistory()); pstmt.setInt(7, employee.getId()); int result = pstmt.executeUpdate(); if(result > 0)
System.out.println("Employee saved successfully"); ret = 1; } else { ret = 0; } } catch (Exception e) { e.printStackTrace(); } finally { if(pstmt != null) { try { pstmt.close(); } catch (SQLException e) { e.printStackTrace(); } } DataUtils.disconnectDb(); } return ret; }
public int deleteEmployee(int id){
System.out.println("deleteEmployee method in EmployeeService class"); int ret = -1; PreparedStatement pstmt = null; try { DataUtils.connectDb(); pstmt =
DataUtils.getConnect().prepareStatement("DELETE FROM tblEmployee WHERE id=?"); pstmt.setInt(1, id); pstmt.executeUpdate(); ret = 1; } catch (Exception e) { e.printStackTrace(); } finally {
if(pstmt != null) { try { pstmt.close(); } catch (SQLException e) { e.printStackTrace(); } } DataUtils.disconnectDb(); } return ret; }
public Employee findById(int id){
addEmployeeToList();
System.out.println("findById method in EmployeeService class");
for (Employee employee : employeeList) {
if(employee.getId()==id)
return employee;
}
return null;
}
public Employee getEmployee(int id){ Employee employee = new Employee(); ResultSet rs = null;
PreparedStatement pstmt = null;
try {
DataUtils.connectDb();
pstmt =
DataUtils.getConnect().prepareStatement("SELECT * FROM tblEmployee WHERE id=?"); pstmt.setInt(1, id); rs = pstmt.executeQuery(); while (rs.next()) { employee.setId(rs.getInt("ID")); employee.setName(rs.getString("Name")); employee.setSex(rs.getString("Sex")); employee.setBirthday(rs.getString("Birthday")); employee.setCity(rs.getString("City")); employee.setEmail(rs.getString("Email")); employee.setHistory(rs.getString("History")); }
} catch (Exception e) { e.printStackTrace(); } finally { if(pstmt != null) { try { pstmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(rs != null) { //rs.close(); } DataUtils.disconnectDb(); } return employee; } } 4. Utils : DataUtils.class package net.vietcore.demo.utils; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class DataUtils {
private static Connection con; private static int count;
public static void connectDb() {
try {
// Connect Normal
String DBDriver = "sun.jdbc.odbc.JdbcOdbcDriver"; String connString = "jdbc:odbc:dataStruts2";
Class.forName(DBDriver).newInstance();
// chuong trinh DEMO
System.out.println("Connection number: " + (++count));
} catch (ClassNotFoundException cnfe) {
try {
throw new Exception("Cannot find the specified driver.", cnfe);
} catch (Exception e) {
}
} catch (Exception e) {
System.out.println("Error, class Connect \n Method: connectDb()");
System.out.println(e);
}
}
public static Connection getConnect() {
return con;
}
public static void disconnectDb() {
try {
System.out.println("Disconnecting..." + count);
con.close();
} catch (SQLException sqle) {
System.out.println(sqle.getMessage());
}
}
public static ResultSet Doc(String chuoi_lenh) throws Exception { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection conn= DriverManager.getConnection("jdbc:odbc:dataStruts2"); Statement stmt = conn.createStatement(); ResultSet rs= stmt.executeQuery(chuoi_lenh); return rs; } } 5. 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="tokenPackage" namespace="/employee"
extends="struts-default">
<action name="getEmployeeList"
class="net.vietcore.demo.action.ListEmployeeAction"
method="execute">
<result name="success">/Employee.jsp</result>
<!-- <result name="error">/error.jsp</result> -->
</action>
<action name="EmployeeInput" method="input"
class="net.vietcore.demo.action.EmployeeAction"> <result
name="input">/Employee.jsp</result>
</action>
<action name="EmployeeAdd" method="addEmployee"
class="net.vietcore.demo.action.EmployeeAction">
<result type="redirect- action">getEmployeeList</result>
<result name="error">error.jps</result>
</action>
<action name="EmployeeDelete"
method="deleteEmployee"
class="net.vietcore.demo.action.EmployeeAction">
<result
type="redirect">getEmployeeList.action</result>
</action>
<action name="EmployeePrepareUpdate"
class="net.vietcore.demo.action.EmployeeAction">
<result>/Update.jsp</result>
<interceptor-ref
name="paramsPrepareParamsStack"/>
</action>
<action name="EmployeeUpdate"
method="updateEmployee"
class="net.vietcore.demo.action.EmployeeAction">
<result type="redirect- action">getEmployeeList</result>
</action>
</package> </struts>
6. Build.xml:
<project name="Struts2" default="dist" basedir="."> <property name="app.version" value="0.1-dev"/>
<property name="build.home" value="${basedir}/build"/> <property name="dist.home" value="${basedir}/dist"/> <property name="src.home" value="${basedir}/src"/> <property name="web.home" value="${basedir}/web"/> <property name="lib.home" value="${basedir}/web/WEB- INF/lib"/>
<property name="compile.debug" value="true"/> <property name="compile.deprecation" value="false"/> <property name="compile.optimize" value="true"/> <property name="tomcat.home" value="C:\Program Files\Apache Software Foundation\Tomcat 5.5"/> <path id="compile.classpath">
<fileset dir="${lib.home}" includes="**/*.jar"/> </path>
<target name="prepare" description="Prepare some necessary steps">
<mkdir dir="${build.home}"/>
<mkdir dir="${dist.home}"/> </target>
<target name="clean" description="Delete old build and dist directories">
<delete dir="${build.home}"/>
<delete dir="${dist.home}"/> </target>
<target name="compile" depends="prepare"
description="Compile Java sources">
<javac srcdir="${src.home}"
destdir="${build.home}"
debug="${compile.debug}"
deprecation="${compile.deprecation}"
optimize="${compile.optimize}">
<classpath refid="compile.classpath"/>
</javac>
<!-- <copy todir="${build.home}">
<fileset dir="${src.home}" excludes="**/*.java"/> </copy>-->
<target name="dist" depends="compile" description="Create binary distribution">
<war destfile="${dist.home}/${ant.project.name}.war"
webxml="${web.home}/WEB-INF/web.xml"> <webinf dir="${web.home}/WEB-INF"/>
<!--<lib dir="${lib.home}"/>-->
<!--<classes dir="${build.home}"/>-->
<fileset dir="${web.home}" includes="*.*"/>
<!-- <zipfileset dir="${web.home}/css" prefix="css"/> -- >
<!--<zipfileset dir="${web.home}/images" prefix="images"/> -->
<!--<fileset dir="${web.home}" includes="*.jsp"/>--> </war>
</target>
<target name="deploy-tomcat">
<copy todir="${tomcat.home}/webapps"> <fileset dir="${dist.home}">
<include name="${ant.project.name}.war"/> </fileset> </copy> </target> </project> II . Triển Khai Ứng Dụng: 1. Cơ sở dữ liệu: