JavaWeb_12_jdbc_改造MVC案例(登录注册)

总纲:  改造数据库应用(以前是xml现在是mysql)
1.导入数据库驱动
2.为应用创建相应的库和表
3.改造dao

4.改造service
5.使用工厂模式,即使底层换了,业务层一行代码也不用改

(因为DaoFactory是读取配置文件来产生DaoImpl的实例)

用到的第3方jar包

用到的第三方库
jaxen-1.1-beta-6.jar
jstl.jar    
standard.jar
dom4j-1.6.1.jar
commons-beanutils-1.8.0.jar 
commons-logging.jar
MySQL驱动:mysql-connector-java-5.0.8-bin.jar

UserDao位于dao包

package cn.itcast.dao;
import cn.itcast.domain.User;
public interface UserDao {
  //操作1,添加一个用户到数据库
  void add(User user);
  //操作2,登录时,校验用户名和密码,正确则返回该用户
  User find(String username, String password);
  //操作3,注册时,检验用户名是否已存在,返回布尔值
  boolean find(String username);
}
CopyOfUserDaoJdbcImpl位于dao.impl包
package cn.itcast.dao.impl;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import cn.itcast.dao.UserDao;
import cn.itcast.domain.User;
import cn.itcast.exception.DaoException;
import cn.itcast.utils.JdbcUtils;
/*
 改造数据库应用
1.导入数据库驱动
2.为应用创建相应的库和表
3.改造dao
<user id="8881" username="weixi" password="888" email="weixi@163.com" birthday="1990-09-09" nickname="潇湘妃子"/>
mysql -uroot -proot
set character_set_client=gb2312;
set character_set_results=gb2312;
create database day14_user;
use day14_user;
create table users
(
  id varchar(40) primary key,
  username varchar(40) not null unique,
  password varchar(40) not null,
  email varchar(100) not null unique,
  birthday date,
  nickname varchar(40) not null
);
show tables;
 */
public class CopyOfUserDaoJdbcImpl implements UserDao {
  //操作1,添加一个用户到数据库
  public void add(User user){
    Connection conn=null;
    Statement st=null;
    ResultSet rs=null;
    try {
      conn=JdbcUtils.getConnection();
      st=conn.createStatement();//preparedStatement
      String id=user.getId();
      String username=user.getUsername();
      String password=user.getPassword();
      String email=user.getEmail();
      String birthday=user.getBirthday().toLocaleString();
      String nickname=user.getNickname();
      String sql="insert into users(id,username,password,email,birthday,nickname) values('"+id+"','"+username+"','"+password+"','"+email+"','"+birthday+"','"+nickname+"')";
      int num=st.executeUpdate(sql);
      //反向推理,如果插入失败,抛异常
      if (num<1) {
      throw new RuntimeException("插入失败");
    }
    } catch (Exception e) {
        // 不能抛,转型,异常链不能断
      //为了方便问题出于哪一层,自定义DaoException(不能处理,继承运行时异常)
        throw new DaoException(e);
      }finally{
        JdbcUtils.release(conn, st, rs);
      }
  }
  //'or 1=1 or username='
  //select * from users where username=''or 1=1 or username='' and password=''
  //操作2,登录时,校验用户名和密码,正确则封装数据返回该用户
  public User find(String username,String password){
    Connection conn=null;
    Statement st=null;
    ResultSet rs=null;
    try {
        conn=JdbcUtils.getConnection();
      st=conn.createStatement();//preparedStatement
      String sql="select * from users where username='"+username+"' and password='"+password+"'";
      rs=st.executeQuery(sql);
      if (rs.next()) {
      //如果找到则将数据库中的数据封装到user对象返回该user对象
        User user=new User();
        user.setId(rs.getString("id"));
        user.setUsername(username);
        user.setPassword(password);
        user.setEmail(rs.getString("email"));
        user.setBirthday(rs.getDate("birthday"));
        user.setNickname(rs.getString("nickname"));
        return user;
      }
    //如果没找到则返回空
      return null;
    } catch (Exception e) {
        // 不能抛,转型,异常链不能断
       //为了方便问题出于哪一层,自定义DaoException(不能处理,继承运行时异常)
        throw new DaoException(e);
    }finally{
      JdbcUtils.release(conn, st, rs);
    }
  }
  //操作3,注册时,检验用户名是否已存在,返回布尔值
  public boolean find(String username){
    Connection conn=null;
    Statement st=null;
    ResultSet rs=null;
    try {
        conn=JdbcUtils.getConnection();
      st=conn.createStatement();//preparedStatement
      String sql="select * from users where username='"+username+"'";
      rs=st.executeQuery(sql);
        if (rs.next()) {
          return true;
        }
        return false;
    } catch (Exception e) {
       // 不能抛,转型,异常链不能断
       //为了方便问题出于哪一层,自定义DaoException(不能处理,继承运行时异常)
        throw new DaoException(e);
    }finally{
      JdbcUtils.release(conn, st, rs);
    }
  }
}
/*
select * from users where username=''or 1=1 or username='' and 
password=''
mysql -uroot -proot
set character_set_client=gb2312;
set character_set_results=gb2312;
use day14_user;
select * from users where username='' or 1=1 and password=''
select * from users where username='' or 1=1 or username='' and 
password=''
SQL注入:' or 1=1 or username='
*/
UserDaoJdbcImpl位于d ao.impl包
package cn.itcast.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import cn.itcast.dao.UserDao;
import cn.itcast.domain.User;
import cn.itcast.exception.DaoException;
import cn.itcast.utils.JdbcUtils;
/*
 改造数据库应用
1.导入数据库驱动
2.为应用创建相应的库和表
3.改造dao
<user id="8881" username="weixi" password="888" email="weixi@163.com" birthday="1990-09-09" nickname="潇湘妃子"/>
mysql -uroot -proot
set character_set_client=gb2312;
set character_set_results=gb2312;
create database day14_user;
use day14_user;
create table users
(
  id varchar(40) primary key,
  username varchar(40) not null unique,
  password varchar(40) not null,
  email varchar(100) not null unique,
  birthday date,
  nickname varchar(40) not null
);
show tables;*/
/*statment和preparedStatement的区别:
  1. preparedStatement是statement的孩子
  2. preparedStatement可以防止sql注入的问题
  3. preparedStatement会对sql语句进行预编译,以减轻数据库服务器的压力
  java---class---jvm
  sql----编译---数据库*/
