JSP+Servlet+JavaBean的一个注册登录小项目

遵守javaweb开发的MVC模式。

已知问题:

1.不能注册中文用户(并没有用pattern约束)

2.没有注册输入格式不对的提示,但是可以写入Map集合并且跳转到regist.jsp。点击注册后输入框清空,因为是转发所以地址栏没变正常。


问题已解决。

1.开始时注册用户名为中文的时候认为是账号密码错误无法登陆。原因是问题分析错误:LoginServlet.java类中写的是一个响应跳转,而实际是需要请求转发到login.jsp中的,而非仅仅跳转过去。并不是由于中文用户注册引起的。

 2.注册失败时没有提示的总是回抛出一个在com.aloha.domain.UserForm中找不到msg属性的异常。最后发现是由于存放异常信息的Map集合的set/get方法忘记添加了,抛出的异常。

3.BeanUtils的populate方法是可以校验日期是否越界的。如果越界会通过Exception 的对象抛出这个异常,将这个异常同样以一个错误的回显形式请求转发给regist.jsp个面,可以对应提示生日的不合常理问题,如2月30日。


 下面是问题代码,修改后的代码在网盘中:

https://pan.baidu.com/s/1UKnt1Ch27rompcONI4NdSQ

UserDao.java

package com.aloha.dao;

import com.aloha.domain.User;

/**
 * 这是用户数据库连接的接口
 * @author malaganguo
 *
 */
public interface UserDao {
	/**
	 * 添加用户信息
	 * @param user 用户对象
	 * @throws Exception 
	 */
	void addUser(User user) throws Exception;
	/**
	 * 在数据库中核对用户
	 * @param user
	 * @return
	 * @throws Exception
	 */
	User findUser(User user) throws Exception;
	/**
	 * 根据用户名查找用户是否存在
	 * @param name
	 * @return
	 */
	boolean findUserByName(String name);
}

UserDaoImpl.java

package com.aloha.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;

import javax.persistence.PrePersist;

import com.aloha.dao.UserDao;
import com.aloha.domain.User;
import com.aloha.utils.DBUtils;
/**
 * 这是数据库接口的实现类
 * @author malaganguo
 *
 */
public class UserDaoImpl implements UserDao{

	public void addUser(User user) throws Exception {
		Connection conn = null;
		PreparedStatement pstmt = null;
		try {
			conn = DBUtils.getConnection();
			pstmt = conn.prepareStatement("INSERT INTO users(username,PASSWORD,email,birthday) VALUES(?,?,?,?)");
			pstmt.setString(1, user.getUsername());
			pstmt.setString(2, user.getPassword());
			pstmt.setString(3, user.getEmail());
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			String date = sdf.format(user.getBirthday());
			pstmt.setString(4, date);
			
			System.out.println(pstmt.executeUpdate());//返回的是几行受影响的值
			
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("添加失败!");
		}finally{
			DBUtils.closeAll(null, pstmt, conn);
		}
	}

	public User findUser(User user) throws Exception {
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		User u = null;
		
		try {
			conn = DBUtils.getConnection();
			pstmt = conn.prepareStatement("SELECT * FROM users WHERE username=? AND PASSWORD=?");
			pstmt.setString(1, user.getUsername());
			pstmt.setString(2, user.getPassword());
			
			rs = pstmt.executeQuery();
			if(rs.next()){//如果返回的结果集中有值
				u =new User();
				u.setId(rs.getInt(1));
				u.setUsername(rs.getString(2));
				u.setPassword(rs.getString(3));
				u.setEmail(rs.getString(4));
				u.setBirthday(rs.getDate(5));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			DBUtils.closeAll(rs, pstmt, conn);
		}
		
		return u;
	}
	/**
	 * 如果当前用户名已存在,则返回true,否则返回false
	 */
	public boolean findUserByName(String name) {
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try {
			conn = DBUtils.getConnection();
			pstmt = conn.prepareStatement("SELECT * FROM users WHERE username=?");
			pstmt.setString(1, name);
			
			rs = pstmt.executeQuery();
			if(rs.next()){//如果这个名字存在
				return true;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			DBUtils.closeAll(rs, pstmt, conn);
		}
		return false;
	}

}

User.java

package com.aloha.domain;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable{
	private int id;
	private String username;
	private String password;
	private String email;
	private Date birthday;

	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 getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	
	
}

UserForm.java

package com.aloha.domain;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

public class UserForm {

	private int id;
	private String username;
	private String password;
	private String repassword;
	private String email;
	private String birthday;
	
	Map<String, String> msg = new HashMap<String, String>();
	/*用户名:必须输入,且3~8位的字母组成<br>
	密码:必须输入,3~8位的数组组成<br>
	确认密码:和密码保持一致<br>
	邮箱:必须输入,且要符合邮箱的格式<br>
	生日:必须输入,符合yyyy-MM-dd的格式<br>*/
	
	/**
	 * 这是一个规范输入的方法
	 * @return 符合规范返回true,不符合规范返回false
	 */
	public boolean validate(){
		
		if("".equals(username)){
			msg.put("username", "用户名不能为空!");
		}
		if("".equals(password)){
			msg.put("password", "密码不能为空!");
		}
		if(!repassword.equals(password)){
			msg.put("repassword", "两次密码不一致!");
		}
		if("".equals(email)){
			msg.put("email", "邮箱不能为空!");
		}else if(!email.matches("\\b^['_a-z0-9-\\+]+(\\.['_a-z0-9-\\+]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2}|aero|arpa|asia|biz|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|nato|net|org|pro|tel|travel|xxx)$\\b")){
			msg.put("email", "邮箱格式不正确!");
		}
		if("".equals(birthday)){
			msg.put("birthday", "生日不能为空!");
		}else {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			try {
				sdf.parse(birthday);
			} catch (ParseException e) {
				msg.put("birthday", "生日格式不正确!");
			}
		}
		//所有不符合规范的输入都将输入键入Map集合中。所以当完全符合规范的时候,msg是为null的。
		return msg.isEmpty();
		
	}
	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 getRepassword() {
		return repassword;
	}
	public void setRepassword(String repassword) {
		this.repassword = repassword;
	}
	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;
	}
	
	
}

UsersException.java

package com.aloha.exception;

public class UsersException extends Exception {

