图书商城【4】

 我们先写网站的注册登录这一块功能,首先在domain包里先写User类,关于domain包给大家解释一下,在mvc结构里,domain是主控制层,对应数据库实体setter,getter和toString方法,为dao层做好准备。那么dao层又是干嘛的呢?dao层主要就是数据访问层,也就是操作表单,对数据进行访问,这里不会涉及复杂逻辑,主要就是对表的增删查改,完全根据domain的要求来查找数据,所以我们要对每个要操作的数据库定义一个dao,对具体操作定义一个方法说明。
讲完这些,我们开始写代码,domain里写的十分简单,就不做太多解释,不过需要注意的是我们在这个类下面加了一个注册验证,只要不符合验证,会在提交表单时进行提示。

package cn.itcast.estore.domain;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户表
 * 
 */
public class User implements Serializable{
	private int id;
	private String username;
	private String password; 
	private String nickname; 
	private String email; 
	private String role; 
	private int state; 
	private String activecode;
	private Timestamp updatetime;

	public int getId() {
		return id;
	}

	public void setId(int 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 getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getRole() {
		return role;
	}

	public void setRole(String role) {
		this.role = role;
	}

	public int getState() {
		return state;
	}

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

	public String getActivecode() {
		return activecode;
	}

	public void setActivecode(String activecode) {
		this.activecode = activecode;
	}

	public Timestamp getUpdatetime() {
		return updatetime;
	}

	public void setUpdatetime(Timestamp updatetime) {
		this.updatetime = updatetime;
	}

	public Map<String, String> validateRegist() {
		Map<String, String> map = new HashMap<String, String>();

		if (username == null || username.trim().isEmpty()) {
			map.put("username.message", "用户名不能为空");
		}

		if (password == null || password.trim().isEmpty()) {
			map.put("password.message", "密码不能为空");
		}

		if (nickname == null || nickname.trim().isEmpty()) {
			map.put("nickname.message", "昵称不能为空");
		}

		if (email == null || email.trim().isEmpty()) {
			map.put("email.message", "邮箱不能为空");
		}

		return map;
	}

}
写完domain,然后我们开始写Dao层里的UserDao
package cn.itcast.estore.dao;

import java.sql.SQLException;

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

import cn.itcast.estore.domain.User;
import cn.itcast.estore.utils.DataSourceUtils;
import cn.itcast.estore.utils.Md5Utils;

public class UserDao {

	// 添加用户操作
	public void addUser(User user) throws SQLException {
		// 1.创建QueryRunner
		QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
		// 2.执行sql语句
		// 默认用户role=user state=0 代表未激活
		String sql = "insert into users values(null,?,?,?,?,'user','0',?,null)";

		runner.update(sql, user.getUsername(), Md5Utils.md5(user.getPassword()), user.getNickname(), user.getEmail(),
				user.getActivecode());

	}

	public User findUserByActiveCode(String activecode) throws SQLException {
		// 1.创建QueryRunner
		QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
		// 2.执行sql语句
		String sql = "select * from users where activecode=?";
		return runner.query(sql, new BeanHandler<User>(User.class), activecode);

	}

	public void activeUserByActivecode(String activecode) throws SQLException {
		QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
		String sql = "update users set state=1 where activecode=?";
		runner.update(sql, activecode);
	}

	public User findUserByUserNameAndPassword(String username, String password) throws SQLException {
		// 1.创建QueryRunner
		QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());

		String sql = "select * from users where username=? and password=?";

		return runner.query(sql, new BeanHandler<User>(User.class), username, Md5Utils.md5(password));
	}
}
然后我们再到service包里写UserService,先定义好一个接口,在里面写都要实现哪些service
package cn.itcast.estore.service;

import cn.itcast.estore.domain.User;

public interface UserService {
	// 注册操作
	public void regist(User user) throws Exception;
	// 登录操作
	public User login(String username, String password) throws Exception;
	// 激活操作
	public void activeUser(String activecode) throws Exception;
}
写完接口后我们开始实现接口,有了前面的User和UserDao,接口实现便理所应当,
package cn.itcast.estore.service;

import java.sql.SQLException;

import javax.mail.MessagingException;
import javax.mail.internet.AddressException;

import cn.itcast.estore.dao.UserDao;
import cn.itcast.estore.domain.User;
import cn.itcast.estore.exception.ActiveUserException;
import cn.itcast.estore.exception.LoginException;
import cn.itcast.estore.exception.RegistException;
import cn.itcast.estore.utils.MailUtils;

public class UserServiceImpl implements UserService{