public class UserDaoJdbcImpl implements UserDao {
  //操作1,添加一个用户到数据库
  public void add(User user){
    Connection conn=null;
    PreparedStatement st=null;
    ResultSet rs=null;
    try {
      conn=JdbcUtils.getConnection();
      //先准备String sql,再通过连接准备PreparedStatement
      String id=user.getId();
      String username=user.getUsername();
      String password=user.getPassword();
      String email=user.getEmail();
      java.util.Date birthday=user.getBirthday();
      String nickname=user.getNickname();
      String sql="insert into users(id,username,password,email,birthday,nickname) values(?,?,?,?,?,?)";
      st=conn.prepareStatement(sql);//preparedStatement
      //将占位符填充
      st.setString(1, id);
      st.setString(2, username);
      st.setString(3, password);
      st.setString(4, email);
      //需要将util.Date变成Long,再构造成sql.Date
      st.setDate(5, new java.sql.Date(birthday.getTime()));
      st.setString(6, nickname);
      //因为已经封装好了,直接用空参执行!
      int num=st.executeUpdate();
      //反向推理,如果插入失败,抛异常
      if (num<1) {
      throw new RuntimeException("插入失败");
    }
    } catch (Exception e) {
        // 不能抛,转型,异常链不能断
      //为了方便问题出于哪一层,自定义DaoException(不能处理,继承运行时异常)
        throw new DaoException(e);
      }finally{
        JdbcUtils.release(conn, st, rs);
      }
  }
  //'or 1=1 or username='
  //select * from users where username=''or 1=1 or username='' and password=''
  //操作2,登录时,校验用户名和密码,正确则封装数据返回该用户
  public User find(String username,String password){
    Connection conn=null;
    PreparedStatement st=null;
    ResultSet rs=null;
    try {
        conn=JdbcUtils.getConnection();
      String sql="select * from users where username=? and password=?";
      st=conn.prepareStatement(sql);//preparedStatement
      //将占位符替换掉!
      st.setString(1, username);
      st.setString(2, password);
    //因为PreparedStatement已经封装好了,直接用空参执行!
      rs=st.executeQuery();
      if (rs.next()) {
      //如果找到则将数据库中的数据封装到user对象返回该user对象
        User user=new User();
        user.setId(rs.getString("id"));
        user.setUsername(username);
        user.setPassword(password);
        user.setEmail(rs.getString("email"));
        user.setBirthday(rs.getDate("birthday"));
        user.setNickname(rs.getString("nickname"));
        return user;
      }
    //如果没找到则返回空
      return null;
    } catch (Exception e) {
        // 不能抛,转型,异常链不能断
       //为了方便问题出于哪一层,自定义DaoException(不能处理,继承运行时异常)
        throw new DaoException(e);
    }finally{
      JdbcUtils.release(conn, st, rs);
    }
  }
  //操作3,注册时,检验用户名是否已存在,返回布尔值
  public boolean find(String username){
    Connection conn=null;
    PreparedStatement st=null;
    ResultSet rs=null;
    try {
        conn=JdbcUtils.getConnection();
      String sql="select * from users where username=?";
      st=conn.prepareStatement(sql);//preparedStatement
    //将占位符替换掉!
      st.setString(1, username);
    //因为PreparedStatement已经封装好了,直接用空参执行!
      rs=st.executeQuery();
        if (rs.next()) {
          return true;
        }
        return false;
    } catch (Exception e) {
       // 不能抛,转型,异常链不能断
       //为了方便问题出于哪一层,自定义DaoException(不能处理,继承运行时异常)
        throw new DaoException(e);
    }finally{
      JdbcUtils.release(conn, st, rs);
    }
  }
}
/*
select * from users where username=''or 1=1 or username='' and 
password=''
mysql -uroot -proot
set character_set_client=gb2312;
set character_set_results=gb2312;
use day14_user;
select * from users where username='' or 1=1 and password=''
select * from users where username='' or 1=1 or username='' and 
password=''
SQL注入:' or 1=1 or username='
*/
UserDaoXmlImpl位于d ao.impl包
package cn.itcast.dao.impl;
import java.io.IOException;
import java.text.SimpleDateFormat;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import cn.itcast.dao.UserDao;
import cn.itcast.domain.User;
import cn.itcast.utils.XmlUtils;
public class UserDaoXmlImpl implements UserDao {
  //操作1,添加一个用户到数据库
  public void add(User user){
    try {
      Document doc= XmlUtils.getDocument();
      Element root=doc.getRootElement();
      Element user_tag=root.addElement("user");
      user_tag.setAttributeValue("id", user.getId());
      user_tag.setAttributeValue("username", user.getUsername());
      user_tag.setAttributeValue("password", user.getPassword());
      user_tag.setAttributeValue("email", user.getEmail());
      user_tag.setAttributeValue("birthday", user.getBirthday()==null?"":user.getBirthday().toLocaleString());
      user_tag.setAttributeValue("nickname", user.getNickname());
      XmlUtils.write2Xml(doc);
    } catch (Exception e) {
      // 不能抛,转型,异常链不能断
      throw new RuntimeException(e);
    }
  }
  //操作2,登录时,校验用户名和密码,正确则返回该用户
  public User find(String username,String password){
    try {
      Document doc= XmlUtils.getDocument();
      Element e= (Element) doc.selectSingleNode("//user[@username='"+username+"' and @password='"+password+"']");
      if (e==null) {
        return null;
      }
      //如果找到了,将xml中的数据封装到User里面返回
      User user=new User();
      user.setId(e.attributeValue("id"));
      user.setUsername(e.attributeValue("username"));
      user.setPassword(e.attributeValue("password"));
      user.setEmail(e.attributeValue("email"));
      user.setNickname(e.attributeValue("nickname"));
      //封装生日的时候,需分情况讨论
      String date=e.attributeValue("birthday");
      if (date==null || "".equals(date)) {
        user.setBirthday(null);
      } else {
        //注意大小写,含义不一样
        SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");
        user.setBirthday(df.parse(date));
      }
      return user;
    } catch (Exception e) {
      // 不能抛,转型,异常链不能断
      throw new RuntimeException(e);
    }
  }
  //操作3,注册时,检验用户名是否已存在,返回布尔值
  public boolean find(String username){
    try {
      Document doc= XmlUtils.getDocument();
      Element e= (Element) doc.selectSingleNode("//user[@username='"+username+"']");
      if (e==null) {
        return false;
      }
      return true;
    } catch (Exception e) {
      // 不能抛,转型,异常链不能断
      throw new RuntimeException(e);
    }
  }
}
User位于domain
package cn.itcast.domain;
import java.util.Date;
public class User {
  private String id;
  private String username;
  private String password;
  private String email;
  private Date   birthday; 
  private String nickname;
  public String getId() {
    return id;
  }
  public void setId(String id) {
    this.id = id;
  }
  public String getUsername() {
    return username;
  }
  public void setUsername(String username) {
    this.username = username;
  }
  public String getPassword() {
    return password;
  }
  public void setPassword(String password) {
    this.password = password;
  }
  public String getEmail() {
    return email;
  }
  public void setEmail(String email) {
    this.email = email;
  }
  public Date getBirthday() {
    return birthday;
  }
  public void setBirthday(Date birthday) {
    this.birthday = birthday;
  }
  public String getNickname() {
    return nickname;
  }
  public void setNickname(String nickname) {
    this.nickname = nickname;
  }
}
DaoException位于exception
package cn.itcast.exception;
public class DaoException extends RuntimeException {
	//自定义Dao异常,是为了定位错误出在哪一层方便!
	//运行时异常,继承RuntimeException,是不想给上层带来麻烦!
	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);
	}
}
UserExistException位于exception
package cn.itcast.exception;
public class UserExistException extends Exception {
	//继承Exception乃编译时异常,因为希望上层必须重视和处理这个情况!
  public UserExistException() {
  }
  public UserExistException(String message) {
    super(message);
  }
  public UserExistException(Throwable cause) {
    super(cause);
  }
  public UserExistException(String message, Throwable cause) {
    super(message, cause);
  }
  public UserExistException(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 {
/*23种设计模式之工厂模式!
 * 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){
    //配置文件中UserDao=cn.itcast.dao.impl.UserDaoJdbcImpl
    //String full_name=clazz.getName();//cn.itcast.dao.UserDao
    String simple_name=clazz.getSimpleName();//UserDao
    //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.UserDaoJdbcImpl()
      return dao;
    } catch (Exception e) {
      // 转型后抛出
      throw new RuntimeException(e);
    }
  }
}
BusinessServiceImpl位于service.impl
package cn.itcast.service.impl;
import cn.itcast.dao.UserDao;
import cn.itcast.domain.User;
import cn.itcast.exception.UserExistException;
import cn.itcast.factory.DaoFactory;
import cn.itcast.utils.ServiceUtils;
/*对web层提供所有的服务,
 * web层收到请求后,统一交给BusinessServiceImpl处理*/
public class BusinessServiceImpl {
  //private UserDao dao=new UserDaoJdbcImpl();//若要解耦需要工厂模式或spring
  private UserDao dao=DaoFactory.getInstance().createDao(UserDao.class);
  //服务1,提供注册服务
  public void register(User user) throws UserExistException{
     // 先检查用户名是否存在,如果存在抛编译时异常,让调用者知道!
    boolean b=dao.find(user.getUsername());
    if (b) {
      //如果存在,抛编译时异常(必须处理),让调用者(web层)知道(给友好提示)!
      throw new UserExistException();
    } else {
      //如果不存在,先将密码用工具类md5加密,然后将用户添加进数据库
      user.setPassword(ServiceUtils.md5(user.getPassword()));
      dao.add(user);
    }
  }
  //服务2,提供登录服务
  public User login(String username,String password){
    //注意查找时,要用加密后的密码找
    password=ServiceUtils.md5(password);
    //找不到返回null,找到了返回user
    return dao.find(username, password);
  }
}
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;
    }
  }
}
ServiceUtils位于utils
package cn.itcast.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import sun.misc.BASE64Encoder;
public class ServiceUtils {
  public static String md5(String message){
    /*工具类异常直接抛,异常链不能断
     * 提供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);
    }
  }
}
WebUtils位于utils
package cn.itcast.utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
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;
public class WebUtils {
  //方法1, 将表单中的数据封装到RegisterForm里面
  //使用字节码避免new 对象,使用泛形避免强转
  public static <T> T request2Bean(HttpServletRequest request,Class<T> beanClass){
    try{
      //1.实例化要封装数据的bean
      T bean = beanClass.newInstance();
      //2.用BeanUtils的方法把request中的数据封装到bean对象中
      Enumeration  e = request.getParameterNames();//参数列表
      while(e.hasMoreElements()){
        String name = (String) e.nextElement();   //username password email birthday
        String value = request.getParameter(name); 
        BeanUtils.setProperty(bean, name, value);
      }
      //3,返回封装了表单数据的RegisterForm对象
      return bean;
    }catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  //方法2, 将RegisterForm中的数据封装到User里面
  public static void copyBean(Object src,Object dest){
    //需要注册日期转换器
    //(将RegisterForm里的字符串转成User里的日期)
    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;
        }
        //设计转换格式
        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);
    } 
  }
  //方法3, 产生一个唯一的id(UUID.randomUUID().toString())
  public static String generateId(){
    return UUID.randomUUID().toString();
  }
}
XmlUtils位于utils
package cn.itcast.utils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class XmlUtils {
	//操作XML的精华之一!
  private static String filepath;
  static{
    filepath=XmlUtils.class.getClassLoader().getResource("users.xml").getPath();
  }
  public static Document getDocument() throws DocumentException{
    /*dom4j读取Document
     * 工具类有异常直接抛出去*/
    SAXReader reader=new SAXReader();
    Document document=reader.read(new File(filepath));
    return document;
  }
  public static void write2Xml(Document doc) throws IOException{
    //dom4j写入Xml
    OutputFormat format=OutputFormat.createPrettyPrint();
    format.setEncoding("UTF-8");
    XMLWriter writer=new XMLWriter(new FileOutputStream(filepath),format);
    writer.write(doc);
    writer.close();
  }
}
ImageServlet位于web.controller
package cn.itcast.web.controller;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ImageServlet extends HttpServlet {
  private static final int WIDTH=120;
  private static final int HEIGHT=30;
  private static final int IMAGETYPE=BufferedImage.TYPE_INT_RGB;
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    //内存里的图像
    BufferedImage image=new BufferedImage(WIDTH,HEIGHT,IMAGETYPE);
    Graphics g=image.getGraphics();
    //设置背景色
    setBackground(g);
    //设置边框
    setBorder(g);
    //设置干扰线
    setLine(g);
    //设置汉字,需要旋转,强转为Graphics2D
    String random=setCode((Graphics2D) g);
    //要在服务器也存一份
    request.getSession().setAttribute("s_checkcode", random);
    //设置不要缓存,告知是图片,并写给浏览器
    response.setDateHeader("expires", -1);
    response.setHeader("Cache-Control", "no-cache");
    response.setHeader("Prama", "no-cache");
    response.setContentType("image/jpeg");
    ImageIO.write(image, "jpg", response.getOutputStream());
  }
  private String setCode(Graphics2D g) {
    /*方法说明:
    *生成随机汉字如:林黛玉薛宝钗史湘云
    */
    g.setColor(Color.RED);
    g.setFont(new Font("宋体",Font.BOLD,20));
    StringBuffer sb=new StringBuffer();
    String base="\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740\u4e2a\u5730\u5230\u5927\u91cc\u8bf4\u5c31\u53bb\u5b50\u5f97\u4e5f\u548c\u90a3\u8981\u4e0b\u770b\u5929\u65f6\u8fc7\u51fa\u5c0f\u4e48\u8d77\u4f60\u90fd\u628a\u597d\u8fd8\u591a\u6ca1\u4e3a\u53c8\u53ef\u5bb6\u5b66\u53ea\u4ee5\u4e3b\u4f1a\u6837\u5e74\u60f3\u751f\u540c\u8001\u4e2d\u5341\u4ece\u81ea\u9762\u524d\u5934\u9053\u5b83\u540e\u7136\u8d70\u5f88\u50cf\u89c1\u4e24\u7528\u5979\u56fd\u52a8\u8fdb\u6210\u56de\u4ec0\u8fb9\u4f5c\u5bf9\u5f00\u800c\u5df1\u4e9b\u73b0\u5c71\u6c11\u5019\u7ecf\u53d1\u5de5\u5411\u4e8b\u547d\u7ed9\u957f\u6c34\u51e0\u4e49\u4e09\u58f0\u4e8e\u9ad8\u624b\u77e5\u7406\u773c\u5fd7\u70b9\u5fc3\u6218\u4e8c\u95ee\u4f46\u8eab\u65b9\u5b9e\u5403\u505a\u53eb\u5f53\u4f4f\u542c\u9769\u6253\u5462\u771f\u5168\u624d\u56db\u5df2\u6240\u654c\u4e4b\u6700\u5149\u4ea7\u60c5\u8def\u5206\u603b\u6761\u767d\u8bdd\u4e1c\u5e2d\u6b21\u4eb2\u5982\u88ab\u82b1\u53e3\u653e\u513f\u5e38\u6c14\u4e94\u7b2c\u4f7f\u5199\u519b\u5427\u6587\u8fd0\u518d\u679c\u600e\u5b9a\u8bb8\u5feb\u660e\u884c\u56e0\u522b\u98de\u5916\u6811\u7269\u6d3b\u90e8\u95e8\u65e0\u5f80\u8239\u671b\u65b0\u5e26\u961f\u5148\u529b\u5b8c\u5374\u7ad9\u4ee3\u5458\u673a\u66f4\u4e5d\u60a8\u6bcf\u98ce\u7ea7\u8ddf\u7b11\u554a\u5b69\u4e07\u5c11\u76f4\u610f\u591c\u6bd4\u9636\u8fde\u8f66\u91cd\u4fbf\u6597\u9a6c\u54ea\u5316\u592a\u6307\u53d8\u793e\u4f3c\u58eb\u8005\u5e72\u77f3\u6ee1\u65e5\u51b3\u767e\u539f\u62ff\u7fa4\u7a76\u5404\u516d\u672c\u601d\u89e3\u7acb\u6cb3\u6751\u516b\u96be\u65e9\u8bba\u5417\u6839\u5171\u8ba9\u76f8\u7814\u4eca\u5176\u4e66\u5750\u63a5\u5e94\u5173\u4fe1\u89c9\u6b65\u53cd\u5904\u8bb0\u5c06\u5343\u627e\u4e89\u9886\u6216\u5e08\u7ed3\u5757\u8dd1\u8c01\u8349\u8d8a\u5b57\u52a0\u811a\u7d27\u7231\u7b49\u4e60\u9635\u6015\u6708\u9752\u534a\u706b\u6cd5\u9898\u5efa\u8d76\u4f4d\u5531\u6d77\u4e03\u5973\u4efb\u4ef6\u611f\u51c6\u5f20\u56e2\u5c4b\u79bb\u8272\u8138\u7247\u79d1\u5012\u775b\u5229\u4e16\u521a\u4e14\u7531\u9001\u5207\u661f\u5bfc\u665a\u8868\u591f\u6574\u8ba4\u54cd\u96ea\u6d41\u672a\u573a\u8be5\u5e76\u5e95\u6df1\u523b\u5e73\u4f1f\u5fd9\u63d0\u786e\u8fd1\u4eae\u8f7b\u8bb2\u519c\u53e4\u9ed1\u544a\u754c\u62c9\u540d\u5440\u571f\u6e05\u9633\u7167\u529e\u53f2\u6539\u5386\u8f6c\u753b\u9020\u5634\u6b64\u6cbb\u5317\u5fc5\u670d\u96e8\u7a7f\u5185\u8bc6\u9a8c\u4f20\u4e1a\u83dc\u722c\u7761\u5174\u5f62\u91cf\u54b1\u89c2\u82e6\u4f53\u4f17\u901a\u51b2\u5408\u7834\u53cb\u5ea6\u672f\u996d\u516c\u65c1\u623f\u6781\u5357\u67aa\u8bfb\u6c99\u5c81\u7ebf\u91ce\u575a\u7a7a\u6536\u7b97\u81f3\u653f\u57ce\u52b3\u843d\u94b1\u7279\u56f4\u5f1f\u80dc\u6559\u70ed\u5c55\u5305\u6b4c\u7c7b\u6e10\u5f3a\u6570\u4e61\u547c\u6027\u97f3\u7b54\u54e5\u9645\u65e7\u795e\u5ea7\u7ae0\u5e2e\u5566\u53d7\u7cfb\u4ee4\u8df3\u975e\u4f55\u725b\u53d6\u5165\u5cb8\u6562\u6389\u5ffd\u79cd\u88c5\u9876\u6025\u6797\u505c\u606f\u53e5\u533a\u8863\u822c\u62a5\u53f6\u538b\u6162\u53d4\u80cc\u7ec6";
    int x=5;//首个汉字 偏离边框的距离
    for (int i = 0; i < 4; i++) {//生成4个汉字
      int degree=new Random().nextInt()%30;//-30~30度
      String ch=base.charAt(new Random().nextInt(base.length()))+"";
      sb.append(ch);
      g.rotate(degree*Math.PI/180, x, 20);//Graphics2D的方法
      g.drawString(ch, x, 20);
      g.rotate(-degree*Math.PI/180, x, 20);//写下个字前角度还原
      x+=30;//字宽20 间距为10
    }
    return sb.toString();
  }
  private void setLine(Graphics g) {
    g.setColor(Color.GREEN);
    for (int i = 0; i < 5; i++) {
      int x1=new Random().nextInt(WIDTH);
      int y1=new Random().nextInt(HEIGHT);
      int x2=new Random().nextInt(WIDTH);
      int y2=new Random().nextInt(HEIGHT);
      g.drawLine(x1, y1, x2, y2);//两个端点需在矩形框内
    }
  }
  private void setBorder(Graphics g) {
    g.setColor(Color.BLUE);
    g.drawRect(0, 0, WIDTH-1, HEIGHT-1);
  }
  private void setBackground(Graphics g) {
    g.setColor(Color.WHITE);
    g.fillRect(0, 0, WIDTH, HEIGHT);
  }
}