	/**
	 * 此类无参构造访问父类无参构造
	 */
	public UsersException() {
		super();
	}
	/**
	 * 以下都是子类有参构造访问父类
	 * @param message
	 * @param cause
	 */
	public UsersException(String message, Throwable cause) {
		super(message, cause);
	}

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

	public UsersException(Throwable cause) {
		super(cause);
	}

	
}

UsersExistException.java

package com.aloha.exception;
/**
 * 这是用户退出异常类
 * @author malaganguo
 *
 */
public class UsersExistException extends Exception {

	public UsersExistException() {
		super();
	}

	public UsersExistException(String message, Throwable cause) {
		super(message, cause);
	}

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

	public UsersExistException(Throwable cause) {
		super(cause);
	}

	
}

UserService.java

package com.aloha.service;

import com.aloha.domain.User;
import com.aloha.exception.UsersException;
import com.aloha.exception.UsersExistException;
/**
 * 这是根据用户需求写的接口
 * @author malaganguo
 *
 */
public interface UserService {
	/**
	 * 添加用户信息
	 * @param user
	 * @throws Exception
	 */
	void register(User user) throws Exception;
	/**
	 * 根据用户名和密码查找用户信息
	 * @param user
	 * @return
	 * @throws UsersException
	 */
	User login(User user) throws UsersException;
	
	public boolean findUserByName(String name) throws UsersExistException;
	
}

UserServiceImpl.java

package com.aloha.service.impl;

import com.aloha.dao.UserDao;
import com.aloha.dao.impl.UserDaoImpl;
import com.aloha.domain.User;
import com.aloha.exception.UsersExistException;
import com.aloha.service.UserService;

public class UserServiceImpl implements UserService {

	UserDao ud = new UserDaoImpl();
	
	public void register(User user) throws Exception {
		ud.addUser(user);
	}
	
	public User login(User user) {
		User u = null;
		try {
			u=ud.findUser(user);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return u;
	}

	public boolean findUserByName(String name) throws UsersExistException {
		boolean b = ud.findUserByName(name);
		if(b){
			throw new UsersExistException("此用户已存在");
		}
		return b;
	}
	

}

DBUtils.java

package com.aloha.utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle;

public class DBUtils {
	private static String driverClass;
	private static String url;
	private static String username; 
	private static String password;
	/**
	 * properties文件传值以及反射加载jdbc连接驱动
	 */
	static{
		ResourceBundle rb = ResourceBundle.getBundle("dbinfo");
		driverClass = rb.getString("driverClass");
		url = rb.getString("url");
		username = rb.getString("username");
		password = rb.getString("password");
		
		try {
			Class.forName(driverClass);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 这是简化后的创建获取连接的工具
	 * @return 获取到的连接对象
	 * @throws SQLException
	 */
	public static Connection getConnection() throws SQLException{
		return DriverManager.getConnection(url, username, password);
		
	}
	/**
	 * 这是关闭资源的工具
	 * @param rs 这是返回结果集对象
	 * @param stmt 这是执行SQL语句对象
	 * @param conn 这是获取连接对象
	 */
	public static void closeAll(ResultSet rs, Statement stmt, Connection conn){
		if(rs != null){
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			rs = null;
		}
		if(stmt != null){
			try {
				stmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			stmt = null;
		}
		if(conn != null){
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			conn = null;
		}
	}
}

LoginOutServlet.java

package com.aloha.web.servlet;

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 LoginOutServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.getSession().invalidate();//注销:销毁session
		
		response.sendRedirect(request.getContextPath()+"/index.jsp");
		
		//这样写就不会跳转
//		response.getWriter().write("注销成功,2秒后跳转到主页");
//		response.setHeader("refresh", "2;url="+request.getContextPath()+"/index.jsp");
	}

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

}

LoginServlet.java
 

package com.aloha.web.servlet;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

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

import org.apache.commons.beanutils.BeanUtils;

import com.aloha.domain.User;
import com.aloha.service.UserService;
import com.aloha.service.impl.UserServiceImpl;

public class LoginServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//服务器和客户端共同约定使用UTF-8编码格式
		response.setContentType("text/html;charset=UTF-8");
		User u = new User();
		
		try {
			BeanUtils.populate(u, request.getParameterMap());
			UserService us = new UserServiceImpl();
			User user = us.login(u); //重新创建对象,如果在数据库中查找不到,那么u就为空了
			
			if(user != null){
				request.getSession().setAttribute("user", u);//如果登录成功就把user对象放到session对象中
				request.getRequestDispatcher("/index.jsp").forward(request, response);
			}else{
				response.getWriter().write("用户名或者密码错误,2秒后跳转到主页!");
//				response.sendRedirect(request.getContextPath()+"/login.jsp");//如果登录失败跳回到登录页面
				response.setHeader("refresh", "2;url="+request.getContextPath()+"/login.jsp");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

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

}

RegServlet.java

package com.aloha.web.servlet;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;

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

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;

import com.aloha.domain.User;
import com.aloha.domain.UserForm;
import com.aloha.exception.UsersExistException;
import com.aloha.service.UserService;
import com.aloha.service.impl.UserServiceImpl;

public class RegServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		//验证操作
		UserForm uf = new UserForm();
		try {
			BeanUtils.populate(uf, request.getParameterMap());
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		if(!uf.validate()){//如果map集合不为空,说明格式有误
			request.setAttribute("uf", uf);
			System.out.println("map集合不为空");
			request.getRequestDispatcher("/regist.jsp").forward(request, response);
			System.out.println("已完成请求转发");
			return; //这个空的return语句可以让格式错误的表单不提交到服务器中,即下面的代码不执行了
		}
		//获取表单数据
		User u = new User();
		try {
			ConvertUtils.register(new DateLocaleConverter(), Date.class);//这里给提交的Date类型数据提供注册
			BeanUtils.populate(u, request.getParameterMap());//使用apache提供的Bean工具类获取表单数据,支持四类八种数据的转换,但是Date不包含在内,所以会报错
			
			//处理业务逻辑
			UserService us = new UserServiceImpl();
			us.findUserByName(u.getUsername());
			us.register(u);
			
		} catch (UsersExistException e) {
			request.setAttribute("error", "用户名已存在");
			request.getRequestDispatcher("/regist.jsp").forward(request, response);
		} catch (Exception e) {
			e.printStackTrace();
		}
		//分发转向
		response.getWriter().write("注册成功,1秒后进入主页。");
		response.setHeader("refresh", "1;url="+request.getContextPath()+"/index.jsp");

	}

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

}

dbinfo.properties

driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbctest
username=root
password=root

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name></display-name>
  <servlet>
    <servlet-name>RegServlet</servlet-name>
    <servlet-class>com.aloha.web.servlet.RegServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>com.aloha.web.servlet.LoginServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>LoginOutServlet</servlet-name>
    <servlet-class>com.aloha.web.servlet.LoginOutServlet</servlet-class>
  </servlet>






  <servlet-mapping>
    <servlet-name>RegServlet</servlet-name>
    <url-pattern>/servlet/regServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/servlet/loginServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>LoginOutServlet</servlet-name>
    <url-pattern>/servlet/loginOutServlet</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>
	<c:if test="${empty user }">
	<a href="login.jsp">登录</a>
	<a href="regist.jsp">注册</a>
  	</c:if>
  	<c:if test="${not empty user }">
  		欢迎你:${user.username } <a href="${pageContext.request.contextPath }/servlet/loginOutServlet">注销</a>
  	</c:if>
  </body>
</html>

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录页面</title>
</head>
<body>
	<form action="${pageContext.request.contextPath }/servlet/loginServlet" method="post">
		用户名:<input type="text" name="username" /><br/>
		密码:<input type="password" name="password" /><br/>
		<input type="submit" value="登录" />
	</form>
</body>
</html>

regist.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" 
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%-- 这里使用了EL表达式来给html标签的value传递真实的值,在输入框后面打印校验信息。因为EL表达式具有很强的容错能力,即找不到值就不打印,所以很方便 --%>
	<form action="${pageContext.request.contextPath }/servlet/regServlet" method="post">
		用户名:<input type="text" name="username" value="${uf[username] }">${uf[msg][username] }${error }<br/>
		密码:<input type="password" name="password">${uf[msg][password] }<br/>
		确认密码:<input type="password" name="repassword">${uf[msg][repassword] }<br/>
		邮箱:<input type="text" name="email" value="${uf[email] }">${uf[msg][email] }<br/>
		生日:<input type="text" name="birthday" value="${uf[birthday] }">${uf[msg][birthday] }<br/>
		<input type="submit" name="注册"><br/>
	</form>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/weixin_38930706/article/details/81368045