基于javaweb的网上书城项目开发全过程之第一步:注册


注册是本项目的第一步,首先要分析注册的流程。

  第一步:创建用户相关类

      ** domain:User

     ** dao:UserDao

     ** service:UserService

    ** servlet:UserServlet

 注:包名习惯以:cn.域名.项目名.相关类名:如:cn.baidu.bookstore.domain.User

  第二步:用户注册流程如下图

    

第三步:用户激活功能如下图

 

 接下来就是代码的设计

    1、 建立相应的数据库,并建立以下几张表:

       

tb_user
tb_category
tb_book
tb_orders
tb_orderitem

表的架构如下

  

 

 

2、导包

   数据库用c3p0连接池链接,所以需要用到和c3p0相关的包

       c3p0-0.9.2-pre1.jar,这是核心包,其依赖包为:mchange-commons-0.2.jar ,还有mysql-connector-java-5.1.28-bin.jar  驱动架包

  当然还需要commons-dbutils这样的工具包,方便我们设计;commons-beanutils-1.8.3.jar创建javabean的工具包,其依赖包commons-logging-1.1.1.jar

 项目需要发送邮件激活注册,与javamail相关的包有:mail.jar,activation.jar。同时用要用到ajax相关的包,由于包比较多,这里不再一一列出

  导入配置文件,c3p0配置文件如下:

    

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <c3p0-config>
 3     <!-- 默认配置0~1 -->
 4     <default-config> 
 5         <property name="jdbcUrl">jdbc:mysql://localhost:3306/数据库名</property>
 6         <property name="driverClass">com.mysql.jdbc.Driver</property>
 7         <property name="user">root</property>
 8         <property name="password">数据库密码</property>
 9         
10         <property name="acquireIncrement">3</property>
11         <property name="initialPoolSize">10</property>
12         <property name="minPoolSize">2</property>
13         <property name="maxPoolSize">10</property>
14     </default-config>>
15 </c3p0-config>

为了以后便于把邮件发送人修改,我统一把与邮件有关的设置在一个配置文件中。代码如下:

  

host=smtp.qq.com    //主机,采用qq邮箱的服务器
uname=邮箱(不带后面的@qq.com)
pwd=邮箱的密码
from=邮箱的全部名称
subject=\u8FD9\u662F\u6765\u81EAYouth\u7F51\u4E0A\u4E66\u57CE\u7684\u6FC0\u6D3B\u90AE\u4EF6  //主题,这里已经转码了
content=<a href\="http\://localhost/bookstore/UserServlet?method\=active&code\={0}">\u70B9\u51FB\u8FD9\u91CC\u5B8C\u6210\u6FC0\u6D3B</a>  激活链接

3、创建包。

   关于注册界面,需要创建如下包和类

    com.youth.bookstore.user.domain---->User(javabean类),这是User的领域对象类,其中的字段必须要数据库对应,包括uid,uname,password,email,code,state

    com.youth.bookstore.user.Dao --->UserDao,这是User持久层

   com.youth.bookstore.user.service --->UserService和UserException类,前者为业务层,后者为继承了exception的异常类,用于抛出异常信息

   com.youth.bookstore.user.web.servlet --->UserServlet,这是User的表述层

 

这是MVC设计模式,就是把表述层、业务层、数据层分开,这样做的好处是有利于以后的移植,同时表述层值依赖于业务层,业务层值只依赖于持久层,持久层与数据库打交道,极大的减少了各类之间的耦合度。

 4、类的设计

   1、UserDao类必须具备五个方法.

      1、User findByUsername(String name)  //通过用户名查找用户

      2、User findByEmail(String name)    //通过email查找用户

      3、void add(User user)    //添加用户

      4、 User findByCode(String code)  //通过激活码来查找用户

      5、void updateState(String uid,boolean state)  //更新用户状态,用户已激活,则其state为true,,否则为false

  2、UserService类的设计

      1、void regist(User form) throws UserException  //用户注册,如果用户名以及邮箱已被注册,则抛出UserException异常,否则在数据库中添加注册

           UserException类为自己写的类,继承自Exception。

      2、void active(String code) throws UserException //用户激活,首先查看用户的激活状态,如果已经激活或激活码不存在,则抛出异常

  3、UserServlet类的设计

      1、激活方法

      2、注册方法

每个类的具体代码如下:

   1、UserDao.java

package com.youth.bookstore.user.dao;

import java.sql.SQLException;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import cn.itcast.jdbc.TxQueryRunner;

import com.youth.bookstore.user.domain.User;