LoginServlet位于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.User;
import cn.itcast.service.impl.BusinessServiceImpl;
public class LoginServlet extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    BusinessServiceImpl service = new BusinessServiceImpl();
    User user = service.login(username, password);
    if(user!=null){
      //session中存入登录成功的标记
      request.getSession().setAttribute("user", user);
      //让用户登陆成功后,跳转首页
      //得到web应用所在目录day09
      String url=request.getContextPath();
      response.sendRedirect(url+ "/index.jsp");
      return;
    }
    request.setAttribute("message", "用户名或密码错误!!");
    request.getRequestDispatcher("/message.jsp").forward(request, response);
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doGet(request, response);
  }
}

LogoutServlet位于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 javax.servlet.http.HttpSession;
public class LogoutServlet extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    HttpSession session = request.getSession(false);
    if(session!=null){
      session.removeAttribute("user");
    }
    //注销成功,跳到全局消息显示页面,显示注销成功消息
    //并控制消息显示页面过3秒后跳转到首页
    //实用的跳转技术
    String url=request.getContextPath();//day04
    request.setAttribute("message", "注销成功,浏览器将在3秒后跳转至首页<meta http-equiv='refresh' content='3;url="+url+"/index.jsp'>");
    request.getRequestDispatcher("/message.jsp").forward(request, response);
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doGet(request, response);
  }
}
RegisterServlet位于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.User;
import cn.itcast.exception.UserExistException;
import cn.itcast.service.impl.BusinessServiceImpl;
import cn.itcast.utils.WebUtils;
import cn.itcast.web.formbean.RegisterForm;
public class RegisterServlet extends HttpServlet {
  //处理用户注册请求
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    //首先解决post提交上来的中文乱码问题
    request.setCharacterEncoding("UTF-8");
    //1.把表单数据封装到RegisterForm对象,对提交表单的字段进行合法性校验
    //注意要把服务器的验证码封装到RegisterForm,以供校验
    RegisterForm form=WebUtils.request2Bean(request, RegisterForm.class);
    String s_checkcode=(String) request.getSession().getAttribute("s_checkcode");
    form.setS_checkcode(s_checkcode);
    boolean b=form.validate();
    //2.如果校验失败,跳回到表单页面,回显校验失败信息
    if(!b){
      request.setAttribute("form", form);   
      request.getRequestDispatcher("/WEB-INF/jsp/register.jsp").forward(request, response);
      return;
    }
    //3.如果校验成功,则调用service处理注册请求
    //(将RegisterForm里面的字符数据全放到User里)
    User user=new User();
    WebUtils.copyBean(form, user);
    user.setId(WebUtils.generateId());
    BusinessServiceImpl service=new BusinessServiceImpl();
    try {
      service.register(user);
      //成功,跳转到网站的全局消息显示页
      //session中存入登录成功的标记
      request.getSession().setAttribute("user", user);
      String url=request.getContextPath();
      request.setAttribute("message", "恭喜您,注册成功!!浏览器将在3秒后跳转至首页<meta http-equiv='refresh' content='3;url="+url+"/index.jsp'>");
      request.getRequestDispatcher("/message.jsp").forward(request, response);
      return;
    } catch (UserExistException e) {
      //注册用户已存在则跳回到注册页面,显示注册用户已存在的消息
      form.getErrors().put("username", "注册的用户名已存在!!");
      request.setAttribute("form", form);
      request.getRequestDispatcher("/WEB-INF/jsp/register.jsp").forward(request, response);
      return;
    }catch(Exception e){
      //抓住其他的问题
      e.printStackTrace();
      request.setAttribute("message", "服务器出现未知错误!!!");
      request.getRequestDispatcher("/message.jsp").forward(request, response);
      return;
    }
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doGet(request, response);
  }
}
RegisterForm位于web.formbean

