struts2官方入门案列curd

      偶然在查看文档时,看到这个demo,后来认真看了下真是麻雀虽小,很单一的struts2的增删改查,但是却从各方面诠释着struts2这一开源框架的精妙设计和丰富的可定制性。文档上提供是片段式的代码讲解,且是英文的,所以这里记录一下,方面以后查看。

      和以前一样,先上效果图:

 

    图一:

 

 

 

     图二:

 

 

 

     图三:

 

 

 

    图四:

 

 

            虽然从图上看的话,以上功能简单,但是代码里,时刻体现着该框架的设计之优秀,首先,我们新建一个web功能CusManager,并加入struts2的7个必要jar包。

           

             第一步,新建两个实体类Department和Employee作POJO,代码如下:

package com.aurifa.struts2.tutorial.model;

import java.io.Serializable;

public class Department implements Serializable {
	Integer departmentId;

	String name;

	public Department() {
	}

	public Department(Integer departmentId, String name) {
		this.departmentId = departmentId;
		this.name = name;
	}

	public Integer getDepartmentId() {
		return departmentId;
	}

	public void setDepartmentId(Integer departmentId) {
		this.departmentId = departmentId;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

 

package com.aurifa.struts2.tutorial.model;

import java.io.Serializable;

public class Employee implements Serializable {
	private Integer employeeId;

	private Integer age;

	private String firstName;

	private String lastName;

	private Department department;

	public Employee() {
	}

	public Employee(Integer employeeId, String firstName, String lastName,
			Integer age, Department department) {
		this.employeeId = employeeId;
		this.firstName = firstName;
		this.lastName = lastName;
		this.age = age;
		this.department = department;
	}

	public Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}

	public Integer getEmployeeId() {
		return employeeId;
	}

	public void setEmployeeId(Integer employeeId) {
		this.employeeId = employeeId;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
}

 

           第二步,定义dao层的接口,代码如下:

package com.aurifa.struts2.tutorial.dao;

import java.util.List;
import java.util.Map;

public interface DepartmentDao {
    public List getAllDepartments();
    public Map getDepartmentsMap();
}

 

package com.aurifa.struts2.tutorial.dao;

import java.util.List;

import com.aurifa.struts2.tutorial.model.Employee;

public interface EmployeeDao {
    public List getAllEmployees();
    public Employee getEmployee(Integer id);
    public void update(Employee emp);
    public void insert(Employee emp);
    public void delete(Integer id);
}

 

          第三步,完成上述接口的实现类,代码如下:

package com.aurifa.struts2.tutorial.dao;

import java.util.*;

import com.aurifa.struts2.tutorial.model.Department;

public class DepartmentNoDBdao implements DepartmentDao {
    private static List departments;
    private static Map departmentsMap;
    static {
        departments = new ArrayList();
        departments.add(new Department( new Integer(100), "Accounting" ));
        departments.add(new Department( new Integer(200), "R & D"));
        departments.add(new Department( new Integer(300), "Sales" ));
        departmentsMap = new HashMap();
        Iterator iter = departments.iterator();
        while( iter.hasNext() ) {
            Department dept = (Department)iter.next();
            departmentsMap.put(dept.getDepartmentId(), dept );
        }

     }
    public List getAllDepartments() {
        return departments;
    }
    public Map getDepartmentsMap() {
        return departmentsMap;
    }
}

 

package com.aurifa.struts2.tutorial.dao;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.aurifa.struts2.tutorial.model.Department;
import com.aurifa.struts2.tutorial.model.Employee;

public class EmployeeNoDBdao implements EmployeeDao {
    private static Map departmentsMap;
    private static ArrayList employees;

    static {
        employees = new ArrayList();
        employees.add(new Employee(new Integer(1), "John", "Doe", new Integer(36), new Department(new Integer(100), "Accounting")));
        employees.add(new Employee(new Integer(2), "Bob", "Smith", new Integer(25), new Department(new Integer(300), "Sales")));
        DepartmentDao deptDao = new DepartmentNoDBdao();
        departmentsMap = deptDao.getDepartmentsMap();
    }

    Log logger = LogFactory.getLog(this.getClass());

    public List getAllEmployees() {
        return employees;
    }

    public Employee getEmployee(Integer id) {
        Employee emp = null;
        Iterator iter = employees.iterator();
        while (iter.hasNext()) {
            emp = (Employee)iter.next();
            if (emp.getEmployeeId().equals(id)) {
                break;
            }
        }
        return emp;
    }

    public void update(Employee emp) {
        Integer id = emp.getEmployeeId();
        for (int i = 0; i < employees.size(); i++) {
            Employee tempEmp = (Employee)employees.get(i);
            if (tempEmp.getEmployeeId().equals(id)) {
                emp.setDepartment((Department)departmentsMap.get(emp.getDepartment().getDepartmentId()));
                employees.set(i, emp);
                break;
            }
        }
    }

    public void insert(Employee emp) {
        int lastId = 0;
        Iterator iter = employees.iterator();
        while (iter.hasNext()) {
            Employee temp = (Employee)iter.next();
            if (temp.getEmployeeId().intValue() > lastId) {
                lastId = temp.getEmployeeId().intValue();
            }
        }
        emp.setDepartment((Department)departmentsMap.get(emp.getDepartment().getDepartmentId()));
        emp.setEmployeeId(new Integer(lastId + 1));
        employees.add(emp);
    }

    public void delete(Integer id) {
        for (int i = 0; i < employees.size(); i++) {
            Employee tempEmp = (Employee)employees.get(i);
            if (tempEmp.getEmployeeId().equals(id)) {
                employees.remove(i);
                break;
            }
        }
    }
}

 
          第四步,根据dao层,完成service层(因为代码较为简单,未明确分包),代码如下:

package com.aurifa.struts2.tutorial.service;

import java.util.List;

import com.aurifa.struts2.tutorial.dao.DepartmentDao;
import com.aurifa.struts2.tutorial.dao.DepartmentNoDBdao;

public class DepartmentDaoService implements DepartmentService {
    private DepartmentDao dao;

    public DepartmentDaoService() {
        this.dao = new DepartmentNoDBdao();
    }

    public List getAllDepartments() {
        return dao.getAllDepartments();
    }
}

 

package com.aurifa.struts2.tutorial.service;

import java.util.List;

import com.aurifa.struts2.tutorial.dao.EmployeeDao;
import com.aurifa.struts2.tutorial.dao.EmployeeNoDBdao;
import com.aurifa.struts2.tutorial.model.Employee;

public class EmployeeDaoService implements EmployeeService {
    private EmployeeDao dao;

    public EmployeeDaoService() {
        this.dao = new EmployeeNoDBdao();
    }

    public List getAllEmployees() {
        return dao.getAllEmployees();
    }

    public void updateEmployee(Employee emp) {
        dao.update(emp);
    }

    public void deleteEmployee(Integer id) {
        dao.delete(id);
    }

    public Employee getEmployee(Integer id) {
        return dao.getEmployee(id);
    }

    public void insertEmployee(Employee emp) {
        dao.insert(emp);
    }
}

 

           第五步,service层的接口,代码如下:

package com.aurifa.struts2.tutorial.service;

import java.util.List;

public interface DepartmentService {
    public List getAllDepartments();
}

 

package com.aurifa.struts2.tutorial.service;

import java.util.List;

import com.aurifa.struts2.tutorial.model.Employee;

public interface EmployeeService {
    public List getAllEmployees();
    public void updateEmployee(Employee emp);
    public void deleteEmployee(Integer id);
    public Employee getEmployee(Integer id);
    public void insertEmployee(Employee emp);
}

 

      第六步,则是action层,代码如下:

package com.aurifa.struts2.tutorial.action;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.aurifa.struts2.tutorial.model.Employee;
import com.aurifa.struts2.tutorial.service.DepartmentDaoService;
import com.aurifa.struts2.tutorial.service.DepartmentService;
import com.aurifa.struts2.tutorial.service.EmployeeDaoService;
import com.aurifa.struts2.tutorial.service.EmployeeService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;

public class EmployeeAction extends ActionSupport implements Preparable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -6886717038958304064L;

	private Log logger = LogFactory.getLog(this.getClass());

	private static EmployeeService empService = new EmployeeDaoService();

	private static DepartmentService deptService = new DepartmentDaoService();

	private Employee employee;

	private List employees;

	private List departments;

	public void prepare() throws Exception {
		departments = deptService.getAllDepartments();
		if (employee != null && employee.getEmployeeId() != null) {
			employee = empService.getEmployee(employee.getEmployeeId());
		}
	}

	public String doSave() {
		if (employee.getEmployeeId() == null) {
			empService.insertEmployee(employee);
		} else {
			empService.updateEmployee(employee);
		}
		return SUCCESS;
	}

	public String doDelete() {
		empService.deleteEmployee(employee.getEmployeeId());
		return SUCCESS;
	}

	public String doList() {
		employees = empService.getAllEmployees();
		return SUCCESS;
	}

	public String doInput() {
		return INPUT;
	}

	/**
	 * @return Returns the employee.
	 */
	public Employee getEmployee() {
		return employee;
	}

	/**
	 * @param employee
	 *            The employee to set.
	 */
	public void setEmployee(Employee employee) {
		this.employee = employee;
	}

	/**
	 * @return Returns the employees.
	 */
	public List getEmployees() {
		return employees;
	}

	/**
	 * @return Returns the departments.
	 */
	public List getDepartments() {
		return departments;
	}
}

 

