JavaWeb网上图书商城完整项目--day02-16.登录功能各层实现

/*1、第一步将用户提交的参数封装成javabean对象
*
*2、对提交的参数的进行合法性的校验
*
*3、通过用户名和密码去查找得到user对象
*如果user对象为null,说明用户名和密码不正确,重定向到login.jsp提示用户名和密码错误
*如果user对象不为null,查看当前用户的激活状态,如果当前用户没有被激活,提示当前用户没有被激活,重定向到login.jsp提示
*如果user对象不为null,并且当前用户处于激活状态,把当前用户保存到session中,显示当前用户是谁
*为了实现页面自定功能,需要把用户名保存到cookie中,主要cookie不支持中文,需要对
*中文进行有效性的处理。
*
*
*
* */

 

2、cookie解决中文乱码的问题

在学习当中碰到cookie中文乱码问题,问题原因:cookie对中文不太支持,将中文放入cookie中会报错误。

cookie中使用中文,使用URLEncoder进行编码

try {  
    Cookie cookie = new Cookie("animal",URLEncoder.encode("i love you -- ** 屎壳郎", "UTF-8"));  
    response.addCookie(cookie);  
      
} catch (UnsupportedEncodingException e) {  
    e.printStackTrace();  
}  

浏览器页面中使用cookie的时候使用URLEncoder进行解码

Cookie[] cs = request.getCookies();  
for(Cookie c : cs){  
    if(c.getName().equals("animal")){  
        try {  
            System.out.println(URLDecoder.decode(c.getValue(), "UTF-8"));  
        } catch (UnsupportedEncodingException e) {  
            e.printStackTrace();  
        }  
    }  
}  

 forward是服务器内部重定向,程序收到请求后重新定向到另一个程序,客户机并不知道;redirect则是服务器收到请求后发送一个状态头给客 户,客户将再请求一次,这里多了两次网络通信的来往。

forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.
我们来看看程序的代码:
dao数据层:
package com.weiyuan.goods.user.dao;

import java.sql.SQLException;

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

import com.weiyuan.goods.user.domian.User;

import cn.itcast.jdbc.TxQueryRunner;

public class UserDao {

     //操作数据库
    private TxQueryRunner qr = new TxQueryRunner();
    
    
    /***
     * 查询用户名是否存在
     * @throws SQLException 
     */
    public boolean ajaxValidateLoginName(String loginName) throws SQLException{
        //获得满足记录的数目是对象,返回一个整数,整数是单行单列使用ScalarHandler
        String sql ="select count(*) from t_user where loginname=?";
        Number num = (Number) qr.query(sql, new ScalarHandler(),loginName);
        int count = num.intValue();

        if(count>0){
            return true;
        }
        return false;
    }
    
    /***
     * 查询邮箱是否存在
     * @throws SQLException 
     */
    public boolean ajaxValidateEmail(String email) throws SQLException{
        //获得满足记录的数目是对象,返回一个整数,整数是单行单列使用ScalarHandler
        String sql ="select count(*) from t_user where email=?";
        Number num = (Number) qr.query(sql, new ScalarHandler(),email);
        int count = num.intValue();
        System.out.println("count="+count);
        if(count>0){
            return true;
        }
        return false;
    }
    
    /***
     * 添加注册的用户
     * @throws SQLException 
     */
    public void addUser(User user) throws SQLException{
        //获得满足记录的数目是对象,返回一个整数,整数是单行单列使用ScalarHandler
        String sql ="insert into  t_user values(?,?,?,?,?,?)";
        System.out.println("user="+user.toString());
        Object[] params = {user.getUid(),user.getLoginname(),user.getLoginpass(),
                user.getEmail(),user.getStatus(),user.getActivationCode()};
        qr.update(sql, params);
    }
    
    /*
     * 通过激活码获得用户
     * */
    public User findUserByActivationCode(String activationCode) throws SQLException{
        
        String sql = "select * from t_user where activationCode = ?";
        return qr.query(sql, new BeanHandler<User>(User.class),activationCode);
    }
    
    /*
     * 设置用户的激活状态
     * */
    
    public void setUserActivationCode(String uuid,int status) throws SQLException{
        String sql = "update t_user set status = ? where uid = ? ";
        qr.update(sql,status,uuid);
    }
    

    /*
     * 通过用户名和密码查找得到对应的用户
     * */
    
    public User findUserByLoginnameAndPass(String loginName,String pass) throws SQLException{
        String sql = "select * from t_user where loginname = ? and loginpass = ?";
        return qr.query(sql, new BeanHandler<User>(User.class),loginName,pass);        
    }
        
}

业务层的代码:

package com.weiyuan.goods.user.service;

import java.io.IOException;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.Properties;

import javax.mail.MessagingException;
import javax.mail.Session;
import javax.management.RuntimeErrorException;

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

import com.weiyuan.goods.user.dao.UserDao;
import com.weiyuan.goods.user.domian.User;

public class UserService {

 private UserDao dao = new UserDao();    
    
 
 public boolean ajaxValidateLoginName(String loginName) {
     
     try {
        return dao.ajaxValidateLoginName(loginName);
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        throw new RuntimeException(e.getMessage());
    }
     
 }
 
public boolean ajaxValidateEmail(String email) {
     
     try {
        return dao.ajaxValidateEmail(email);
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        throw new RuntimeException(e.getMessage());
    }
     
 }

//添加注册的用户
public void addUser(User user){
    //添加用户的uuid
    user.setUid(CommonUtils.uuid());
    //添加用户的激活码
    String activationCode = CommonUtils.uuid()+CommonUtils.uuid();
    user.setActivationCode(activationCode);
    //当前处于未激活的状态
    user.setStatus(0);//0表示未激活
    
    try {
        dao.addUser(user);
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        throw new RuntimeException(e.getMessage());
    }
    
    //向注册的用户发送邮件
     //1读取配置文件
      Properties properties = new Properties();
      try {
        properties.load(this.getClass().getClassLoader().getResourceAsStream("email_template.properties"));
    } catch (IOException e1) {
        throw new RuntimeException(e1.getMessage());
    }
    
    
     String host = properties.getProperty("host"); //qq邮箱发送邮件的地址,端口465或者587
        //qq接受邮件服务器的地址是pop.qq.com,端口995
        String username=properties.getProperty("username"); //登陆服务器的账号
        String password=properties.getProperty("password");//这里不是客户端登陆的密码,而是授权密码一定要注意
        Session session = MailUtils.createSession(host, username, password);
        //发送邮件
        String from = properties.getProperty("from");//发件人
        String to = user.getEmail();//收件人
        String title = properties.getProperty("subject");
        String content = properties.getProperty("content");
        Object [] array = new Object[]{user.getActivationCode()};   
        //替换占位符
        String formatContent = MessageFormat.format(content, user.getActivationCode());//替换占位符
        System.out.println("email content is:"+content);
        Mail mail = new Mail(from,to,title,formatContent);
        try {
            MailUtils.send(session, mail);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        } 
    
    
    
}

/*设置用户的激活状态*/

  public void activation(String activationCode) throws Exception{
      //1 、通过激活码查找对应的用户信息
      try {
        User user = dao.findUserByActivationCode(activationCode);
        if(user == null){
            throw new Exception("无效的激活码");//业务异常,业务失败
        }
        if(user.getStatus()== 1){
            throw new Exception("用户已经既激活,不要二次激活");//业务异常,业务失败
        }
        dao.setUserActivationCode(user.getUid(), 1); //1表示激活
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        throw new RuntimeException(e.getMessage()); // 不是业务的异常吗,而是电脑环境系统数据库的异常,直接退出线程,无法进行业务的操作了
    }
      
  }

  
  /*
   * 用户登录的业务操作,这里传递的参数是一个User对象
   * */
  
  public User login(User user){
      
      try {
        return dao.findUserByLoginnameAndPass(user.getLoginname(),user.getLoginpass());
    } catch (SQLException e) {
        throw new RuntimeException(e.getMessage());
    }
      
  }
  
  

}