package cn.itcast.web.formbean;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
public class RegisterForm {
/*用一个类封装表单提交过来的数据
 * 表单提交过来全是String */
  private String username;
  private String password;
  private String password2;
  private String email;
  private String birthday;
  private String nickname;
  private String c_checkcode;
  private String s_checkcode;
// Map errors  保存所有校验不通过的错误消息
  private Map errors = new HashMap();
  public boolean validate(){
    //默认是真,只要有一个错误,flag为假
    boolean flag = true;
    //用户名不能为空,并且要是3-8位字母
    if(this.username==null || this.username.trim().equals("")){
      flag = false;
      errors.put("username", "用户名不能为空!");
    }else{
      if(!this.username.matches("[A-Za-z]{3,8}")){
        flag = false;
        errors.put("username", "用户名必须是3-8位字母!");
      }
    }
    //密码不能为空,并且是3-8位数字
    if(this.password==null || this.password.trim().equals("")){
      flag = false;
      errors.put("password", "密码不能为空!");
    }else{
      if(!this.password.matches("\\d{3,8}")){
        flag = false;
        errors.put("password", "密码必须是3-8位数字!");
      }
    }
    //确认密码不能为空,并且要和一次一致
    if(this.password2==null || this.password2.trim().equals("")){
      flag = false;
      errors.put("password2", "确认密码不能为空!");
    }else{
      if(!this.password.equals(this.password2)){
        flag = false;
        errors.put("password2", "两次密码必须一致!");
      }
    }
    //电子邮箱不能为空,并且要是一个格式合法的邮箱
    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", "邮箱格式错误!");
      }
    }
    /*生日可以为空,不为空时,必须要是一个日期
     * 不能用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", "日期格式不对!");
      }
    }
    //昵称不可以为空,并且要是汉字区间(\u4e00-\u9fa5)
    if(this.nickname==null || this.nickname.trim().equals("")){
      flag = false;
      errors.put("nickname", "昵称不能为空!");
    }else{  //[^\u4e00-\u9fa5]*
      if(!this.nickname.matches("^([\u4e00-\u9fa5]+)$")){
        flag = false;
        errors.put("nickname", "呢称必须是汉字!");
      }
    }
    //客户端提交的验证码不可以为空
    if(c_checkcode==null || this.c_checkcode.trim().equals("")){
      flag = false;
      errors.put("c_checkcode", "必须输入认证码!");
    }else{
      if(!this.c_checkcode.equals(this.s_checkcode)){
        flag = false;
        errors.put("c_checkcode", "认证码错误!");
      }
    }
    return flag;
  }
  public String getUsername() {
    return username;
  }
  public void setUsername(String username) {
    this.username = username;
  }
  public String getPassword() {
    return password;
  }
  public void setPassword(String password) {
    this.password = password;
  }
  public String getPassword2() {
    return password2;
  }
  public void setPassword2(String password2) {
    this.password2 = password2;
  }
  public String getEmail() {
    return email;
  }
  public void setEmail(String email) {
    this.email = email;
  }
  public String getBirthday() {
    return birthday;
  }
  public void setBirthday(String birthday) {
    this.birthday = birthday;
  }
  public String getNickname() {
    return nickname;
  }
  public void setNickname(String nickname) {
    this.nickname = nickname;
  }
  public String getC_checkcode() {
    return c_checkcode;
  }
  public void setC_checkcode(String c_checkcode) {
    this.c_checkcode = c_checkcode;
  }
  public String getS_checkcode() {
    return s_checkcode;
  }
  public void setS_checkcode(String s_checkcode) {
    this.s_checkcode = s_checkcode;
  }
  public Map getErrors() {
    return errors;
  }
  public void setErrors(Map errors) {
    this.errors = errors;
  }
}
LoginUIServlet位于web.UI

package cn.itcast.web.UI;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginUIServlet extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    //为用户转到登录页面login.jsp
    request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doGet(request, response);
  }
}

RegisterUIServlet位于web.UI

package cn.itcast.web.UI;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RegisterUIServlet extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    //为用户转到注册页面register.jsp
    request.getRequestDispatcher("/WEB-INF/jsp/register.jsp").forward(request, response);
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doGet(request, response);
  }
}
dao.properties位于src类目录下

UserDao=cn.itcast.dao.impl.UserDaoJdbcImpl
#UserDao=cn.itcast.dao.impl.UserDaoXmlImpl
db.properties位于src类目录下
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/day14_user?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
Users.xml位于src类目录下

<?xml version="1.0" encoding="UTF-8"?>
<users>
	<user id="95a08f25-ad11-4f69-8b37-65e21b809e50" username="tanchun" password="4QrcOUm6Wau+VuBX8g+IPg==" email="weixi@163.com" birthday="1990-09-09" nickname="探春"/>
</users>

index.jsp位于WebRoot目录下

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>网站首页</title>
  </head>
  <body>
  <c:if test="${user!=null}">
  欢迎您:${user.nickname }
  <a href="${pageContext.request.contextPath }/servlet/LogoutServlet">注销</a>
  </c:if>
  
  <c:if test="${user==null}">
  <a href="${pageContext.request.contextPath }/servlet/LoginUIServlet">登录</a>
  <a href="${pageContext.request.contextPath }/servlet/RegisterUIServlet">注册</a>
  </c:if>
总纲:  改造数据库应用
1.导入数据库驱动
2.为应用创建相应的库和表
3.改造dao
<user id="8881" username="weixi" password="888" email="weixi@163.com" birthday="1990-09-09" nickname="潇湘妃子"/>

mysql -uroot -proot
set character_set_client=gb2312;
set character_set_results=gb2312;
create database day14_user;
use day14_user;
create table users
(
	id varchar(40) primary key,
	username varchar(40) not null unique,
	password varchar(40) not null,
	email varchar(100) not null unique,
	birthday date,
	nickname varchar(40) not null
);
show tables;

  </body>
</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 }
  </body>
</html>
ShowCalendar.js位于WebRoot/js目录下(千万别放到WEB-INF)
// 日期选择
// 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;
}
login.jsp位于WebRoot/WEB-INF/JSP目录下

<%@ 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>
               <form action="${pageContext.request.contextPath }/servlet/LoginServlet" method="post">
          用户:<input type="text" name="username" />
           密码:<input type="password" name="password" />
                     <input type="submit" value="登陆" />
                     <input type="button" value="注册" οnclick="window.location.href='${pageContext.request.contextPath }/servlet/RegisterUIServlet'" />
               </form>
   </body>
</html>
register.jsp位于WebRoot/WEB-INF/JSP目录下

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!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>
</head>
<body>
      <h3>注册须知:</h3> 
      1:在本站注册的会员,必须遵守《互联网电子公告服务管理规定》,不得在本站发表诽谤他人,侵犯他人隐私,侵犯他人知识产权,传播病毒,政治言论,商业机密等信息。
    <form action="${pageContext.request.contextPath }/servlet/RegisterServlet" method="post">
    <table>
        <tr>
          <td >登陆帐号:</td>
          <td>
            <input  type="text" name="username" value="${form.username }">
            <span >${form.errors.username }</span>
          </td>
        </tr>
        <tr>
          <td >重复密码:</td>
          <td>
            <input  type="password" name="password" value="${form.password }">
            <span >${form.errors.password }</span>
          </td>
        </tr>
        <tr>
          <td >确认密码:</td>
          <td>
            <input  type="password" name="password2"  value="${form.password2 }">
            <span >${form.errors.password2 }</span>  
          </td>
        </tr>
        <tr>
          <td >电子邮箱:</td>
          <td>
            <input  type="text" name="email"  value="${form.email }">
            <span >${form.errors.email }</span>
          </td>
        </tr>
        <tr>
          <td >生日:</td>
          <td>
            <input  type="text" name="birthday" id="birthday" title="点击选择" onClick="showCalendar(this.id)" value="${form.birthday }">
            <span >${form.errors.birthday }</span>
          </td>
        </tr>
        <tr>
          <td >您的呢称:</td>
          <td>
            <input  type="text" name="nickname" value="${form.nickname }">
            <span >${form.errors.nickname }</span>  
          </td>
        </tr>
        <tr>
          <td >图片认证:</td>
          <td>
            <input  type="text" name="c_checkcode">
            <span >${form.errors.c_checkcode }</span>  
            <img src="${pageContext.request.contextPath }/servlet/ImageServlet" height="25px" width="120px" alt="看不清" style="cursor: hand;" οnclick="this.src=this.src+'?'+Math.random().toString().substr(2,3)">
          </td>
        </tr>
    </table>
      <span><input class="btn" type="reset" name="reset" value="重 置"></span>
      <span><input class="btn" type="submit" name="submit" value="注 册"></span>
    </form>
</body>
</html>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值