           接着在同级目录下,我们添加该action的同名验证框架,代码如下:

<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
       "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
  <field name="employee.firstName">
     <field-validator type="requiredstring">
          <message key="errors.required.firstname"/>
      </field-validator>
  </field>
  <field name="employee.lastName">
     <field-validator type="requiredstring">
          <message key="errors.required.lastname"/>
      </field-validator>
  </field>
  <field name="employee.age">
     <field-validator type="required" short-circuit="true">
          <message key="errors.required.age"/>
      </field-validator>
      <field-validator type="int">
      		<param name="min">18</param>
      		<param name="max">65</param>
          	<message key="errors.required.age.limit"/>
      </field-validator>
  </field>
</validators>

 

           至此,代码部分大抵完成,下面在src下,新建所需的配置文件:

首先是log4j,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
	<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
		<layout class="org.apache.log4j.TTCCLayout"/>
	</appender>
	
	<!-- log detail configuration -->
	<logger name="com.opensymphony.xwork">
		<level value="error"/>
		<appender-ref ref="stdout"/>
	</logger>
	<logger name="com.opensymphony.webwork">
		<level value="error"/>
		<appender-ref ref="stdout"/>
	</logger>
	<logger name="freemarker">
		<level value="warn"/>
		<appender-ref ref="stdout"/>
	</logger>
	<logger name="com.mevipro">
		<level value="debug"/>
		<appender-ref ref="stdout"/>
	</logger>
	<root>
		<level value="error"/>
		<appender-ref ref="stdout"/>
	</root>
</log4j:configuration>

 

             其次是struts.xml,代码如下:

<!DOCTYPE struts PUBLIC 
	"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
	"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
	<!-- Include webwork default (from the Struts JAR). -->
	<include file="struts-default.xml"/>

	<!-- Configuration for the default package. -->
	<package name="default" extends="struts-default">
		
		<!-- Default interceptor stack. -->
		<default-interceptor-ref name="paramsPrepareParamsStack"/>
		<action name="index" class="com.aurifa.struts2.tutorial.action.EmployeeAction" method="list">
			<result name="success">/jsp/employees.jsp</result>
			<!-- we don't need the full stack here -->
			<interceptor-ref name="basicStack"/>
		</action>
		<action name="crud" class="com.aurifa.struts2.tutorial.action.EmployeeAction" method="input">
			<result name="success" type="redirect-action">index</result>
			<result name="input">/jsp/employeeForm.jsp</result>
			<result name="error">/jsp/error.jsp</result>
		</action>
	</package>
</struts>

 

            然后是struts的国际化文件,struts.properties和guest.properties,代码分别如下:

struts.custom.i18n.resources=guest

 

#labels
application.title=Employee Maintenance Application
label.employees=Employees
label.delete=Delete
label.edit=Edit
label.employee.edit=Edit Employee
label.employee.add=Add Employee
label.firstName=First Name
label.lastName=Last Name
label.department=Department
label.age=Age

#button labels
button.label.submit=Submit
button.label.cancel=Cancel

##-- errors
errors.prefix=<span style="color:red;font-weight:bold;">
errors.suffix=</span>
errors.general=An Error Has Occcured
errors.required.firstname=Name is required.
errors.required.lastname=Last name is required.
errors.required.age=Please provide an age.
errors.required.age.limit=Please provide an age between ${min} and ${max}.
errors.required.department=Department is required.

 

 最后贴上运行时的jsp页面,代码不多,下面我分别贴出来,代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.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="Refresh" content="0;URL=index.action">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>
    This is my JSP page. <br>
  </body>
</html>

 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:if test="employee==null || employee.employeeId == null">
	<s:set name="title" value="%{'Add new employee'}"/>
</s:if>
<s:else>
	<s:set name="title" value="%{'Update employee'}"/>
</s:else>

<html>
<head>
    <link href="css/main.css" rel="stylesheet" type="text/css"/>
    <style>td { white-space:nowrap; }</style>
    <title><s:property value="#title"/></title>
</head>
<body>
<div class="titleDiv"><s:text name="application.title"/></div>
<h1><s:property value="#title"/></h1>
<%--<s:actionerror />--%>
<%--<s:actionmessage />--%>
<s:form action="crud!save.action" method="post">
    <s:textfield name="employee.firstName" value="%{employee.firstName}" label="%{getText('label.firstName')}" size="40"/>
    <s:textfield name="employee.lastName" value="%{employee.lastName}" label="%{getText('label.lastName')}" size="40"/>
    <s:textfield name="employee.age" value="%{employee.age}" label="%{getText('label.age')}" size="20"/>
    <s:select name="employee.department.departmentId" value="%{employee.department.departmentId}" list="departments" listKey="departmentId" listValue="name"/>
<%--    <s:select name="gender" list="%{#{'male':'Male', 'female':'Female'}}" />--%>
    <s:hidden name="employee.employeeId" value="%{employee.employeeId}"/>
    <s:submit value="%{getText('button.label.submit')}"/>
    <s:submit value="%{getText('button.label.cancel')}" name="redirect-action:index"/>
</s:form>
</body>
</html>

 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <link href="css/main.css" rel="stylesheet" type="text/css"/>
    <title><s:text name="label.employees"/></title>
</head>
<body>
<div class="titleDiv"><s:text name="application.title"/></div>
<h1><s:text name="label.employees"/></h1>
<s:url id="url" action="crud!input" />
<a href="<s:property value="#url"/>">Add New Employee</a>
<br/><br/>
<table class="borderAll">
    <tr>
        <th><s:text name="label.firstName"/></th>
        <th><s:text name="label.lastName"/></th>
        <th><s:text name="label.age"/></th>
        <th><s:text name="label.department"/></th>
        <th>&nbsp;</th>
    </tr>
    <s:iterator value="employees" status="status">
        <tr class="<s:if test="#status.even">even</s:if><s:else>odd</s:else>">
            <td class="nowrap"><s:property value="firstName"/></td>
            <td class="nowrap"><s:property value="lastName"/></td>
            <td class="nowrap"><s:property value="age"/></td>
            <td class="nowrap"><s:property value="department.name"/></td>
            <td class="nowrap">
                <s:url action="crud!input" id="url">
                    <s:param name="employee.employeeId" value="employeeId"/>
                </s:url>
                <a href="<s:property value="#url"/>">Edit</a>
                &nbsp;&nbsp;&nbsp;
                <s:url action="crud!delete" id="url">
                    <s:param name="employee.employeeId" value="employeeId"/>
                </s:url>
                <a href="<s:property value="#url"/>">Delete</a>
            </td>
        </tr>
    </s:iterator>
    </table>
</body>
</html>

 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <title>Error Page</title>
    <link href="<s:url value='/css/main.css'/>" rel="stylesheet" type="text/css"/>
</head>
<body>
<s:actionerror/>
<br/>
In order that the development team can address this error, please report what you were doing that caused this error.
<br/><br/>
The following information can help the development
team find where the error happened and what can be done to prevent it from
happening in the future.

</body>
</html>

 

以上页面引用到的css文件,代码如下:

html, body  {
    margin-left: 10px;
    margin-right: 10px;
    margin-bottom: 5px;
    color: black;
    background-color: white;
    font-family: Verdana, Arial, sans-serif;
    font-size:12px;
}
.titleDiv {
    background-color: #EFFBEF;
    font-weight:bold;
    font-size:18px;
    text-align:left;
    padding-left:10px;
    padding-top:10px;
    padding-bottom:10px;
    border:2px solid #8F99EF;
}
h1 { font-weight:bold; color: brown; font-size:15px; text-align:left;}

td { font-size:12px; padding-right:10px; }
th { text-align:left; font-weight:bold; font-size:13px; padding-right:10px; }
.tdLabel { font-weight: bold; white-space:nowrap; vertical-align:top;}

A { color:#4A825A; text-decoration:none;}
A:link { text-decoration:none;}
A:visited { text-decoration:none;}
A:hover { text-decoration:none; color: red;}

.borderAll {
    border: 2px solid #8F99EF;
}

.butStnd {
    font-family:arial,sans-serif;
    font-size:11px;
    width:105px;
    background-color:#DCDFFA ;color:#4A825A;font-weight:bold;
}

.error {
    color: red;
    font-weight: bold;
}
.errorSection {
    padding-left:18px;
    padding-top:2px;
    padding-bottom:10px;
    padding-right:5px;
}

.even { background-color: #EFFBEF; }
.odd { background-color: white; }

.nowrap { white-space:nowrap; }

              

           到这里,这个例子基本上就完成了,其主要亮点在action层的实现类和验证xml,而jsp页面的tag和struts.xml也比较耐看,将web.xml配置好struts2的监听以后,部署到tomcat之后,浏览器键入:localhost:8080/CusManager,即可得到以上效果图所示。

 

            代码我是全部都贴上了,连css也有,不会有任何地方的缺失,假使大家运行报错,请认真查看错误,并检查自己的web.xml的配置,除此之外不会有任何错误。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值