Servlet层:

package com.weiyuan.goods.user.web.servlet;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.map.HashedMap;

import com.weiyuan.goods.user.domian.User;
import com.weiyuan.goods.user.service.UserService;

import cn.itcast.commons.CommonUtils;
import cn.itcast.servlet.BaseServlet;

/**
 * Servlet implementation class UserServlet
 */
@WebServlet("/UserServlet")
public class UserServlet extends BaseServlet{
    private static final long serialVersionUID = 1L;
    private UserService service = new UserService();
    /*
     * 用户注册页面使用ajax校验/*
     * 用户注册页面使用ajax校验用户名会调用该方法
     * *会调用该方法
     * */
    public String validateLoginname(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        //首先获得用户上传的用户名
        String loginName = request.getParameter("loginname");
        boolean  flag = service.ajaxValidateLoginName(loginName);
        response.getWriter().print(flag);
        return null;
    }
    /*
     * 用户注册页面使用ajax校验邮箱会调用该方法
     * */
    public String validateEmail(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
       //获得用户上传的emai
    
        String email = request.getParameter("email");
        System.out.println("validateEmail is called"+email);
        boolean  flag = service.ajaxValidateEmail(email);
        response.getWriter().print(flag);
        return null;
    }
    
    /*
     * 用户注册页面使用ajax校验验证码会调用该方法
     * */
    public String validateVerifyCode(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
         //获得用户上传的verfycode
        String verifyCode  = request.getParameter("verifyCode");
        //获得session中保存的验证码
        String sessionCode = (String) request.getSession().getAttribute("vCode");
        //二者进行比较看是否相等
        System.out.println("validateVerifyCode is called"+verifyCode+":"+sessionCode);
        boolean  flag = sessionCode.equalsIgnoreCase(verifyCode);
        response.getWriter().print(flag);
        return null;
    }
    
    /*
     * 当用户从邮箱点击的激活的时候会调用该方法,并且把激活码传递过来
     * 
     * */
    public String activation(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub

        String activationCode = request.getParameter("activationCode");
        System.out.println("email activationCode is :"+activationCode);
        try {
            service.activation(activationCode);
            //激活成功
             request.setAttribute("code", "success"); //msg.jsp已经code的值来显示错误信息还是正确的信息
             request.setAttribute("msg", "激活成功");
             return "f:/jsps/msg.jsp";
        } catch (Exception e) {
           //将业务操作的异常信息在msg.jsp中显示出来
            String msg = e.getMessage();
             request.setAttribute("code", "error"); //msg.jsp已经code的值来显示错误信息还是正确的信息
             request.setAttribute("msg", msg);
             return "f:/jsps/msg.jsp";
            
        }
        
    }
    
    
    /*
     * 当用户注册的时候会调用该方法
     * 
     * */
    public String regist(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        System.out.println("activation is called");
        
        //1、将请求的参数封装成User对象
                User user = CommonUtils.toBean(request.getParameterMap(), User.class);
                //2 、对传递过来的参数进行校验,把错误的信息封装到一个hashMap中
                  Map errors = validateParams(user, request);
                  if(errors.size() > 0){//说明参数错误,跳转到注册界面提示用户输入的参数有误
                      request.setAttribute("errors", errors);    
                      request.setAttribute("user", user);
                      return "f:/jsps/user/regist.jsp";
                  }
                 service.addUser(user);
                 request.setAttribute("code", "success");
                 request.setAttribute("msg", "用户注册成功,请马上到邮箱进行激活");
                  return "f:/jsps/msg.jsp";
          
    }
    
    
    /*
     * 当用户登录的时候会调用该方法
     * 
     * */
    public String login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        System.out.println("activation is called");
        
        /*1、第一步将用户提交的参数封装成javabean对象
         *
         *2、对提交的参数的进行合法性的校验
         *
         *3、通过用户名和密码去查找得到user对象
         *如果user对象为null,说明用户名和密码不正确,重定向到login.jsp提示用户名和密码错误
         *如果user对象不为null,查看当前用户的激活状态,如果当前用户没有被激活,提示当前用户没有被激活,重定向到login.jsp提示
         *如果user对象不为null,并且当前用户处于激活状态,把当前用户保存到session中,显示当前用户是谁
         *为了实现页面自定功能,需要把用户名保存到cookie中,主要cookie不支持中文,需要对
         *中文进行有效性的处理。
         *
         * 
         * 
         * */
        
        User formUser = CommonUtils.toBean(request.getParameterMap(), User.class);
        //对参数进行合法性的校验
        //2 、对传递过来的参数进行校验,把错误的信息封装到一个hashMap中
          Map errors = validateParams(formUser, request);
          if(errors.size() > 0){//说明参数错误,跳转到注册界面提示用户输入的参数有误
              request.setAttribute("errors", errors);    
              request.setAttribute("user", formUser);
              return "f:/jsps/user/login.jsp";
          }
          User user =service.login(formUser);
          
          //判断用户是否为null
          if(user == null){
              request.setAttribute("msg", "输入的用户名和密码不正确");
              request.setAttribute("user", formUser);
              return "f:/jsps/user/login.jsp";
          }else{
              if(0 == user.getStatus()){ //没有激活  
                  request.setAttribute("msg", "当前用户没有激活,请先激活该用户");
                  request.setAttribute("user", formUser);
                  return "f:/jsps/user/login.jsp"; 
              }
              //说明用户登录成功
              request.getSession().setAttribute("sessionUser", user);
              //将用户名保存到cookie中,因为cookie不支持中文使用URL进行编码
               Cookie cookie = new Cookie("cookieLoginName", URLEncoder.encode(user.getLoginname(), "utf-8"));
               cookie.setMaxAge(60*60*24);//cookie的有效期是一天
               //添加cookie对象,把cookier对象返回给浏览器
               response.addCookie(cookie);
               //登录成功之后客户端使用redict重新登录到index.jsp主页面
               return "r:/index.jsp";
               
          }
    }
    
    
    public Map validateParams(User user,HttpServletRequest request){
        Map<String, String> map  = new HashedMap();
        //校验用户名
        String loginName = user.getLoginname();
        if(loginName == null || loginName.isEmpty()){
            map.put("loginname", "用户名不能为空");
        }
        if(loginName.length() < 3 || loginName.length() > 20){
            map.put("loginname", "用户名长度应该在3到20之间");
        }
        //校验用户名是否注册
        if(service.ajaxValidateLoginName(loginName)){
            map.put("loginname", "用户名已经被注册");
        }
        
        //检查登陆密码
        String loginpass = user.getLoginpass();
        if(loginpass == null || loginpass.isEmpty()){
            map.put("loginpass", "登陆密码不能为空");
        }
        if(loginpass.length() < 3 || loginpass.length() > 20){
            map.put("loginname", "登陆密码的长度应该在3到20之间");
        }
        
        //检查确认密码的信息
        //检查登陆密码
        String reloginpass = user.getReloginpass();
        if(reloginpass == null || reloginpass.isEmpty()){
            map.put("reloginpass", "登陆密码不能为空");
        }
        if(reloginpass.length() < 3 || reloginpass.length() > 20){
            map.put("reloginpass", "登陆密码的长度应该在3到20之间");
        }
        if(!reloginpass.equalsIgnoreCase(loginpass)){
            map.put("reloginpass", "两次输入的密码不一样");
        }
        
        //检查邮箱
        String email = user.getEmail();
        if(email == null || email.isEmpty()){
            map.put("email", "登陆邮箱不能为空");
        }
        //检查邮箱的格式是否正确
        if(!email.matches("^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\\.[a-zA-Z0-9_-]{2,3}){1,2})$")){
            map.put("email", "邮箱格式不正确");
        }
        
        
        //检查验证码是否相等
        String verifyCode = user.getVerifyCode();
        //获得session中保存的验证码
        String sessionCode =(String) request.getSession().getAttribute("vCode");
        if(!verifyCode.equalsIgnoreCase(sessionCode)){
            map.put("verifyCode", "验证码不正确");
        }
        
        return map;
        
        
        
    }

    
    public Map validateLoginParams(User user,HttpServletRequest request){
        Map<String, String> map  = new HashedMap();
        //校验用户名
        String loginName = user.getLoginname();
        if(loginName == null || loginName.isEmpty()){
            map.put("loginname", "用户名不能为空");
        }
        if(loginName.length() < 3 || loginName.length() > 20){
            map.put("loginname", "用户名长度应该在3到20之间");
        }
                        
        //检查验证码是否相等
        String verifyCode = user.getVerifyCode();
        //获得session中保存的验证码
        String sessionCode =(String) request.getSession().getAttribute("vCode");
        if(!verifyCode.equalsIgnoreCase(sessionCode)){
            map.put("verifyCode", "验证码不正确");
        }
        
        return map;
        
        
        
    }

}

 

转载于:https://www.cnblogs.com/kebibuluan/p/6855396.html

这个网上书城系统使用Eclipse开发的,代码完整,jar包齐全,sql脚本包含在里面,将下载下来的项目导入到Eclipse中即可运行,本项目做了很多校验,对可能出现的bug做了考虑,属于比较完善的系统。本系统包含九个模块,前台模块分为:用户模快,分类模块,图书模块,购物车模块,订单模块;后台模块分为:管理员模块,分类管理模快,图书管理模快,订单管理模块。书城界面简洁,易于操作,简单易懂,代码均有注释,各模块功能完善。各大模块的功能描述:前台: 1). 用户模块功能有: * 用户注册: > 表单页面是jQuery做校验(包含了ajax异步请求) # 在输入框失去焦点时进行校验; # 在提交时对所有输入框进行校验; # 在输入框得到焦点时,隐藏错误信息。 > 表单页面使用一次性图形验证码; > 在servlet中再次做了表单校验。 * 用户登录: > 表单校验与注册功能相同; > 登录成功时会把当前用户名保存到cookie中,为了在登录页面的输入框中显示! * 用户退出:销毁session 2). 分类模块 * 查询所有分类: > 有1级和2级分类 > 在页面中使用手风琴式菜单(Javascript组件)显示分类。 3). 图书模块: * 按分类查询 * 按作者查询 * 按出版社查询 * 按书名模糊查询 * 多条件组合查询 * 按id查询 除按id查询外,其他都是分页查询。 技术难点: > 组合查询:根据多个条件拼凑sql语句。 > 带条件分页查询:条件可能会丢失。使用自定义的PageBean来传递分页数据! > 页面上的分页导航:页码列表的显示不好计算! 4). 购物车模块: * 添加条目 * 修改条目数量 * 删除条目 * 批量删除条目 * 我的购物车 * 查询被勾选条目 购物车没有使用sesson或cookie,而是存储到数据库中。 技术难点: > 添加条目时,如果两次添加针对同一本书的条目,不是添加,而是合并; > 修改数量时使用ajax时请求服务器端,服务器端返回json。 > 大量js代码 5). 订单模块: * 生成订单 * 我的订单 * 查看订单详细 * 订单支付 * 订单确认收货 * 取消订单 后台 1). 管理员 * 管理员登录 2). 分类管理 * 添加1级分类 * 添加2级分类: 需要为2级分类指定所属1级分类 * 编辑1级分类 * 编辑2级分类: 可以修改所属1级分类 * 删除1级分类: 存在子分类时,不能删除 * 删除2级分类: 当前2级分类下存在图书时不能删除 * 查看所有分类 3). 图书管理 * 各种查询:与前台相同 * 添加图书: > 上传图片 > 页面中使用动态下拉列表显示2级分类,当指定1级分类后,2级分类下拉列表中动态显示该1级分类下所有2级分类名称 * 修改图书: 与添加图书相似,也使用动态下拉列表 * 删除图书: 需要删除图书对应图片,再删除图书 4). 订单管理 * 各种查询 * 订单发货 * 订单取消
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值