	// 注册功能
	public void regist(User user) throws RegistException {

		// 调用dao中添加用户操作的方法

		try {
			new UserDao().addUser(user);

			// 发送邮件操作
			String emailMsg = "注册成功,请在15分钟内<a href='http://localhost:8080/bookEstore/user?method=activeuser&activecode="
					+ user.getActivecode()
					+ "'>激活</a>,激活码是"
					+ user.getActivecode();
			MailUtils.sendMail(user.getEmail(), emailMsg);

		} catch (SQLException e) {
			throw new RegistException("注册失败");
		} catch (Exception e) {
			throw new RegistException("邮件发送失败");
		}
	}

	public void activeUser(String activecode) throws RegistException,
			ActiveUserException {

		// 调用一个dao中的方法,根据activecode查找用户
		UserDao dao = new UserDao();
		User user = null;
		try {
			user = dao.findUserByActiveCode(activecode);
		} catch (SQLException e) {
			throw new RegistException("根据激活码查找用户失败");
		}
		long time = System.currentTimeMillis() - user.getUpdatetime().getTime();

		if (time > 15 * 60 * 1000) {
			throw new ActiveUserException("激活码过期");
		}

		// 进行激活操作
		try {
			dao.activeUserByActivecode(activecode);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new ActiveUserException("激活失败");
		}

	}

	public User login(String username, String password) throws LoginException {
		UserDao dao = new UserDao();
		User user = null;
		try {
			user = dao.findUserByUserNameAndPassword(username, password);

			if (user == null) {
				throw new LoginException("用户名或密码不正确");
			}
			// 判断用户的状态。
			if (user.getState() == 0) {
				// 用户状态未激活,不能进行登录操作
				throw new LoginException("用户未激活");
			}

		} catch (SQLException e) {
			throw new LoginException("登录失败");
		}

		return user;
	}
}


最后我们开始写UserServlet,在UserServlet中首先我们得到请求参数,判断当前是什么操作,然后通过判断,执行相应操作所对应的方法。比如register方法,对应的就是注册操作。
接下来我们较为详细的说明一下注册操作的过程,在register.jsp及User部分已经写好了关于表单验证的操作,所以在servlet里,我们只要写一个验证码操作就可以了。验证码通过后,我们将请求对象全部封装到JavaBean中,然后进行服务器段的数据校验。封装激活码等操作。完成这些操作后调用UserService操作,完成注册操作。
package cn.itcast.estore.web.servlet;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.UUID;

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

import org.apache.commons.beanutils.BeanUtils;

import cn.itcast.estore.domain.User;
import cn.itcast.estore.exception.ActiveUserException;
import cn.itcast.estore.exception.LoginException;
import cn.itcast.estore.exception.RegistException;
import cn.itcast.estore.service.UserServiceImpl;

public class UserServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 得到请求参数method,判断当前是什么操作
		String method = request.getParameter("method");

		if ("login".equals(method)) { // 登录操作台
			login(request, response);
		} else if ("regist".equals(method)) { // 注册操作
			regist(request, response);
		} else if ("logout".equals(method)) {
			// 注销操作
			logout(request, response);
		} else if ("activeuser".equals(method)) {
			activecode(request, response);
		}

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

	// 激活用户操作
	public void activecode(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// 1.得到激活码
		String activecode = request.getParameter("activecode");

		// 2.调用UserService中的方法完成激活操作
		UserServiceImpl service = new UserServiceImpl();

		try {
			service.activeUser(activecode);
		} catch (RegistException e) {
			e.printStackTrace();

			response.getWriter().write(
					e.getMessage() + ",重新<a href='" + request.getContextPath()
							+ "/regist.jsp'>注册</a>");
			return;

		} catch (ActiveUserException e) {
			e.printStackTrace();
			response.getWriter().write(
					e.getMessage() + ",重新<a href='" + request.getContextPath()
							+ "/regist.jsp'>注册</a>");
			return;
		}

		response.getWriter().write(
				"用户激活成功,请<a href='" + request.getContextPath()
						+ "/index.jsp'>回首页</a>");
		return;
	}

	// 注销操作
	public void logout(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		request.getSession().invalidate(); // 销毁session

		Cookie cookie = new Cookie("autologin", "");
		cookie.setMaxAge(0);
		cookie.setPath("/");

		response.addCookie(cookie);

		response.sendRedirect(request.getContextPath() + "/index.jsp");

	}

	// 登录操作
	public void login(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 1.得到用户名与密码
		String username = request.getParameter("username");
		String password = request.getParameter("password");

		// 2.调用service中登录方法
		UserServiceImpl service = new UserServiceImpl();
		try {
			User user = service.login(username, password);

			if (user != null) {

				// 用户如果登录成功,判断是否勾选了记住用户名.
				String saveUsername = request.getParameter("remember");

				if ("on".equals(saveUsername)) {
					// 记住用户名
					Cookie cookie = new Cookie("saveusername",
							URLEncoder.encode(username, "utf-8")); // 存储utf-8码
					cookie.setMaxAge(7 * 24 * 60 * 60); // 可以记住7天
					cookie.setPath("/");
					response.addCookie(cookie);
				} else {
					Cookie cookie = new Cookie("saveusername",
							URLEncoder.encode(username, "utf-8")); // 存储utf-8码
					cookie.setMaxAge(0);
					cookie.setPath("/");
					response.addCookie(cookie);
				}

				// 自动登录
				String autologin = request.getParameter("autologin");

				if ("on".equals(autologin)) {
					// 勾选了自动登录,就将用户名与密码存储到cookie中.
					Cookie cookie = new Cookie("autologin", URLEncoder.encode(
							username, "utf-8") + "%itcast%" + password);
					cookie.setMaxAge(7 * 24 * 60 * 60);
					cookie.setPath("/");
					response.addCookie(cookie);
				} else {
					Cookie cookie = new Cookie("autologin", URLEncoder.encode(
							username, "utf-8") + "%itcast%" + password);
					cookie.setMaxAge(0);
					cookie.setPath("/");
					response.addCookie(cookie);
				}

				// 登录成功后,将用户存储到session中.
				request.getSession().invalidate();
				request.getSession().setAttribute("user", user);
				response.sendRedirect(request.getContextPath() + "/index.jsp");
				return;
			} else {
				request.setAttribute("login.message", "用户名或密码错误");
				request.getRequestDispatcher("/page.jsp").forward(request,
						response);
				return;
			}

		} catch (LoginException e) {
			e.printStackTrace();
			request.setAttribute("login.message", e.getMessage());
			request.getRequestDispatcher("/page.jsp")
					.forward(request, response);
			return;
		}
	}

	// 注册操作
	public void regist(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 验证码操作
		String checkcode = request.getParameter("checkcode");

		String _checkcode = (String) request.getSession().getAttribute(
				"checkcode_session");

		request.getSession().removeAttribute("checkcode_session");
		if (_checkcode == null || (!_checkcode.equals(checkcode))) {
			request.setAttribute("regist.message", "验证码不正确");
			request.getRequestDispatcher("/regist.jsp").forward(request,
					response);
			return;
		}

		// 1.得到请求参数,封装到javaBean中.
		User user = new User();
		try {
			BeanUtils.populate(user, request.getParameterMap());
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}

		// 进行服务器端数据校验
		Map<String, String> map = user.validateRegist();

		if (map.size() > 0) {
			// 说明有错误信息
			request.setAttribute("map", map);
			request.getRequestDispatcher("/regist.jsp").forward(request,
					response);
			return;
		}

		// 手动封装一个激活码
		user.setActivecode(UUID.randomUUID().toString());

		// 2.调用service操作

		UserServiceImpl service = new UserServiceImpl();

		try {
			service.regist(user);

			response.getWriter().write(
					"注册成功,激活后请<a href='" + request.getContextPath()
							+ "/index.jsp'>登录</a>");

		} catch (RegistException e) {
			request.setAttribute("regist.message", e.getMessage());
			request.getRequestDispatcher("/regist.jsp").forward(request,
					response);
			return;
		}

	}

}
登录,及激活功能与注册功能类似,就不再作太多介绍,不过再多说几句关于验证码,密码的事情,验证码是通过WEB-INF中的txt文档,然后经过utils包里的CheckImgServlet处理实现的,密码是通过MD5加密储存在数据库中,注册时候发送邮件用的也是工具类,我用的是搜狐邮箱,大家可以随便改那个MailUtil工具类(已经把密码删了,所以上传的那个工具类需要改为自己的邮箱账号及密码),最后提醒大家把邮箱设置里的STMP开启,要不可能会无法发送邮件。项目里面用到的一些util类,我直接给大家发布出来,大家都全部加到utils包里,方便以后直接使用。最后一个问题就是配置web.xml文件,写servlet时生成的默认url-pattern会和servlet-name一样,我们这个项目统一改为servlet-name的前面单词小写,如
  <servlet>
    <servlet-name>UserServlet</servlet-name>
    <servlet-class>cn.itcast.estore.web.servlet.UserServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>UserServlet</servlet-name>
    <url-pattern>/user</url-pattern>
  </servlet-mapping>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值