/**
 * User持久层
 * @author 11937
 *
 */
public class UserDao {
   private QueryRunner qr = new TxQueryRunner(); 
   
   /**
    * 按用户名查询
    * @param username
    * @return
    */
   public User findByUsername(String username){
       try {
        String sql = "select * from tb_user where username=?";
        return qr.query(sql, new BeanHandler<User>(User.class),username);
    } catch (SQLException  e) {
        throw new RuntimeException(e);
    }
   }
   
   /**
    * 按用户邮箱查询
    * @param email
    * @return
    */
   public User findByEmail(String email){
       try {
        String sql = "select * from tb_user where email=?";
        return qr.query(sql, new BeanHandler<User>(User.class),email);
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
   }
   
   /**
    * 添加用户
    * @param user
    */
   public void add(User user){
      try {
        String sql = "insert into tb_user values(?,?,?,?,?,?)";
        Object[] params = {user.getUid(),user.getUsername(),
                user.getPassword(),user.getEmail(),
                user.getCode(),user.isState()};
        qr.update(sql, params);
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }  
   }
  
   /**
    * 按激活码查询
    * @param code
    * @return
    */
   public User findByCode(String code){
       try {
        String sql = "select * from tb_user where code=?";
        return qr.query(sql, new BeanHandler<User>(User.class),code);
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
   }
   
   /**
    * 更新用户激活状态信息
    * @param uid
    * @param state
    */
   public void updateState(String uid,boolean state){
       try {
         String sql = "update tb_user set state=? where uid=?";
         qr.update(sql, state,uid);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
   }
   
}

 

  2、UserService.java

  

package com.youth.bookstore.user.service;

import com.youth.bookstore.user.dao.UserDao;
import com.youth.bookstore.user.domain.User;

/**
 * User业务层
 * @author 11937
 *
 */
public class UserService {
  private UserDao userDao = new UserDao();
  
  /**
   * 注册功能
   * @param user
 * @throws UserException 
   */
  public void regist(User form) throws UserException{
      User user = userDao.findByUsername(form.getUsername());
      if(user != null) throw new UserException("用户名已被注册");
      user = userDao.findByEmail(form.getEmail());
      if(user != null) throw new UserException("邮箱已被注册");
      userDao.add(form); 
  }
  
  /*
   * 激活功能
   */
  public void active(String code) throws UserException{
     /*
      * 1、使用code查询数据库 ,得到user
      */
      User user = userDao.findByCode(code);
      /*
       * 2、校验,如果user不存在,抛异常
       */
      if(user == null) throw new UserException("激活码无效!");
      /*
       * 3、再次校验,用户是否已经激活
       */
      if(user.isState()) throw new UserException("您已经激活过了,请直接登录!");
      /*
       * 4、激活成功
       */
      userDao.updateState(user.getUid(), true);
  }
  
  
}

  3、UserException.java

  

package com.youth.bookstore.user.service;

public class UserException extends Exception{

	public UserException() {
		super();
		// TODO Auto-generated constructor stub
	}

	public UserException(String message) {
		super(message);
	}
   
}

    4、 UserServlet.java

package com.youth.bookstore.user.web.servlet;



import java.io.IOException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.mail.MessagingException;
import javax.mail.Session;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.itcast.commons.CommonUtils;
import cn.itcast.mail.Mail;
import cn.itcast.mail.MailUtils;
import cn.itcast.servlet.BaseServlet;

import com.youth.bookstore.user.domain.User;
import com.youth.bookstore.user.service.UserException;
import com.youth.bookstore.user.service.UserService;
 /**
  * User表述层
  * @author 11937
  *
  */
public class UserServlet extends BaseServlet {
  private UserService userService = new UserService();

  /**
   * 激活功能
   * @param request
   * @param response
   * @return
   * @throws ServletException
   * @throws IOException
   */

public String active(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
     /*
      * 1、获取参数激活码
      * 2、调用service方法激活
      *   > 保存异常信息到request域,转发到msg.jsp
      * 3、保存成功信息到request域,转发到msg.jsp
      */
      String code = request.getParameter("code");
      try {
          userService.active(code);
          request.setAttribute("msg", "恭喜,您已激活成功,请赶快登录吧!");
        } catch (UserException e) {
          request.setAttribute("msg", e.getMessage());
        }     
          return "f:/jsps/msg.jsp";
  }
  /**
   * 注册功能
   * @param request
   * @param response
   * @return
   * @throws ServletException
   * @throws IOException
   */

public String regist(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
   /*
    * 1.封装表单数据到form对象中
    * 2.补全uid、code
    * 3、输入校验
    *   >保存错误信息、form到request域,转发到regist.jsp
    * 4、调用service方法完成注册
    *   >保存错误信息、form到request域,转发到regist.jsp
    * 5、发邮件
    * 6、保存成功信息转发到regist.jsp
    */
    //封装表单数据
    User form = CommonUtils.toBean(request.getParameterMap(), User.class);
    //补全
    form.setUid(CommonUtils.uuid());
    form.setCode(CommonUtils.uuid() + CommonUtils.uuid());
    /*输入校验
     *   1.创建一个map,用来封装错误信息
     */
    Map<String,String> errors = new HashMap<String,String>();
    String username = form.getUsername();
    if(username == null || username.trim().isEmpty()){
        errors.put("username", "用户名不能为空");
    }else if(username.length() < 3 || username.length() >10){
        errors.put("username", "用户名长度必须在3~10之间");
    }
    
    String password = form.getPassword();
    if(password == null || password.trim().isEmpty()){
        errors.put("password", "密码不能为空");
    }else if(password.length() < 3 || password.length() >10){
        errors.put("password", "密码长度必须在3~10之间! ");
    }
    
    String email = form.getEmail();
    if(email == null || email.trim().isEmpty()){
        errors.put("email", "邮箱不能为空");
    }else if(!email.matches("\\w+@\\w+\\.\\w+")){
        errors.put("email", "Email格式错误 ");
    } 
    
    /*
     * 3、判断是否存在错误信息
     */
    if(errors.size() > 0){
        //保存错误信息
        //保存表单数据
        //转发至regist.jsp
       request.setAttribute("errors", errors);
       request.setAttribute("form", form);
       return "f:/jsps/user/regist.jsp";
    }
    
    /*
     * 调用service的regist方法
     */
    try {
        userService.regist(form);
    } catch (UserException e) {
        //保存错误信息
        //保存表单数据
        //转发至regist.jsp
        request.setAttribute("msg", e.getMessage());
        request.setAttribute("form", form);
        return "f:/jsps/user/regist.jsp";
    }
    /*
     * 说明userService执行成功
    */
    
    /*
     * 发送邮件
     *  准备配置文件
     */
    //获取配置文件内容
     Properties props = new Properties();
     props.load(this.getClass().getClassLoader().
             getResourceAsStream("email_template.properties"));
     String host = props.getProperty("host"); //获取主机
     String uname = props.getProperty("uname"); //获取用户名
     String pwd = props.getProperty("pwd");
     String from = props.getProperty("from");
     String to = form.getEmail();  //获取发件人
     String subject = props.getProperty("subject");
     String content = props.getProperty("content");  //获取邮件内容
     //{0}为占位符的格式
     //MessageFormat.format('{0}或者{1}出错','name','password')
     content = MessageFormat.format(content,form.getCode()); //替换{0}
     Session session = MailUtils.createSession(host, uname, pwd);
     Mail mail = new Mail(from,to,subject,content);
     try{
     MailUtils.send(session, mail);
     } catch(Exception e){
        throw new RuntimeException(e); 
     }
     /*  1、保存成功信息
     *  2、转发到msg.jsp
     */
    request.setAttribute("msg", "恭喜,注册成功!请马上到邮箱激活 ");
    return "f:/jsps/msg.jsp";
 }
}

   5、User.java

  

package com.youth.bookstore.user.domain;

/**
 * User的领域对象
 * 
 * @author 11937
 * 
 */
public class User {
    /**
     * 对应数据库
     */
    private String uid; // 主键
    private String username;
    private String password;
    private String email;
    private String code; // 激活码
    private boolean state; // 激活状态

    public String getUid() {
        return uid;
    }

    public void setUid(String uid) {
        this.uid = uid;
    }

    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 String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public boolean isState() {
        return state;
    }

    public void setState(boolean state) {
        this.state = state;
    }

    public User(String uid, String username, String password, String email,
            String code, boolean state) {
        super();
        this.uid = uid;
        this.username = username;
        this.password = password;
        this.email = email;
        this.code = code;
        this.state = state;
    }

    @Override
    public String toString() {
        return "User [uid=" + uid + ", username=" + username + ", password="
                + password + ", email=" + email + ", code=" + code + ", state="
                + state + "]";
    }

    public User() {
        super();
    }
}

   6、数据库建立如下:

   

CREATE DATABASE bookstore;

/*用户表*/
CREATE TABLE tb_user(
  uid CHAR(32) PRIMARY KEY,/*主键*/
  username VARCHAR(50) NOT NULL,/*用户名*/
  `password` VARCHAR(50) NOT NULL,/*密码*/
  email VARCHAR(50) NOT NULL,/*邮箱*/
  `code` CHAR(64) NOT NULL,/*激活码*/
  state BOOLEAN/*用户状态,有两种是否激活*/
);

SELECT * FROM tb_user;

/*分类*/
CREATE TABLE category (
  cid CHAR(32) PRIMARY KEY,/*主键*/
  cname VARCHAR(100) NOT NULL/*分类名称*/
);

INSERT  INTO category(cid,cname) VALUES ('1','JavaSE');
INSERT  INTO category(cid,cname) VALUES ('2','JavaEE');
INSERT  INTO category(cid,cname) VALUES ('3','Javascript');

SELECT * FROM category;

/*图书表*/
CREATE TABLE book (
  bid CHAR(32) PRIMARY KEY,/*主键*/
  bname VARCHAR(100),/*图书名*/
  price DECIMAL(5,1),/*单价*/
  author VARCHAR(20),/*作者*/
  image VARCHAR(200),/*图片*/
  cid CHAR(32),/*所属分类*/
  FOREIGN KEY (cid) REFERENCES category(cid)/*建立主外键关系*/
);

INSERT  INTO book VALUES ('1','Java编程思想(第4版)','75.6','qdmmy6','book_img/9317290-1_l.jpg','1');
INSERT  INTO book VALUES ('2','Java核心技术卷1','68.5','qdmmy6','book_img/20285763-1_l.jpg','1');
INSERT  INTO book VALUES ('3','Java就业培训教程','39.9','张孝祥','book_img/8758723-1_l.jpg','1');
INSERT  INTO book VALUES ('4','Head First java','47.5','(美)塞若','book_img/9265169-1_l.jpg','1');
INSERT  INTO book VALUES ('5','JavaWeb开发详解','83.3','孙鑫','book_img/22788412-1_l.jpg','2');
INSERT  INTO book VALUES ('6','Struts2深入详解','63.2','孙鑫','book_img/20385925-1_l.jpg','2');
INSERT  INTO book VALUES ('7','精通Hibernate','30.0','孙卫琴','book_img/8991366-1_l.jpg','2');
INSERT  INTO book VALUES ('8','精通Spring2.x','63.2','陈华雄','book_img/20029394-1_l.jpg','2');
INSERT  INTO book VALUES ('9','Javascript权威指南','93.6','(美)弗兰纳根','book_img/22722790-1_l.jpg','3');

SELECT * FROM book;

/*订单表*/
CREATE TABLE orders (
  oid CHAR(32) PRIMARY KEY,/*主键*/
  ordertime DATETIME,/*订单生成时间*/
  total DECIMAL(10,0),/*订单合计*/
  state SMALLINT(1),/*订单状态:未付款、已付款但未发货、已发货但未确认收货、收货已结束*/
  uid CHAR(32),/*订单的主人*/
  address VARCHAR(200),/*订单的收货地址*/
  FOREIGN KEY (uid) REFERENCES tb_user(uid)/*建立主外键关系*/
);

SELECT * FROM orders;

/*订单项表*/
CREATE TABLE orderitem (
  iid CHAR(32) PRIMARY KEY,/*主键*/
  `count` INT,/*数量*/orderitem
  subtotal DECIMAL(10,0),/*小计*/
  oid CHAR(32),/*所属订单*/
  bid CHAR(32),/*订单项所指的商品*/
  FOREIGN KEY (oid) REFERENCES orders (oid),/*建立主外键关系*/
  FOREIGN KEY (bid) REFERENCES book (bid)/*建立主外键关系*/
);

SELECT * FROM orderitem;

   

   总结:在设计过程中,有一个问题我几乎弄了一个下午,就是我在发送邮件的时候,邮箱服务器指定为stmp.qq.com时,用qq邮箱给其他邮箱发邮件时,如果发给对方的是qq邮箱,对方可以接收到邮件,但是无法打开设定的超链接,我查看了它的源码,在相应位置处,确实是一个a标签,同时链接也并有错误,单独把链接复制过来去访问,则可以成功。我用此qq邮箱给163邮箱发送邮件,163邮箱可以直接点开链接。后来我又用163邮箱给qq发送邮件,发现根本无法连接163服务器,我确认已经登录网页163邮箱,打开了了 POP3/SMTP/IMAP,但是依旧没有解决此问题,希望看到这篇博客的博友,如果好的解决方案,请分享到下面,感激不尽。

   写于2015-12-18  21:22:16。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM