CustomerDao位于dao包
package cn.itcast.dao;
import java.util.List;
import cn.itcast.domain.Customer;
import cn.itcast.domain.QueryResult;
public interface CustomerDao {
//方法1:添加一个Customer到数据库,返回值为void
void add(Customer c);
//方法2:更新一个Customer到数据库,返回值为void
void update(Customer c);
//方法3:删除一个Customer从数据库,返回值为void
void delete(Customer c);
//方法4:通过id查询并返回一个封装好数据的Customer
Customer find(String id);
//方法5:返回一个封装了所有Customer的集合
List<Customer> getAll();
//方法6:两条SQL,先从数据库第N条开始查询M条记录,参数(N,M),
//再统计总的记录数,封装到QueryResult对象并返回!
public QueryResult pageQuery(int startIndex,int pageSize);
}
CustomerDaoImpl位于dao.impl包
package cn.itcast.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import cn.itcast.dao.CustomerDao;
import cn.itcast.domain.Customer;
import cn.itcast.domain.QueryResult;
import cn.itcast.exception.DaoException;
import cn.itcast.utils.JdbcUtils;
public class CustomerDaoImpl implements CustomerDao {
//方法1:添加一个Customer到数据库,返回值为void
public void add(Customer c){
Connection conn=null;
PreparedStatement st=null;
ResultSet rs=null;
try {
conn=JdbcUtils.getConnection();
//先准备String sql,再通过连接准备PreparedStatement
String fields="id,name,gender,birthday,cellphone,email,preference,type,description";
String sql="insert into customer("+fields+") values(?,?,?,?,?,?,?,?,?)";
st=conn.prepareStatement(sql);
st.setString(1, c.getId());
st.setString(2, c.getName());
st.setString(3, c.getGender());
//特别注意,setDate需要一个子类sql.Date
st.setDate(4, new java.sql.Date(c.getBirthday().getTime()));
st.setString(5, c.getCellphone());
st.setString(6, c.getEmail());
st.setString(7, c.getPreference());
st.setString(8, c.getType());
st.setString(9, c.getDescription());
st.executeUpdate();
}catch (Exception e) {
//自定义Dao异常,是为了方便定义错误出在哪一层!
throw new DaoException();
}finally{
JdbcUtils.release(conn, st, rs);
}
}
//方法2:更新一个Customer到数据库,返回值为void
public void update(Customer c){
Connection conn=null;
PreparedStatement st=null;
ResultSet rs=null;
try {
conn=JdbcUtils.getConnection();
//先准备String sql,再通过连接准备PreparedStatement
String fields="name=?,gender=?,birthday=?,cellphone=?,email=?,preference=?,type=?,description=?";
String sql="update customer set "+fields+" where id=?";
st=conn.prepareStatement(sql);
st.setString(1, c.getName());
st.setString(2, c.getGender());
//特别注意,setDate需要一个子类sql.Date
st.setDate(3, new java.sql.Date(c.getBirthday().getTime()));
st.setString(4, c.getCellphone());
st.setString(5, c.getEmail());
st.setString(6, c.getPreference());
st.setString(7, c.getType());
st.setString(8, c.getDescription());
st.setString(9, c.getId());
st.executeUpdate();
}catch (Exception e) {
throw new DaoException();
}finally{
JdbcUtils.release(conn, st, rs);
}
}
//方法3:删除一个Customer从数据库,返回值为void
public void delete(Customer c){
Connection conn=null;
PreparedStatement st=null;
ResultSet rs=null;
try {
conn=JdbcUtils.getConnection();
//先准备String sql,再通过连接准备PreparedStatement
String sql="delete from customer where id=?";
st=conn.prepareStatement(sql);
st.setString(1, c.getId());
st.executeUpdate();
}catch (Exception e) {
throw new DaoException();
}finally{
JdbcUtils.release(conn, st, rs);
}
}
//方法4:通过id查询并返回一个封装好数据的Customer
public Customer find(String id){
Connection conn=null;
PreparedStatement st=null;
ResultSet rs=null;
try {
conn=JdbcUtils.getConnection();
//先准备String sql,再通过连接准备PreparedStatement
String sql="select * from customer where id=?";
st=conn.prepareStatement(sql);
st.setString(1, id);
rs=st.executeQuery();
if (rs.next()) {
Customer c=new Customer();
c.setId(rs.getString("id"));
c.setName(rs.getString("name"));
c.setGender(rs.getString("gender"));
//形参是个父类util.Date,传参是个子类sql.Date,多态!
c.setBirthday(rs.getDate("birthday"));
c.setCellphone(rs.getString("cellphone"));
c.setEmail(rs.getString("email"));
c.setPreference(rs.getString("preference"));
c.setType(rs.getString("type"));
c.setDescription(rs.getString("description"));
return c;
}
return null;
}catch (Exception e) {
throw new DaoException();
}finally{
JdbcUtils.release(conn, st, rs);
}
}
//方法5:返回一个封装了所有Customer的集合
public List<Customer> getAll(){
Connection conn=null;
PreparedStatement st=null;
ResultSet rs=null;
try {
conn=JdbcUtils.getConnection();
//先准备String sql,再通过连接准备PreparedStatement
String sql="select * from customer";
st=conn.prepareStatement(sql);
rs=st.executeQuery();
List<Customer> list=new ArrayList<Customer>();
while (rs.next()) {
Customer c=new Customer();
c.setId(rs.getString("id"));
c.setName(rs.getString("name"));
c.setGender(rs.getString("gender"));
//形参是个父类util.Date,传参是个子类sql.Date,多态!
c.setBirthday(rs.getDate("birthday"));
c.setCellphone(rs.getString("cellphone"));
c.setEmail(rs.getString("email"));
c.setPreference(rs.getString("preference"));
c.setType(rs.getString("type"));
c.setDescription(rs.getString("description"));
list.add(c);
}
return list;
}catch (Exception e) {
throw new DaoException();
}finally{
JdbcUtils.release(conn, st, rs);
}
}
//方法6:两条SQL,先从数据库第N条开始查询M条记录,参数(N,M),先装list
//再统计总的记录数,两个SQL语句的结果都封装到QueryResult对象并返回!
public QueryResult pageQuery(int startIndex,int pageSize){
//SQL查询模板代码(sql_s)
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
QueryResult qr = null;
try {
conn = JdbcUtils.getConnection();
//第1个?索引从条记录开始,第2个?代表取多少条记录
String sql = "select * from customer limit ?,?";
st = conn.prepareStatement(sql);
st.setInt(1, startIndex);
st.setInt(2, pageSize);
rs = st.executeQuery();
//将第1句SQL查询结果封装到list,再将集合添加到QueryResult(结果对象)
List<Customer> list=new ArrayList<Customer>();
while (rs.next()) {
Customer c=new Customer();
c.setId(rs.getString("id"));
c.setName(rs.getString("name"));
c.setGender(rs.getString("gender"));
//形参是个父类util.Date,传参是个子类sql.Date,多态!
c.setBirthday(rs.getDate("birthday"));
c.setCellphone(rs.getString("cellphone"));
c.setEmail(rs.getString("email"));
c.setPreference(rs.getString("preference"));
c.setType(rs.getString("type"));
c.setDescription(rs.getString("description"));
list.add(c);
}
//再将list添加到QueryResult(结果对象)
qr=new QueryResult();
qr.setList(list);
//执行第2条sql,将总记录数,封装到QueryResult
sql="select count(*) from customer";
st=conn.prepareStatement(sql);
rs=st.executeQuery();
//因只有一列,所以用if
if (rs.next()) {
//总记录数 封装到QueryResult(结果对象)
qr.setTotalRecord(rs.getInt(1));//注意是int类型
//也可以使用列名rs.getInt("count(*)");
//qr.setTotalRecord(rs.getInt("count(*)"));
}
//返回封装好所有数据(list,总记录数目)的QueryResult(结果对象)
return qr;
} catch (Exception e) {
throw new DaoException(e);
} finally {
JdbcUtils.release(conn, st, rs);
}
}
}
/*JDBCIMPL模板代码!
Connection conn=null;
PreparedStatement st=null;
ResultSet rs=null;
try {
conn=JdbcUtils.getConnection();
//先准备String sql,再通过连接准备PreparedStatement
String sql="?";
st=conn.prepareStatement(sql);
st.setString(1, "");
int num=st.executeUpdate();
rs=st.executeQuery();
}catch (Exception e) {
throw new DaoException();
}finally{
JdbcUtils.release(conn, st, rs);
}
*/
Customer位于domain包
package cn.itcast.domain;
import java.util.Date;
public class Customer {
//成员要与表中字段一致,并生成Getter Setter方法
private String id;
private String name;
private String gender;
private Date birthday;
private String cellphone;
private String email;
private String preference;
private String type;
private String description;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getCellphone() {
return cellphone;
}
public void setCellphone(String cellphone) {
this.cellphone = cellphone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPreference() {
return preference;
}
public void setPreference(String preference) {
this.preference = preference;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
PageBean位于domain包
package cn.itcast.domain;
import java.util.List;
/*PageBean是重点,也是难点!
PageBean封装页面需要显示的所有信息,
包括查询条件(QueryInfo的两个成员)和查询的结果(QueryResult的两个成员),
以及根据算法生成的4个成员*/
public class PageBean {
private List list;//QueryResult的成员,封装select limit 得到的记录
private int totalRecord;//QueryResult的成员,封装select count(*) 得到的库里客户总数!
private int pageSize;//QueryInfo的成员,封装每页显示条数
private int currentPage;//QueryInfo的成员,封装当前页码数
//下面4个成员无setter,因是算法生成
private int totalPage;//算法生成(totalRecord,pageSize)!
private int previousPage;//算法生成(分析currentPage<2)!
private int nextPage;//算法生成(分析currentPage+1>=totalPage)!
private int[] pageBar;//难点!算法生成,固定显示10个页码(需分析totalPage,currentPage)
//实现算法,并生成相应的getter方法!
public int getTotalPage() {
//两种算法,首先是简单的,逻辑清晰!
//共100条 每页显示5 需20页
//共101条 每页显示5 需21页
//共99条 每页显示5 还是需20页
int mod=totalRecord%pageSize;//余数
if (mod==0) {
//如果余数为0,即整除,则总页数刚好是A/B
totalPage=totalRecord/pageSize;
} else {
//否则,总页数是A/B+1;
totalPage=totalRecord/pageSize+1;
}
/*第2种算法:
totalPage = (totalRecord+(pageSize-1))/pageSize;
*/
return totalPage;
}
public int getPreviousPage() {
//返回当前页码的上一页,注意特殊情况即可!
//算法生成(分析currentPage<2)!
if (currentPage<2) {
previousPage=1;
} else {
previousPage=currentPage-1;
}
return previousPage;
}
public int getNextPage() {
//返回当前页码的下一页,注意特殊情况即可!
//算法生成(分析currentPage+1>=totalPage)!
if (currentPage+1>=totalPage) {
nextPage=totalPage;
} else {
nextPage=currentPage+1;
}
return nextPage;
}
public int[] getPageBar() {
/*算法生成,固定显示10页(需根据totalpage,currentpage分析)
特殊情况下:即总的页码数不足10条,那么起始就为1,结束页为总页数
默认情况下:起始页为当前页减4(比如15-4=11)
结束页为当前页加5(比如15+5=20)
显示的页码条就是11,12,...19,20
默认情况又有两种特殊情况:
1,当前页减4之后的起始页,如果<1,那么起始页为1,结束页为10
2,当前页加5之后的结束页,如果>总页数,
那么结束页为总页数,起始页为总页数减9*/
int start;
int end;
int pb[] = null;
if(totalPage<=10){
pb = new int[totalPage];
start = 1;
end = totalPage;
}else{
pb = new int[10];
start = currentPage - 4;
end = currentPage + 5;
//总页数=30 当前第3页 3-4=-1 1 10
//总页数=30 当前第29页 29+5=34 21 30
if(start<1){
start = 1;
end = 10;
}
if(end>totalPage){
start = totalPage - 9;
end = totalPage;
}
}
//接着再将起始页和结束页一一填充到pageBar数组里,用于页面显示
int index = 0;
for(int i=start;i<=end;i++){
pb[index++] = i;
}
this.pageBar = pb;
return pageBar;
/*简单方案:将总页数全显示成pagebar[]
int pb[] = new int[totalPage];
for(int i=1;i<=totalPage;i++){
//第1个数组元素,下标为0,值为1;
pb[i-1] = i;
}
this.pageBar = pb;
return pageBar;
*/
}
//生成相应的getter和setter
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public int getTotalRecord() {
return totalRecord;
}
public void setTotalRecord(int totalRecord) {
this.totalRecord = totalRecord;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
}
QueryInfo位于domain包
package cn.itcast.domain;
//QueryInfo对象封装的是jsp发给servlet的2个请求参数!
public class QueryInfo {
//注意用户第一次是没有带查询参数过来!要设置默认值!
private int currentPage=1; //当前页
private int pageSize=5;//页面大小,即每页显示记录数目
private int startIndex;//select * from 表名 limit X,Y; 的第1个参数,
//即查数据库时的起始位置,算法生成(当前页,页面大小)
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getStartIndex() {
//查数据库时的起始位置,算法生成,无setter!
//select * from 表名 limit 起始位置,记录数;
startIndex=(currentPage-1)*pageSize;
//比如第1页,从0开始,显示五条
//第2页,从5开始,显示五条
return startIndex;
}
}
QueryResult位于domain包
package cn.itcast.domain;
import java.util.List;
//QueryResult对象封装的是两条SQL语句的查询结果!
public class QueryResult {
private List list;//保存select * from 表名 limit 起始位置,记录数;
private int totalRecord;//保存客户总数select count(*) from 表名;
//分别生成getter setter方法!
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public int getTotalRecord() {
return totalRecord;
}
public void setTotalRecord(int totalRecord) {
this.totalRecord = totalRecord;
}
}
DaoException位于exception包
package cn.itcast.exception;
public class DaoException extends RuntimeException {
//1,自定义异常是为了方便查找错误发生在哪一层
//2,继承运行时异常,是避免给上层带麻烦
public DaoException() {
}
public DaoException(String message) {
super(message);
}
public DaoException(Throwable cause) {
super(cause);
}
public DaoException(String message, Throwable cause) {
super(message, cause);
}
public DaoException(String message, Throwable cause,
boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
DaoFactory位于factory包
package cn.itcast.factory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class DaoFactory {
/*
* 1,工厂设计成单例
* 2,读取src类目录下的dao.properties配置文件
* 3,参数为键,通过值返回接口的实现类!*/
private static Properties pro=new Properties();
//单例第1步,构造函数私有化,仅运行一次
private DaoFactory(){
//dao.properties配置文件仅加载1次就欧了
String pro_name="dao.properties";
InputStream in=DaoFactory.class.getClassLoader().getResourceAsStream(pro_name);
try {
pro.load(in);
} catch (IOException e) {
//转型后抛出
throw new RuntimeException(e);
}
}
//单例第2步,自己创个实例
private static DaoFactory instance=new DaoFactory();
//单例第3步,对外提供公开方法
public static DaoFactory getInstance(){
return instance;
}
//重点!泛型!根据参数(接口名),创建出该接口的实现类的实例对象!
public <T> T createDao(Class<T> clazz){
//配置文件中CustomerDao=cn.itcast.dao.impl.CustomerDaoImpl
//String full_name=clazz.getName();//cn.itcast.dao.CustomerDao
String simple_name=clazz.getSimpleName();//CustomerDao
//simple_name即为dao.properties配置文件键名,值impl_name就是实现类的完整名字
String impl_name=pro.getProperty(simple_name);
try {
T dao=(T) Class.forName(impl_name).newInstance();
//相当于new cn.itcast.dao.impl.CustomerDaoImpl()
return dao;
} catch (Exception e) {
// 转型后抛出
throw new RuntimeException(e);
}
}
}
FormBean位于formbean包
package cn.itcast.formbean;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
public class FormBean {
/*用一个FormBean类封装表单提交过来的数据
* 表单提交过来全是String */
private String name;
private String gender;
private String birthday;
private String cellphone;
private String email;
private String preference;
private String type;
private String description;
// Map errors 保存所有校验不通过的错误消息
private Map errors = new HashMap();
public boolean validate(){
//默认是真,只要有一个错误,flag为假
boolean flag = true;
//1,名字不能为空,只能是2-10位字母 或汉字区间(\u4e00-\u9fa5)
if(name==null || name.trim().equals("")){
flag = false;
errors.put("name", "名字不能为空!");
}else if(!name.matches("^([\u4e00-\u9fa5]{2,10})$") && !name.matches("[A-Za-z]{2,10}")){
//既不是中文也不是英文,则为假
flag = false;
errors.put("name", "名字必须是2-10位中文或英文!");
}
/*2,生日可以为空,不为空时,必须要是一个日期
* 不能用SimpleDateFormat因为12月32日会转成第2年的
* 而是用BeanUtils里面的DateLocaleConverter
* 日期错误转不了,就会抛异常!*/
if(this.birthday!=null && !this.birthday.trim().equals("")){
try{
DateLocaleConverter conv= new DateLocaleConverter();
conv.convert(this.birthday, "yyyy-MM-dd");
}catch (Exception e) {
//日期错误转不了,就会抛异常
flag = false;
errors.put("birthday", "日期格式不对!");
}
}
//3,手机可以为空,否则必需是7-11位数字
if(!this.cellphone.matches("\\d{7,11}") && cellphone!=null && !cellphone.trim().equals("")){
flag = false;
errors.put("cellphone", "手机号码为7-11位数字!");
}
//4,电子邮箱不能为空,并且要是一个格式合法的邮箱
if(this.email==null || this.email.trim().equals("")){
flag = false;
errors.put("email", "邮箱不能为空!");
}else{
if(!this.email.matches("\\w+@\\w+(\\.\\w+)+")){
flag = false;
errors.put("email", "邮箱格式错误!");
}
}
return flag;
}
//如果要在jsp中用EL${}千万要记得生成 getter and setter方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getCellphone() {
return cellphone;
}
public void setCellphone(String cellphone) {
this.cellphone = cellphone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPreference() {
return preference;
}
public void setPreference(String preference) {
this.preference = preference;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Map getErrors() {
return errors;
}
public void setErrors(Map errors) {
this.errors = errors;
}
}
BusinessService位于service包
package cn.itcast.service;
import java.util.List;
import cn.itcast.domain.Customer;
import cn.itcast.domain.PageBean;
import cn.itcast.domain.QueryInfo;
public interface BusinessService {
//方法1:添加一个Customer到数据库,返回值为void
void add(Customer c);
//方法2:更新一个Customer到数据库,返回值为void
void update(Customer c);
//方法3:删除一个Customer从数据库,返回值为void
void delete(Customer c);
//方法4:通过id查询并返回一个封装好数据的Customer
Customer find(String id);
//方法5:返回一个封装了所有Customer的集合
List<Customer> getAll();
//方法6:同dao的方法名一样!因为薄薄的业务层全是调用dao的方法!
//封装好QueryInfo和PageBean里的数据,返回PageBean 以供jsp显示
public PageBean pageQuery(QueryInfo info);
}
BusinessServiceImpl位于service.impl包
package cn.itcast.service.impl;
import java.util.List;
import cn.itcast.dao.CustomerDao;
import cn.itcast.dao.impl.CustomerDaoImpl;
import cn.itcast.domain.Customer;
import cn.itcast.domain.PageBean;
import cn.itcast.domain.QueryInfo;
import cn.itcast.domain.QueryResult;
import cn.itcast.factory.DaoFactory;
import cn.itcast.service.BusinessService;
public class BusinessServiceImpl implements BusinessService {
/*对web层提供所有的服务,
* web层收到请求后,统一交给BusinessServiceImpl处理
* BusinessServiceImpl实际上是交给CustomDao处理
* 薄薄的业务层!
* 如果要实现与Dao层完全解耦,则可以使用工厂模式
* 1,建一个factory包,建一个DaoFactory类(单例)
* 2,src下建一个dao.properties配置文件,
* 键为CustomerDao,值为cn.itcast.dao.impl.CustomerDaoImpl
* 3,DaoFactory类使用泛型方法,参数为CustomerDao接口的字节码名
* 返回一个dao.properties配置文件中该接口对应的实现类的实例,并返回!
* 4,在BusinessServiceImpl的成员变量调用上述方法得到CustomerDao*/
//private CustomerDao dao=new CustomerDaoImpl();
private CustomerDao dao=DaoFactory.getInstance().createDao(CustomerDao.class);
//方法1:添加一个Customer到数据库,返回值为void
public void add(Customer c){
dao.add(c);
}
//方法2:更新一个Customer到数据库,返回值为void
public void update(Customer c){
dao.update(c);
}
//方法3:删除一个Customer从数据库,返回值为void
public void delete(Customer c){
dao.delete(c);
}
//方法4:通过id查询并返回一个封装好数据的Customer
public Customer find(String id){
return dao.find(id);
}
//方法5:返回一个封装了所有Customer的集合
public List<Customer> getAll(){
return dao.getAll();
}
//方法6:同dao的方法名一样!因为薄薄的业务层全是调用dao的方法!
//封装好QueryInfo和PageBean里的数据,返回PageBean 以供jsp显示
public PageBean pageQuery(QueryInfo info){
int startIndex=info.getStartIndex();
int pageSize=info.getPageSize();
//调用dao获取页面查询的结果对象
QueryResult qr=dao.pageQuery(startIndex, pageSize);
//装备好PageBean,封装所有数据(包括QueryInfo对象和QueryResult),供jsp页面显示!
PageBean bean=new PageBean();
bean.setList(qr.getList());
bean.setTotalRecord(qr.getTotalRecord());
bean.setCurrentPage(info.getCurrentPage());
bean.setPageSize(info.getPageSize());
return bean;
}
}
Global位于utils包
package cn.itcast.utils;
public class Global {
public static String genders[] = {"男","女"};
public static String preferences[] = {"女红","绘画","诗词","对联","喝酒","玩乐","理政","理财"};
public static String types[] = {"大丫鬟","小丫鬟","嬷嬷","少爷","姑娘","亲戚","老爷","花旦","尼姑"};
}
JdbcUtils位于utils包
package cn.itcast.utils;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JdbcUtils {
private static Properties pro=new Properties();
/*
* 静态成员Properties
* 静态代码块:加载配置文件,注册驱动
* 静态方法1:获取连接
* 静态方法2:释放连接
* 工具类的异常只管抛,也可以转型后抛
* db.properties文件位于类目录下即src
*/
static{
String pro_name="db.properties";
InputStream in=JdbcUtils.class.getClassLoader().getResourceAsStream(pro_name);
try {
pro.load(in);
Class.forName(pro.getProperty("driver"));
} catch (Exception e) {
// 静态代码块的异常只能转型后抛出
throw new ExceptionInInitializerError(e);
}
}
//方法1:获取连接
public static Connection getConnection() throws SQLException{
String url=pro.getProperty("url");
String user=pro.getProperty("user");
String password=pro.getProperty("password");
Connection conn=DriverManager.getConnection(url, user, password);
return conn;
}
//方法2:释放连接
public static void release(Connection conn,Statement st,ResultSet rs){
if (conn!=null) {
try {
conn.close();
}catch (Exception e) {
//只能记录!一旦抛出,后面的2条if代码就无法执行了
e.printStackTrace();
}
conn=null;
}
if (st!=null) {
try {
st.close();
}catch (Exception e) {
//只能记录!一旦抛出,后面的1条if代码就无法执行了
e.printStackTrace();
}
st=null;
}
if (rs!=null) {
try {
rs.close();
}catch (Exception e) {
e.printStackTrace();
}
rs=null;
}
}
}
MyEL位于utils包
package cn.itcast.utils;
/*自定义EL函数,虽无法代替与web有关的java代码
* 1,静态方法
* 2,tld文件描一把,抄Tomcat的tld抄头抄屁股
* 3,jsp中taglib导入*/
public class MyEL {
//我的EL函数库,方法1,取文本左边!
public static String leftStr(String str,Integer len){
if(str.trim().length()>len){
return str.substring(0, len) + "......";
}
return str;
}
}
WebUtils位于utils包
package cn.itcast.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import sun.misc.BASE64Encoder;
import cn.itcast.formbean.FormBean;
public class WebUtils {
//方法1说明:将表单数据封装到formbean中,供校验用!先不使用泛型
public static FormBean request2FormBean(HttpServletRequest request,
Class<FormBean> beanClass) {
try{
//1,创建bean对象实例,用来接收request中的数据!
FormBean bean=beanClass.newInstance();
//2,用BeanUtils的方法把request中的数据封装到bean对象中
Enumeration e = request.getParameterNames();//参数名列表
while(e.hasMoreElements()){
String name = (String) e.nextElement(); //name gender birthday等
String value = request.getParameter(name);
//虽然只支持8种基本数据类型,但是FormBean里成员全是string!
BeanUtils.setProperty(bean, name, value);
}
//3,返回封装了表单数据的FormBean对象
return bean;
}catch (Exception e) {
// 转运行时异常后抛出
throw new RuntimeException(e);
}
}
//方法2说明:使用泛型 将表单数据封装到formbean中,供校验用!
public static<T> T request2FormBean(HttpServletRequest request,
Class<T> beanClass) {
try{
//1,创建bean对象实例,用来接收request中的数据!
T bean=beanClass.newInstance();
//2,用BeanUtils的方法把request中的数据封装到bean对象中
Enumeration e = request.getParameterNames();//参数名列表
while(e.hasMoreElements()){
String name = (String) e.nextElement(); //name gender birthday等
String value = request.getParameter(name);
BeanUtils.setProperty(bean, name, value);
}
//3,返回封装了表单数据的FormBean对象
return bean;
}catch (Exception e) {
// 转运行时异常后抛出
throw new RuntimeException(e);
}
}
//方法3说明:将FormBean中的数据(该类成员全是string)封装到domain包的Bean里面
public static void copyBean(Object src,Object dest){
//需要注册日期转换器
//(将FormBean里的字符串转成Bean里的成员:Date日期)
ConvertUtils.register(new Converter(){
public Object convert(Class type, Object value) {
/*方法说明:(将value转成type类型)
*1,判断value是不是null
*2,判断value是不是String
*3,判断value是不是空白字符串
*4,用SimpleDateFormat parse
*5,工具类异常统统往外抛 */
if(value==null){
return null;
}
String date=(String)value;
if("".equals(date.trim())){
return null;
}
//指定字符串的格式,转成Date对象
SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");
try {
return df.parse(date);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}, Date.class);
try {
//使用BeanUtils的复制bean方法
BeanUtils.copyProperties(dest, src);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//方法4, 直接将表单中的数据封装到domain包的Bean里面
//使用字节码避免new 对象,使用泛形避免强转
public static <T> T request2Bean(HttpServletRequest request,Class<T> beanClass){
try{
//1,创建bean对象实例,用来接收request中的数据!
T bean = beanClass.newInstance();
//2,得到request里面所有提交的数据(键值对)
Map map = request.getParameterMap();
//map{name=aa,password=bb,birthday=1990-09-09} bean(name=aa,password=dd,birthday=Date)
//3,需要注册日期转换器
//(将表单里的字符串value转成Object即 Customer的成员:Date日期)
ConvertUtils.register(new Converter(){
public Object convert(Class type, Object value) {
if(value==null){
return null;
}
String str = (String) value;
if(str.trim().equals("")){
return null;
}
//指定字符串的格式,转成Date对象
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try {
return df.parse(str);
} catch (Exception e) {
//异常不希望给上层带麻烦,就转型后再抛
throw new RuntimeException(e);
}
}
}, Date.class);
//4,根据关键字,将map集合里面的数据填充到bean里(即Customer)
//只支持8种基本数据类型
BeanUtils.populate(bean, map);
//5,返回填充好请求参数的bean
return bean;
}catch (Exception e) {
throw new RuntimeException(e);
}
}
//方法5, 产生一个唯一的id(UUID.randomUUID().toString())
public static String generateId(){
return UUID.randomUUID().toString();
}
//方法6,将字符串md5加密后返回!
public static String md5(String message){
/*ServiceUtils工具类异常直接抛,异常链不能断
* 提供md5加密标准4步骤(生成图片验证码曾用到)*/
try {
MessageDigest md=MessageDigest.getInstance("md5");
byte[] md5=md.digest(message.getBytes());
BASE64Encoder encoder=new BASE64Encoder();
return encoder.encode(md5);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}
AddCustomerServlet位于web.controller包
package cn.itcast.web.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.domain.Customer;
import cn.itcast.formbean.FormBean;
import cn.itcast.service.BusinessService;
import cn.itcast.service.impl.BusinessServiceImpl;
import cn.itcast.utils.Global;
import cn.itcast.utils.WebUtils;
public class AddCustomerServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*点击超链接:给用户提供一个添加界面
* 1,先将Global的静态成员(可能变化的数据)存到request域内
* 2,转发到WEB-INF/jsp/addcustomer.jsp*/
request.setAttribute("genders", Global.genders);
request.setAttribute("preferences", Global.preferences);
request.setAttribute("types", Global.types);
request.getRequestDispatcher("/WEB-INF/jsp/addcustomer.jsp").forward(request, response);
}
//处理表单提交的添加客户请求
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
//1,处理乱码问题
request.setCharacterEncoding("utf-8");
//2,把表单数据封装到FormBean对象,对提交表单的字段进行validate校验
FormBean form=WebUtils.request2FormBean(request, FormBean.class);
boolean b=form.validate();
//2.1 如果校验失败,跳回到表单页面,回显校验失败信息
if(!b){
//因为form对象中有一个map errors封装了错误信息
request.setAttribute("form", form);
//request.getRequestDispatcher("/servlet/AddCustomerServlet").forward(request, response);
doGet(request, response);
return;
//request.setAttribute("message", "validate失败!");
//request.getRequestDispatcher("/message.jsp").forward(request, response);
}
//request.setAttribute("message", "validate成功!");
//2.2如果校验成功,把表单封装到customer对象中
Customer c =WebUtils.request2Bean(request, Customer.class);
c.setDescription(c.getDescription().trim());
//Customer还差一个成员:id,通过工具类UUID算法生成全球唯一ID
c.setId(WebUtils.generateId());
//3,这个时候已经将Customer对象准备好了,调业务层添加客户
BusinessService service=new BusinessServiceImpl();
service.add(c);
request.setAttribute("message", "添加用户成功!");
} catch (Exception e) {
//如果添加失败:记录异常,并给友好提示
e.printStackTrace();
request.setAttribute("message", "添加用户失败!");
}
//无论添加成功或失败,都将跳转到全局消息显示页面
request.getRequestDispatcher("/message.jsp").forward(request, response);
}
}
CopyOfListCustomerServlet位于web.controller包
package cn.itcast.web.controller;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.service.BusinessService;
import cn.itcast.service.impl.BusinessServiceImpl;
public class CopyOfListCustomerServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//谁能保证这儿不抛异常!
try {
//所示请求,都通过业务层实现!接口指向实现
BusinessService service = new BusinessServiceImpl();
List list = service.getAll();
//将list集合存到request域带给jsp显示
request.setAttribute("list", list);
request.getRequestDispatcher("/WEB-INF/jsp/listcustomer.jsp").forward(request, response);
} catch (Exception e) {
// 出现异常不要紧,记录下来,并给友好提示!
e.printStackTrace();
request.setAttribute("message", "查看客户失败!!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
DeleteCustomerServlet位于web.controller包
package cn.itcast.web.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.service.BusinessService;
import cn.itcast.service.impl.BusinessServiceImpl;
public class DeleteCustomerServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//servlet的doPost方法try异常模板代码[try_post]
//谁能保证这儿不抛异常!
try {
String id=request.getParameter("id");
//调用service处理业务!所示请求,都通过业务层实现!接口指向实现
BusinessService service = new BusinessServiceImpl();
service.delete(service.find(id));
//业务处理好之后,将message存到request域带给jsp显示!
request.setAttribute("message", "删除成功");
request.getRequestDispatcher("/message.jsp").forward(request,
response);
} catch (Exception e) {
//出现异常不要紧,记录下来,并给友好提示!
e.printStackTrace();
request.setAttribute("message", "删除失败");
request.getRequestDispatcher("/message.jsp").forward(request,
response);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
EditCustomerServlet位于web.controller包
package cn.itcast.web.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.domain.Customer;
import cn.itcast.formbean.FormBean;
import cn.itcast.service.BusinessService;
import cn.itcast.service.impl.BusinessServiceImpl;
import cn.itcast.utils.Global;
import cn.itcast.utils.WebUtils;
public class EditCustomerServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*点击修改超链接:给用户提供一个修改界面
* 1,先通过参数c.id获取Customer对象,存到request域内
* 1,再将Global的静态成员(可能变化的数据)存到request域内
* 2,最后转发到WEB-INF/jsp/editcustomer.jsp*/
String id=request.getParameter("id");
//调用业务层处理业务,获得Customer
BusinessService service=new BusinessServiceImpl();
Customer c=service.find(id);
request.setAttribute("c", c);
//别忘了还要将可能变化的这些动态数据存到域内,传给jsp显示
request.setAttribute("genders", Global.genders);
request.setAttribute("preferences", Global.preferences);
request.setAttribute("types", Global.types);
request.getRequestDispatcher("/WEB-INF/jsp/editcustomer.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
//1,既然是Post提交上来的数据,首先处理乱码问题!
request.setCharacterEncoding("utf-8");
//2,把表单数据封装到FormBean对象,对提交表单的字段进行validate校验
FormBean form=WebUtils.request2FormBean(request, FormBean.class);
boolean b=form.validate();
//2.1 如果校验失败,跳回到表单页面,回显校验失败信息
if(!b){
//因为form对象中有一个map errors封装了错误信息
request.setAttribute("form", form);
//request.getRequestDispatcher("/servlet/AddCustomerServlet").forward(request, response);
doGet(request, response);
return;
//request.setAttribute("message", "validate失败!");
//request.getRequestDispatcher("/message.jsp").forward(request, response);
}
//request.setAttribute("message", "validate成功!");
//2.2如果校验成功,把表单封装到customer对象中
Customer c =WebUtils.request2Bean(request, Customer.class);
//3,这个时候已经将Customer对象准备好了,调业务层更新客户数据
BusinessService service=new BusinessServiceImpl();
service.update(c);
request.setAttribute("message", "更新用户成功!");
} catch (Exception e) {
//如果更新失败:记录异常,并给友好提示
e.printStackTrace();
request.setAttribute("message", e);
}
//无论更新成功或失败,都将跳转到全局消息显示页面
request.getRequestDispatcher("/message.jsp").forward(request, response);
}
}
ListCustomerServlet位于web.controller包
package cn.itcast.web.controller;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.domain.PageBean;
import cn.itcast.domain.QueryInfo;
import cn.itcast.service.BusinessService;
import cn.itcast.service.impl.BusinessServiceImpl;
import cn.itcast.utils.WebUtils;
public class ListCustomerServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//谁能保证这儿不抛异常!
try {
//使用工具类,先将请求封装到一个QueryInfo对象中去!
QueryInfo info=WebUtils.request2Bean(request, QueryInfo.class);
//所示请求,都通过业务层实现!接口指向实现
BusinessService service = new BusinessServiceImpl();
PageBean pb=service.pageQuery(info);
//PageBean已经封装了所有数据,存到request域带给jsp显示
request.setAttribute("pb", pb);
request.getRequestDispatcher("/WEB-INF/jsp/listcustomer.jsp").forward(request, response);
} catch (Exception e) {
// 出现异常不要紧,记录下来,并给友好提示!
e.printStackTrace();
request.setAttribute("message", e);
request.getRequestDispatcher("/message.jsp").forward(request, response);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
batchinsert位于junit.test包
package junit.test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import cn.itcast.exception.DaoException;
import cn.itcast.utils.JdbcUtils;
import cn.itcast.utils.WebUtils;
public class batchinsert {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement st=null;
ResultSet rs=null;
try {
conn=JdbcUtils.getConnection();
//先准备String sql,再通过连接准备PreparedStatement
String fields="id,name,gender,preference,type";
String sql="insert into customer("+fields+") values(?,?,?,?,?)";
st=conn.prepareStatement(sql);
//批量插入
for(int i=0;i<200;i++){
st.setString(1, WebUtils.generateId() + i);
st.setString(2, "妙玉" + i);
st.setString(3, "女");
st.setString(4, "诗词");
st.setString(5, "尼姑");
st.addBatch();
if(i%50==0){
//避免内存溢出,每50条执行一次后清空!
st.executeBatch();
st.clearBatch();
}
}
st.executeBatch();
} catch (Exception e) {
//自定义Dao异常,是为了方便定义错误出在哪一层!
throw new DaoException();
}finally{
JdbcUtils.release(conn, st, rs);
}
}
}
test位于junit.test
包
package junit.test;
import java.util.HashMap;
import java.util.Map;
public class test {
private static Map errors=new HashMap();
public static void main(String[] args) {
System.out.println(validate("1231232121"));
}
public static boolean validate(String cellphone){
//默认是真,只要有一个错误,flag为假
boolean flag = true;
//3,手机是7-11位数字
if(!cellphone.matches("\\d{7,11}") && cellphone!=null && !cellphone.trim().equals("")){
flag = false;
errors.put("cellphone", "手机号码为7-11位数字!");
}
// if(!name.matches("^([\u4e00-\u9fa5]+)$") || !name.matches("[A-Za-z]{2,10}"))
return flag;
}
public static boolean validate1(String name){
//默认是真,只要有一个错误,flag为假
boolean flag = true;
//名字不能为空,只能是2-10位字母或汉字区间(\u4e00-\u9fa5)
if(name==null || name.trim().equals("")){
flag = false;
errors.put("name", "名字不能为空!");
}else if(!name.matches("^([\u4e00-\u9fa5]{2,})$") && !name.matches("[A-Za-z]{2,10}")){
flag = false;
errors.put("name", "名字必须是2-10位字母或汉字!");
}
// if(!name.matches("^([\u4e00-\u9fa5]+)$") || !name.matches("[A-Za-z]{2,10}"))
return flag;
}
}
dao.properties位于src类目录下
CustomerDao=cn.itcast.dao.impl.CustomerDaoImpl
#CustomerDao=cn.itcast.dao.impl.UserDaoXmlImpl
db.properties位于src类目录下
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/day14_customer?useUnicode=true&characterEncoding=utf-8
user=root
password=root
#driver=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@localhost:1521:orcl
#user=system
#password=itcast
用到的第3方jar包
用到的第三方库
jstl.jar
standard.jar
commons-beanutils-1.8.0.jar
commons-logging.jar
MySQL驱动:mysql-connector-java-5.0.8-bin.jar
head.jsp位于WebRoot目录下
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>红楼梦苑</title>
</head>
<body style="text-align: center;">
<h1>红楼梦苑</h1>
<a href="${pageContext.request.contextPath}/servlet/AddCustomerServlet" target="main">添加红楼十二钗</a>
<a href="${pageContext.request.contextPath}/servlet/ListCustomerServlet" target="main">查看红楼十二钗</a>
</body>
</html>
index.jsp位于WebRoot目录下
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>首页</title>
<!-- 千万注意:frameset和body是同级标签,不能嵌套 -->
</head>
<frameset rows="20%,*">
<frame name="head" src="${pageContext.request.contextPath}/head.jsp" scrolling="no" noresize="noresize"/>
<frame name="main" src="#">
</frameset>
</html>
message.jsp位于WebRoot目录下
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>您有新的消息,请注意查收</title>
</head>
<body>
${message }
${requestScope.message }
${form.errors.name }
</body>
</html>
ShowCalendar.js位于WebRoot/js目录下
// 日期选择
// By Ziyue(http://www.web-v.com/)
// 使用方法:
// <script type="text/javascript" src="${pageContext.request.contextPath }/js/ShowCalendar.js"></script>
// <input name="birthday" type="text" id="birthday" title="点击选择" onClick="showCalendar(this.id)">
var today;
document.writeln("<div id='Calendar' style='position:absolute; z-index:1; visibility: hidden; filter:\"progid:DXImageTransform.Microsoft.Shadow(direction=135,color=#999999,strength=3)\"'></div>");
function getDays(month, year)
{
var daysInMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
//下面的这段代码是判断当前是否是闰年的
if (1 == month)
return ((0 == year % 4) && (0 != (year % 100))) || (0 == year % 400) ? 29 : 28;
else
return daysInMonth[month];
}
function getToday()
{
//得到今天的年,月,日
this.now = new Date();
this.year = this.now.getFullYear();
this.month = this.now.getMonth();
this.day = this.now.getDate();
}
function getStringDay(str)
{
//得到输入框的年,月,日
var str=str.split("-")
this.now = new Date(parseFloat(str[0]),parseFloat(str[1])-1,parseFloat(str[2]));
this.year = this.now.getFullYear();
this.month = this.now.getMonth();
this.day = this.now.getDate();
}
function newCalendar() {
var parseYear = parseInt(document.all.Year.options[document.all.Year.selectedIndex].value);
var newCal = new Date(parseYear, document.all.Month.selectedIndex, 1);
var day = -1;
var startDay = newCal.getDay();
var daily = 0;
if ((today.year == newCal.getFullYear()) &&(today.month == newCal.getMonth()))
day = today.day;
var tableCal = document.all.calendar;
var intDaysInMonth =getDays(newCal.getMonth(), newCal.getFullYear());
for (var intWeek = 1; intWeek < tableCal.rows.length;intWeek++)
for (var intDay = 0;intDay < tableCal.rows[intWeek].cells.length;intDay++)
{
var cell = tableCal.rows[intWeek].cells[intDay];
if ((intDay == startDay) && (0 == daily))
daily = 1;
if(day==daily) //今天,调用今天的Class
{
cell.style.background='#6699CC';
cell.style.color='#FFFFFF';
//cell.style.fontWeight='bold';
}
else if(intDay==6) //周六
cell.style.color='green';
else if (intDay==0) //周日
cell.style.color='red';
if ((daily > 0) && (daily <= intDaysInMonth))
{
cell.innerText = daily;
daily++;
}
else
cell.innerText = "";
}
}
function GetDate(InputBox)
{
var sDate;
//这段代码处理鼠标点击的情况
if (event.srcElement.tagName == "TD")
if (event.srcElement.innerText != "")
{
sDate = document.all.Year.value + "-" + document.all.Month.value + "-" + event.srcElement.innerText;
eval("document.all."+InputBox).value=sDate;
HiddenCalendar();
}
}
function HiddenCalendar()
{
//关闭选择窗口
document.all.Calendar.style.visibility='hidden';
}
function showCalendar(InputBox)
{
var months = new Array("一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月");
var days = new Array("日","一", "二", "三", "四", "五", "六");
var x,y,intLoop,intWeeks,intDays;
var DivContent;
var year,month,day;
var o=eval("document.all."+InputBox);
var thisyear; //真正的今年年份
thisyear=new getToday();
thisyear=thisyear.year;
today = o.value;
if(isDate(today))
today = new getStringDay(today);
else
today = new getToday();
//显示的位置
x=o.offsetLeft;
y=o.offsetTop;
while(o=o.offsetParent)
{
x+=o.offsetLeft;
y+=o.offsetTop;
}
document.all.Calendar.style.left=x+2;
document.all.Calendar.style.top=y+20;
document.all.Calendar.style.visibility="visible";
//下面开始输出日历表格(border-color:#9DBAF7)
DivContent="<table border='0' cellspacing='0' style='border:1px solid #0066FF; background-color:#EDF2FC'>";
DivContent+="<tr>";
DivContent+="<td style='border-bottom:1px solid #0066FF; background-color:#C7D8FA'>";
//年
DivContent+="<select name='Year' id='Year' onChange='newCalendar()' style='font-family:Verdana; font-size:12px'>";
for (intLoop = thisyear - 35; intLoop < (thisyear + 2); intLoop++)
DivContent+="<option value= " + intLoop + " " + (today.year == intLoop ? "Selected" : "") + ">" + intLoop + "</option>";
DivContent+="</select>";
//月
DivContent+="<select name='Month' id='Month' onChange='newCalendar()' style='font-family:Verdana; font-size:12px'>";
for (intLoop = 0; intLoop < months.length; intLoop++)
DivContent+="<option value= " + (intLoop + 1) + " " + (today.month == intLoop ? "Selected" : "") + ">" + months[intLoop] + "</option>";
DivContent+="</select>";
DivContent+="</td>";
DivContent+="<td style='border-bottom:1px solid #0066FF; background-color:#C7D8FA; font-weight:bold; font-family:Wingdings 2,Wingdings,Webdings; font-size:16px; padding-top:2px; color:#4477FF; cursor:hand' align='center' title='关闭' onClick='javascript:HiddenCalendar()'>S</td>";
DivContent+="</tr>";
DivContent+="<tr><td align='center' colspan='2'>";
DivContent+="<table id='calendar' border='0' width='100%'>";
//星期
DivContent+="<tr>";
for (intLoop = 0; intLoop < days.length; intLoop++)
DivContent+="<td align='center' style='font-size:12px'>" + days[intLoop] + "</td>";
DivContent+="</tr>";
//天
for (intWeeks = 0; intWeeks < 6; intWeeks++)
{
DivContent+="<tr>";
for (intDays = 0; intDays < days.length; intDays++)
DivContent+="<td onClick='GetDate(\"" + InputBox + "\")' style='cursor:hand; border-right:1px solid #BBBBBB; border-bottom:1px solid #BBBBBB; color:#215DC6; font-family:Verdana; font-size:12px' align='center'></td>";
DivContent+="</tr>";
}
DivContent+="</table></td></tr></table>";
document.all.Calendar.innerHTML=DivContent;
newCalendar();
}
function isDate(dateStr)
{
var datePat = /^(\d{4})(\-)(\d{1,2})(\-)(\d{1,2})$/;
var matchArray = dateStr.match(datePat);
if (matchArray == null) return false;
var month = matchArray[3];
var day = matchArray[5];
var year = matchArray[1];
if (month < 1 || month > 12) return false;
if (day < 1 || day > 31) return false;
if ((month==4 || month==6 || month==9 || month==11) && day==31) return false;
if (month == 2)
{
var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
if (day > 29 || (day==29 && !isleap)) return false;
}
return true;
}
igg.tld位于WebRoot/WEB-INF目录下
<?xml version="1.0" encoding="UTF-8" ?>
<taglib 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-jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>1.0</tlib-version>
<short-name>SimpleTagLibrary</short-name>
<uri>www.igg.com</uri>
<function>
<name>leftStr</name>
<function-class>cn.itcast.utils.MyEL</function-class>
<function-signature>java.lang.String leftStr( java.lang.String , java.lang.Integer)</function-signature>
</function>
</taglib>
addcustomer.jsp位于WebRoot/WEB-INF/jsp目录下
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>添加人物</title>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/ShowCalendar.js"></script>
<script type="text/javascript">
//js连接喜好选项,成字符串,并作为隐藏选项添加在form表单里
function joinStr(){
var o1=document.getElementsByName("pre");
var str="";
for(var i=0;i<o1.length;i++){
//alert(o1[i].value);
if(o1[i].checked){
str+=o1[i].value+",";
}
}
str=str.substr(0,str.length-1);
var form=document.getElementById("form_id");
var hiddenInput=document.createElement("input");
hiddenInput.type="hidden";
hiddenInput.name="preference";
hiddenInput.value=str;
//alert(str);
form.appendChild(hiddenInput);
return true;
}
</script>
</head>
<body style="text-align: center;">
<form id="form_id" action="${pageContext.request.contextPath }/servlet/AddCustomerServlet" method="post" οnsubmit="return joinStr()">
<table border="1" width="50%">
<tr>
<td>人物姓名</td>
<td>
<input type="text" name="name" value="${param.name }">
<span>${form.errors.name }</span>
</td>
</tr>
<tr>
<td>人物性别</td>
<td>
<c:forEach var="g" items="${genders}">
<input type="radio" name="gender" value="${g }" ${param.gender==g?'checked':'' }/>${g }
</c:forEach>
</td>
</tr>
<tr>
<td>生日</td>
<td>
<input type="text" name="birthday" id="birthday" onClick="showCalendar(this.id)" value="${param.birthday }" >
<span>${form.errors.birthday }</span>
</td>
</tr>
<tr>
<td>手机</td>
<td>
<input type="text" name="cellphone" value="${param.cellphone }">
<span>${form.errors.cellphone }</span>
</td>
</tr>
<tr>
<td>邮箱</td>
<td>
<input type="text" name="email" value="${param.email }">
<span>${form.errors.email }</span>
</td>
</tr>
<tr>
<td>爱好</td>
<td>
<c:forEach var="pre" items="${preferences}">
<input type="checkbox" name="pre" value="${pre }" ${fn:contains(param.preference,pre)?'checked':'' }/>${pre }
</c:forEach>
</td>
</tr>
<tr>
<td>人物类型</td>
<td>
<c:forEach var="t" items="${types}">
<input type="radio" name="type" value="${t }" ${param.type==t?'checked':'' }>${t }
</c:forEach>
</td>
</tr>
<tr>
<td>备注</td>
<td>
<textarea rows="5" cols="60" name="description">
${fn:trim(param.description) }
</textarea>
</td>
</tr>
<tr>
<td>
<input type="reset" value="重置">
</td>
<td>
<input type="submit" value="添加客户">
</td>
</tr>
</table>
</form>
</body>
</html>
editcustomer.jsp位于WebRoot/WEB-INF/jsp目录下
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>修改人物</title>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/ShowCalendar.js"></script>
<script type="text/javascript">
//js连接喜好选项,成字符串,并作为隐藏选项添加在form表单里
function joinStr(){
var o1=document.getElementsByName("pre");
var str="";
for(var i=0;i<o1.length;i++){
//alert(o1[i].value);
if(o1[i].checked){
str+=o1[i].value+",";
}
}
str=str.substr(0,str.length-1);
var form=document.getElementById("form_id");
var hiddenInput=document.createElement("input");
hiddenInput.type="hidden";
hiddenInput.name="preference";
hiddenInput.value=str;
//alert(str);
form.appendChild(hiddenInput);
return true;
}
</script>
</head>
<body style="text-align: center;">
<form id="form_id" action="${pageContext.request.contextPath }/servlet/EditCustomerServlet" method="post" οnsubmit="return joinStr()">
<table border="1" width="50%">
<input type="hidden" name="id" value="${c.id }">
<tr>
<td>人物姓名</td>
<td>
<input type="text" name="name" value="${c.name }">
<span>${form.errors.name }</span>
</td>
</tr>
<tr>
<td>人物性别</td>
<td>
<c:forEach var="g" items="${genders}">
<input type="radio" name="gender" value="${g }" ${c.gender==g?'checked':'' }/>${g }
</c:forEach>
</td>
</tr>
<tr>
<td>生日</td>
<td>
<input type="text" name="birthday" id="birthday" onClick="showCalendar(this.id)" value="${c.birthday }" >
<span>${form.errors.birthday }</span>
</td>
</tr>
<tr>
<td>手机</td>
<td>
<input type="text" name="cellphone" value="${c.cellphone }">
<span>${form.errors.cellphone }</span>
</td>
</tr>
<tr>
<td>邮箱</td>
<td>
<input type="text" name="email" value="${c.email }">
<span>${form.errors.email }</span>
</td>
</tr>
<tr>
<td>爱好</td>
<td>
<c:forEach var="pre" items="${preferences}">
<input type="checkbox" name="pre" value="${pre }" ${fn:contains(c.preference,pre)?'checked':'' }/>${pre }
</c:forEach>
</td>
</tr>
<tr>
<td>人物类型</td>
<td>
<c:forEach var="t" items="${types}">
<input type="radio" name="type" value="${t }" ${c.type==t?'checked':'' }>${t }
</c:forEach>
</td>
</tr>
<tr>
<td>备注</td>
<td>
<textarea rows="5" cols="60" name="description">
${fn:trim(c.description) }
</textarea>
</td>
</tr>
<tr>
<td>
<input type="reset" value="重置">
</td>
<td>
<input type="submit" value="更新客户">
</td>
</tr>
</table>
</form>
</body>
</html>
listcustomer.jsp位于WebRoot/WEB-INF/jsp目录下
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="/WEB-INF/igg.tld" prefix="igg"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>显示红楼梦所有人物</title>
<style type="text/css">
.even{background-color: #FFFF00}
.odd{background-color: #FFCCFF}
tr:hover{background-color: #FF99FF}
a:link{text-decoration: none}
</style>
<script type="text/javascript">
function deleteById(id){
if(window.confirm("确定删除吗?")){
window.location.href='${pageContext.request.contextPath}/servlet/DeleteCustomerServlet?id='+id;
}
}
</script>
</head>
<body style="text-align: center;">
<table frame="border" width="86%" >
<tr>
<td>人物名字</td>
<td>性别</td>
<td>生日</td>
<td>手机</td>
<td>邮箱</td>
<td>爱好</td>
<td>类型</td>
<td>备注</td>
<td>操作</td>
</tr>
<c:forEach var="c" items="${requestScope.pb.list}" varStatus="status">
<tr class="${status.count%2==0?'even':'odd' }">
<td>${c.name }</td>
<td>${c.gender }</td>
<td>${c.birthday }</td>
<td>${c.cellphone }</td>
<td>${c.email }</td>
<td>${c.preference }</td>
<td>${c.type }</td>
<td>${igg:leftStr(c.description,10) }</td>
<td>
<a href="${pageContext.request.contextPath }/servlet/EditCustomerServlet?id=${c.id }">修改</a>
<a href="javascript:void(0)" οnclick="deleteById('${c.id }')">删除</a>
</td>
<tr>
</c:forEach>
</table>
<hr/>
<script type="text/javascript">
function go(page){
//如果新的page小于0 或者不是数字 或者大于总页数,就置输入框为''
var total_page=document.getElementById("totalPage_id").innerHTML;
//可以直接${pb.totalPage}拿到总页数
var page_size=document.getElementById("pageSize_id").value;
//alert(page);
//alert(total_page);
//alert(page>parseInt(total_page));
if(page<1){
alert("请输入正整数");
document.getElementById("gotoPage_id").value='';
}else if(page>${pb.totalPage}){
alert("请输入"+total_page+"之内的正整数");
document.getElementById("gotoPage_id").value='';
}else if(page==parseInt(page)){
//alert("正准备跳转");
window.location="${pageContext.request.contextPath}/servlet/ListCustomerServlet?currentPage="+page+"&pageSize="+page_size;
}
}
function changeSize(oldSize,newSize){
//如果新的size小于0 或者不是数字 或者大于99,就恢复输入框为oldsize
if(newSize<1){
alert("请输入正整数");
document.getElementById("pageSize_id").value=oldSize;
}else if(newSize>99){
alert("请输入100以内正整数");
document.getElementById("pageSize_id").value=oldSize;
}else if(newSize==parseInt(newSize)){
//alert("正准备跳转");
location.href = '${pageContext.request.contextPath}/servlet/ListCustomerServlet?pageSize=' + newSize;
}
}
</script>
共${pb.totalRecord }条记录
每页
<input type="text" id="pageSize_id" value="${pb.pageSize }" style="width: 15px;" maxlength="2" οnchange="changeSize('${pb.pageSize }',this.value)"/>
条记录
每页${pb.pageSize }条
共<span id="totalPage_id">${pb.totalPage }</span>页
当前第${pb.currentPage}页
<c:if test="${pb.currentPage>5}">
<a href="javascript:void(0)" οnclick="go(1)">首页</a>
</c:if>
<c:if test="${pb.currentPage!=1}">
<a href="javascript:void(0)" οnclick="go(${pb.previousPage})">上一页</a>
</c:if>
<c:forEach var="i" items="${pb.pageBar}">
<c:if test="${i==pb.currentPage}">
<font color='red'>${i}</font>
</c:if>
<c:if test="${i!=pb.currentPage}">
<a href="javascript:void(0)" οnclick="go(${i})">
${i }</a>
</c:if>
</c:forEach>
<c:if test="${pb.currentPage!=pb.totalPage}">
<a href="javascript:void(0)" οnclick="go(${pb.nextPage})">下一页</a>
</c:if>
<c:if test="${pb.currentPage<pb.totalPage-5}">
<a href="javascript:void(0)" οnclick="go(${pb.totalPage} )">末页</a>
</c:if>
<input type="text" id="gotoPage_id" style="width: 20px" οnchange="go(this.value)"/>
</body>
</html>