JavaWeb实现用户登录注册功能实例代码(基于Servlet+JSP+JavaBean模式)

下面通过通过图文并茂的方式给大家介绍JavaWeb实现用户登录注册功能实例代码,一起看看吧。

一、Servlet+JSP+JavaBean开发模式(MVC)介绍

  Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp负责数据显示,javabean负责封装数据。 Servlet+JSP+JavaBean模式程序各个模块之间层次清晰,web开发推荐采用此种模式。

  这里以一个最常用的用户登录注册程序来讲解Servlet+JSP+JavaBean开发模式,通过这个用户登录注册程序综合案例,把之前的学过的XML、Xpath、Servlet、jsp的知识点都串联起来。

二、创建MVC架构的Web项目

  在MyEclipse中新创建一个webmvcframework项目,导入项目所需要的开发包(jar包),创建项目所需要的包,在java开发中,架构的层次是以包的形式体现出来的

项目所需要的开发包(jar包)
序号 开发包名称 描述
1 dom4j-1.6.1.jar dom4j用于操作XML文件
2 jaxen-1.1-beta-6.jar 用于解析XPath表达式
3 commons-beanutils-1.8.0.jar 工具类,用于处理bean对象
4 commons-logging.jar commons-beanutils-1.8.0.jar的依赖jar包
5 jstl.jar jstl标签库和EL表达式依赖包
6 standard.jar jstl标签库和EL表达式依赖包

一个良好的JavaWeb项目架构应该具有以上的11个包,这样显得层次分明,各个层之间的职责也很清晰明了,搭建JavaWeb项目架构时,就按照上面的1~11的序号顺序创建包:domain→dao→dao.impl→service→service.impl→web.controller→web.UI→web.filter→web.listener→util→junit.test,包的层次创建好了,项目的架构也就定下来了,当然,在实际的项目开发中,也不一定是完完全全按照

项目所需要的包
序号 包名 描述 所属层次
1 me.gacl.domain 存放系统的JavaBean类(只包含简单的属性以及属性对应的get和set方法,不包含具体的业务处理方法),提供给【数据访问层】、【业务处理层】、【Web层】来使用  domain(域模型)层
2 me.gacl.dao 存放访问数据库的操作接口类 数据访问层
3 me.gacl.dao.impl 存放访问数据库的操作接口的实现类
4 me.gacl.service 存放处理系统业务接口类 业务处理层
5 me.gacl.service.impl 存放处理系统业务接口的实现类
6 me.gacl.web.controller 存放作为系统控制器的Servlet Web层(表现层)
7 me.gacl.web.UI 存放为用户提供用户界面的servlet(UI指的是user interface)
8 me.gacl.web.filter 存放系统的用到的过滤器(Filter)
9 me.gacl.web.listener 存放系统的用到的监听器(Listener)
10 me.gacl.util 存放系统的通用工具类,提供给【数据访问层】、【业务处理层】、【Web层】来使用  
11 junit.test 存放系统的测试类

上面说的来创建包的层次结构,而是根据项目的实际情况,可能还需要创建其

他的包,这个得根据项目的需要来定了

  在src目录(类目录)下面,创建用于保存用户数据的xml文件(DB.xml)

  在WEB-INF目录下创建一个pages目录,pages目录存放系统的一些受保护(不允许用户直接通过URL地址访问)的jsp页面,用户要想访问这些受保护的jsp页面,那么只能通过me.gacl.web.UI这个包里面的Servlet

  创建好的项目如下图(图-1)所示:

  

                图-1

三、分层架构的代码编写

  分层架构的代码也是按照【域模型层(domain)】→【数据访问层(dao、dao.impl)】→【业务处理层(service、service.impl)】→【表现层(web.controller、web.UI、web.filter、web.listener)】→【工具类(util)】→【测试类(junit.test)】的顺序进行编写的。

3.1、开发domain层

  在me.gacl.domain包下创建一个User类

  

  User类具体代码如下:

package me.gacl.domain;
import java.io.Serializable;
import java.util.Date;
/**
* @author gacl
* 用户实体类
*/
public class User implements Serializable {
private static final long serialVersionUID = -L;
// 用户ID
private String id;
// 用户名
private String userName;
// 用户密码
private String userPwd;
// 用户邮箱
private String email;
// 用户生日
private Date birthday;
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 getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
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;
}
}

3.2、开发数据访问层(dao、dao.impl)

  在me.gacl.dao包下创建一个IUserDao接口类,对于开发接口类,我习惯以字母I作类的前缀,这样一眼就看出当前这个类是一个接口,这也算是一种良好的开发习惯吧,通过看类名就可以方便区分出是接口还是具体的实现类。

  

  IUserDao接口的具体代码如下:

package me.gacl.dao;
import me.gacl.domain.User;
public interface IUserDao {
/**
* 根据用户名和密码来查找用户
* @param userName
* @param userPwd
* @return 查到到的用户
*/
User find(String userName, String userPwd);
/**
* 添加用户
* @param user
*/
void add(User user);
/**根据用户名来查找用户
* @param userName
* @return 查到到的用户
*/
User find(String userName);
}

  对于接口中的方法定义,这个只能是根据具体的业务来分析需要定义哪些方法了,但是无论是多么复杂的业务,都离不开基本的CRUD(增删改查)操作,Dao层是直接和数据库交互的,所以Dao层的接口一般都会有增删改查这四种操作的相关方法。

  在me.gacl.dao.impl包下创建一个UserDaoImpl类

  

  UserDaoImpl类是IUserDao接口的具体实现类,对于接口的实现类命名方式,我习惯以"接口名(去除前缀I)+impl"形式或者"接口名+impl"形式来命名:IUserDao(接口)→UserDaoImpl(实现类)或者IUserDao(接口)→IUserDaoImpl(实现类),这也算是一些个人的编程习惯吧,平时看到的代码大多数都是以这两种形式中的一种来来命名接口的具体实现类的,反正就是要能够一眼看出接口对应的实现类是哪一个就可以了。

  UserDaoImpl类的具体代码如下:

package me.gacl.dao.impl;
import java.text.SimpleDateFormat;
import org.domj.Document;
import org.domj.Element;
import me.gacl.dao.IUserDao;
import me.gacl.domain.User;
import me.gacl.util.XmlUtils;
/**
* IUserDao接口的实现类
* @author gacl
*/
public class UserDaoImpl implements IUserDao {
@Override
public User find(String userName, String userPwd) {
try{
Document document = XmlUtils.getDocument();
//使用XPath表达式来操作XML节点
Element e = (Element) document.selectSingleNode("//user[@userName='"+userName+"' and @userPwd='"+userPwd+"']");
if(e==null){
return null;
}
User user = new User();
user.setId(e.attributeValue("id"));
user.setEmail(e.attributeValue("email"));
user.setUserPwd(e.attributeValue("userPwd"));
user.setUserName(e.attributeValue("userName"));
String birth = e.attributeValue("birthday");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
user.setBirthday(sdf.parse(birth));
return user;
}catch (Exception e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("deprecation")
@Override
public void add(User user) {
try{
Document document = XmlUtils.getDocument();
Element root = document.getRootElement();
Element user_node = root.addElement("user"); //创建user结点,并挂到root
user_node.setAttributeValue("id", user.getId());
user_node.setAttributeValue("userName", user.getUserName());
user_node.setAttributeValue("userPwd", user.getUserPwd());
user_node.setAttributeValue("email", user.getEmail());
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
user_node.setAttributeValue("birthday", sdf.format(user.getBirthday()));
XmlUtils.writeXml(document);
}catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public User find(String userName) {
try{
Document document = XmlUtils.getDocument();
Element e = (Element) document.selectSingleNode("//user[@userName='"+userName+"']");
if(e==null){
return null;
}
User user = new User();
user.setId(e.attributeValue("id"));
user.setEmail(e.attributeValue("email"));
user.setUserPwd(e.attributeValue("userPwd"));
user.setUserName(e.attributeValue("userName"));
String birth = e.attributeValue("birthday");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
user.setBirthday(sdf.parse(birth));
return user;
}catch (Exception e) {
throw new RuntimeException(e);
}
}
}

3.3、开发service层(service层对web层提供所有的业务服务)

  在me.gacl.service包中创建IUserService接口类

    IUserService接口的具体代码如下:

package me.gacl.service;
import me.gacl.domain.User;
import me.gacl.exception.UserExistException;
public interface IUserService {
/**
* 提供注册服务
* @param user
* @throws UserExistException
*/
void registerUser(User user) throws UserExistException;
/**
* 提供登录服务
* @param userName
* @param userPwd
* @return
*/
User loginUser(String userName, String userPwd);
}

  在me.gacl.service.impl包中创建UserServiceImpl类 

  UserServiceImpl类为IUserService接口的具体实现类,具体代码如下:

package me.gacl.service.impl;
import me.gacl.dao.IUserDao;
import me.gacl.dao.impl.UserDaoImpl;
import me.gacl.domain.User;
import me.gacl.exception.UserExistException;
import me.gacl.service.IUserService;
public class UserServiceImpl implements IUserService {
private IUserDao userDao = new UserDaoImpl();
@Override
public void registerUser(User user) throws UserExistException {
if (userDao.find(user.getUserName())!=null) {
//checked exception
//unchecked exception
//这里抛编译时异常的原因:是我想上一层程序处理这个异常,以给用户一个友好提示
throw new UserExistException("注册的用户名已存在!!!");
}
userDao.add(user);
}
@Override
public User loginUser(String userName, String userPwd) {
return userDao.find(userName, userPwd);
}
}

3.4、开发web层

3.4.1、 开发注册功能

    1、在me.gacl.web.UI包下写一个RegisterUIServlet为用户提供注册界面  

  RegisterUIServlet收到用户请求后,就跳到register.jsp

  RegisterUIServlet的代码如下:

package me.gacl.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;
/**
* @author gacl
* 为用户提供注册的用户界面的Servlet
* RegisterUIServlet负责为用户输出注册界面
* 当用户访问RegisterUIServlet时,就跳转到WEB-INF/pages目录下的register.jsp页面
*/
public class RegisterUIServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/pages/register.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}

2、在/WEB-INF/pages/目录下编写用户注册的jsp页面register.jsp

    

    凡是位于WEB-INF目录下的jsp页面是无法直接通过URL地址直接访问的,

    

    在开发中如果项目中有一些敏感web资源不想被外界直接访问,那么可以考虑将这些敏感的web资源放到WEB-INF目录下,这样就可以禁止外界直接通过URL来访问了。

  register.jsp页面的代码如下:

<%@ page language="java" pageEncoding="UTF-"%>
<!DOCTYPE HTML>
<html>
<head>
<title>用户注册</title>
</head>
<body style="text-align: center;">
<form action="${pageContext.request.contextPath}/servlet/RegisterServlet" method="post">
<table width="%" border="">
<tr>
<td>用户名</td>
<td>
<input type="text" name="userName">
</td>
</tr>
<tr>
<td>密码</td>
<td>
<input type="password" name="userPwd">
</td>
</tr>
<tr>
<td>确认密码</td>
<td>
<input type="password" name="confirmPwd">
</td>
</tr>
<tr>
<td>邮箱</td>
<td>
<input type="text" name="email">
</td>
</tr>
<tr>
<td>生日</td>
<td>
<input type="text" name="birthday">
</td>
</tr>
<tr>
<td>
<input type="reset" value="清空">
</td>
<td>
<input type="submit" value="注册">
</td>
</tr>
</table>
</form>
</body>
</html>

  register.jsp中的<form action="${pageContext.request.contextPath}/servlet/RegisterServlet" method="post">指明表单提交后,交给RegisterServlet进行处理

3、在me.gacl.web.controller包下编写用于处理用户注册的RegisterServlet

    RegisterServlet担任着以下几个职责:

  1、接收客户端提交到服务端的表单数据。

2、校验表单数据的合法性,如果校验失败跳回到register.jsp,并回显错误信息。

  3、如果校验通过,调用service层向数据库中注册用户。

    为了方便RegisterServlet接收表单数据和校验表单数据,在此我设计一个用于校验注册表单数据RegisterFormbean,再写WebUtils工具类,封装客户端提交的表单数据到formbean中。

  在me.gacl.web.formbean包下创建一个用于校验注册表单数据RegisterFormbean

  

  RegisterFormbean代码如下:

package me.gacl.web.formbean;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
/**
* 封装的用户注册表单bean,用来接收register.jsp中的表单输入项的值
* RegisterFormBean中的属性与register.jsp中的表单输入项的name一一对应
* RegisterFormBean的职责除了负责接收register.jsp中的表单输入项的值之外还担任着校验表单输入项的值的合法性
* @author gacl
*
*/
public class RegisterFormBean {
//RegisterFormBean中的属性与register.jsp中的表单输入项的name一一对应
//<input type="text" name="userName"/>
private String userName;
//<input type="password" name="userPwd"/>
private String userPwd;
//<input type="password" name="confirmPwd"/>
private String confirmPwd;
//<input type="text" name="email"/>
private String email;
//<input type="text" name="birthday"/>
private String birthday;
/**
* 存储校验不通过时给用户的错误提示信息
*/
private Map<String, String> errors = new HashMap<String, String>();
public Map<String, String> getErrors() {
return errors;
}
public void setErrors(Map<String, String> errors) {
this.errors = errors;
}
/*
* validate方法负责校验表单输入项
* 表单输入项校验规则:
* private String userName; 用户名不能为空,并且要是-的字母 abcdABcd
* private String userPwd; 密码不能为空,并且要是-的数字
* private String confirmPwd; 两次密码要一致
* private String email; 可以为空,不为空要是一个合法的邮箱
* private String birthday; 可以为空,不为空时,要是一个合法的日期
*/
public boolean validate() {
boolean isOk = true;
if (this.userName == null || this.userName.trim().equals("")) {
isOk = false;
errors.put("userName", "用户名不能为空!!");
} else {
if (!this.userName.matches("[a-zA-Z]{,}")) {
isOk = false;
errors.put("userName", "用户名必须是-位的字母!!");
}
}
if (this.userPwd == null || this.userPwd.trim().equals("")) {
isOk = false;
errors.put("userPwd", "密码不能为空!!");
} else {
if (!this.userPwd.matches("\\d{,}")) {
isOk = false;
errors.put("userPwd", "密码必须是-位的数字!!");
}
}
// private String password; 两次密码要一致
if (this.confirmPwd != null) {
if (!this.confirmPwd.equals(this.userPwd)) {
isOk = false;
errors.put("confirmPwd", "两次密码不一致!!");
}
}
// private String email; 可以为空,不为空要是一个合法的邮箱
if (this.email != null && !this.email.trim().equals("")) {
if (!this.email.matches("\\w+@\\w+(\\.\\w+)+")) {
isOk = false;
errors.put("email", "邮箱不是一个合法邮箱!!");
}
}
// private String birthday; 可以为空,不为空时,要是一个合法的日期
if (this.birthday != null && !this.birthday.trim().equals("")) {
try {
DateLocaleConverter conver = new DateLocaleConverter();
conver.convert(this.birthday);
} catch (Exception e) {
isOk = false;
errors.put("birthday", "生日必须要是一个日期!!");
}
}
return isOk;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
public String getConfirmPwd() {
return confirmPwd;
}
public void setConfirmPwd(String confirmPwd) {
this.confirmPwd = confirmPwd;
}
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;
}
}

  在me.gacl.util包下创建一个WebUtils工具类,该工具类的功能就是封装客户端提交的表单数据到formbean中

package me.gacl.util;
import java.util.Enumeration;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.beanutils.BeanUtils;
/**
* @author gacl
* 把request对象中的请求参数封装到bean中
*/
public class WebUtils {
/**
* 将request对象转换成T对象
* @param request
* @param clazz
* @return
*/
public static <T> T requestBean(HttpServletRequest request,Class<T> clazz){
try{
T bean = clazz.newInstance();
Enumeration<String> e = request.getParameterNames();
while(e.hasMoreElements()){
String name = (String) e.nextElement();
String value = request.getParameter(name);
BeanUtils.setProperty(bean, name, value);
}
return bean;
}catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 生成UUID
* @return
*/
public static String makeId(){
return UUID.randomUUID().toString();
}
}

  最后看一下负责处理用户注册的RegisterServlet完整代码:

package me.gacl.web.controller;
import java.io.IOException;
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 me.gacl.domain.User;
import me.gacl.exception.UserExistException;
import me.gacl.service.IUserService;
import me.gacl.service.impl.UserServiceImpl;
import me.gacl.util.WebUtils;
import me.gacl.web.formbean.RegisterFormBean;
/**
* 处理用户注册的Servlet
* @author gacl
*
*/
public class RegisterServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//将客户端提交的表单数据封装到RegisterFormBean对象中
RegisterFormBean formbean = WebUtils.requestBean(request,RegisterFormBean.class);
//校验用户注册填写的表单数据
if (formbean.validate() == false) {//如果校验失败
//将封装了用户填写的表单数据的formbean对象发送回register.jsp页面的form表单中进行显示
request.setAttribute("formbean", formbean);
//校验失败就说明是用户填写的表单数据有问题,那么就跳转回register.jsp
request.getRequestDispatcher("/WEB-INF/pages/register.jsp").forward(request, response);
return;
}
User user = new User();
try {
// 注册字符串到日期的转换器
ConvertUtils.register(new DateLocaleConverter(), Date.class);
BeanUtils.copyProperties(user, formbean);//把表单的数据填充到javabean中
user.setId(WebUtils.makeId());//设置用户的Id属性
IUserService service = new UserServiceImpl();
//调用service层提供的注册用户服务实现用户注册
service.registerUser(user);
String message = String.format(
"注册成功!!秒后为您自动跳到登录页面!!<meta http-equiv='refresh' content=';url=%s'/>",
request.getContextPath()+"/servlet/LoginUIServlet");
request.setAttribute("message",message);
request.getRequestDispatcher("/message.jsp").forward(request,response);
} catch (UserExistException e) {
formbean.getErrors().put("userName", "注册用户已存在!!");
request.setAttribute("formbean", formbean);
request.getRequestDispatcher("/WEB-INF/pages/register.jsp").forward(request, response);
} catch (Exception e) {
e.printStackTrace(); // 在后台记录异常
request.setAttribute("message", "对不起,注册失败!!");
request.getRequestDispatcher("/message.jsp").forward(request,response);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}

  用户注册时如果填写的表单数据校验不通过,那么服务器端就将一个存储了错误提示消息和表单数据的formbean对象存储到request对象中,然后发送回register.jsp页面,因此我们需要在register.jsp页面中取出request对象中formbean对象,然后将用户填写的表单数据重新回显到对应的表单项上面,将出错时的提示消息也显示到form表单上面,让用户知道是哪些数据填写不合法!

  修改register.jsp页面,代码如下:

<%@ page language="java" pageEncoding="UTF-"%>
<!DOCTYPE HTML>
<html>
<head>
<title>用户注册</title>
</head>
<body style="text-align: center;">
<form action="${pageContext.request.contextPath}/servlet/RegisterServlet" method="post">
<table width="%" border="">
<tr>
<td>用户名</td>
<td>
<%--使用EL表达式${}提取存储在request对象中的formbean对象中封装的表单数据(formbean.userName)以及错误提示消息(formbean.errors.userName)--%>
<input type="text" name="userName" value="${formbean.userName}">${formbean.errors.userName}
</td>
</tr>
<tr>
<td>密码</td>
<td>
<input type="password" name="userPwd" value="${formbean.userPwd}">${formbean.errors.userPwd}
</td>
</tr>
<tr>
<td>确认密码</td>
<td>
<input type="password" name="confirmPwd" value="${formbean.confirmPwd}">${formbean.errors.confirmPwd}
</td>
</tr>
<tr>
<td>邮箱</td>
<td>
<input type="text" name="email" value="${formbean.email}">${formbean.errors.email}
</td>
</tr>
<tr>
<td>生日</td>
<td>
<input type="text" name="birthday" value="${formbean.birthday}">${formbean.errors.birthday}
</td>
</tr>
<tr>
<td>
<input type="reset" value="清空">
</td>
<td>
<input type="submit" value="注册">
</td>
</tr>
</table>
</form>
</body>
</html>

  到此,用户注册功能就算是开发完成了!

  下面测试一下开发好的用户注册功能:

    输入URL地址:http://localhost:8080/webmvcframework/servlet/RegisterUIServlet访问register.jsp页面,运行效果如下:

    

  如果输入的表单项不符合校验规则,那么是无法进行注册的,运行效果如下:

    

3.4.2、 开发登录功能

  1、在me.gacl.web.UI包下写一个LoginUIServlet为用户提供登录界面

  

  LoginUIServlet收到用户请求后,就跳到login.jsp

  LoginUIServlet的代码如下:

package me.gacl.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;
/**
* @author gacl
* LoginUIServlet负责为用户输出登陆界面
* 当用户访问LoginUIServlet时,就跳转到WEB-INF/pages目录下的login.jsp页面
*/
public class LoginUIServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/pages/login.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}

  2、在/WEB-INF/pages/目录下编写用户登录的jsp页面login.jsp

  

  login.jsp页面的代码如下:

<%@ page language="java" pageEncoding="UTF-"%>
<!DOCTYPE HTML>
<html>
<head>
<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>

  login.jsp中的<form action="${pageContext.request.contextPath}/servlet/LoginServlet" method="post">指明表单提交后,交给LoginServlet进行处理。

3、在me.gacl.web.controller包下编写用于处理用户登录的LoginServlet

  LoginServlet的代码如下:

package me.gacl.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 me.gacl.domain.User;
import me.gacl.service.IUserService;
import me.gacl.service.impl.UserServiceImpl;
/**
* 处理用户登录的servlet
* @author gacl
*
*/
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");
IUserService service = new UserServiceImpl();
//用户登录
User user = service.loginUser(username, password);
if(user==null){
String message = String.format(
"对不起,用户名或密码有误!!请重新登录!秒后为您自动跳到登录页面!!<meta http-equiv='refresh' content=';url=%s'",
request.getContextPath()+"/servlet/LoginUIServlet");
request.setAttribute("message",message);
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;
}
//登录成功后,就将用户存储到session中
request.getSession().setAttribute("user", user);
String message = String.format(
"恭喜:%s,登陆成功!本页将在秒后跳到首页!!<meta http-equiv='refresh' content=';url=%s'",
user.getUserName(),
request.getContextPath()+"/index.jsp");
request.setAttribute("message",message);
request.getRequestDispatcher("/message.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}

  到此,用户登录的功能就算是开发完成了。

  下面测试一下开发好的用户登录功能,输入URL地址:http://localhost:8080/webmvcframework/servlet/LoginUIServlet访问login.jsp页面,输入正确的用户名和密码进行登录,运行效果如下:

  

  如果输入的用户名和密码错误,那么就无法登录成功,运行效果如下:

  

3.4.3、 开发注销功能

  在me.gacl.web.controller包下编写用于处理用户注销的LogoutServlet

  LogoutServlet的代码如下:

package me.gacl.web.controller;
import java.io.IOException;
import java.text.MessageFormat;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LogoutServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//移除存储在session中的user对象,实现注销功能
request.getSession().removeAttribute("user");
//由于字符串中包含有单引号,在这种情况下使用MessageFormat.format方法拼接字符串时就会有问题
//MessageFormat.format方法只是把字符串中的单引号去掉,不会将内容填充到指定的占位符中
String tempStr = MessageFormat.format(
"注销成功!!秒后为您自动跳到登录页面!!<meta http-equiv='refresh' content=';url={}'/>",
request.getContextPath()+"/servlet/LoginUIServlet");
System.out.println(tempStr);//输出结果:注销成功!!秒后为您自动跳到登录页面!!<meta http-equiv=refresh content=;url={}/>
System.out.println("---------------------------------------------------------");
/**
* 要想解决"如果要拼接的字符串包含有单引号,那么MessageFormat.format方法就只是把字符串中的单引号去掉,不会将内容填充到指定的占位符中"这个问题,
* 那么可以需要使用单引号引起来的字符串中使用个单引号引起来,例如:"<meta http-equiv=''refresh'' content='';url={}''/>"
* 这样MessageFormat.format("<meta http-equiv=''refresh'' content='';url={}''/>","index.jsp")就可以正常返回
* <meta http-equiv=''refresh'' content='';url=index.jsp'/>
*/
String tempStr = MessageFormat.format(
"注销成功!!秒后为您自动跳到登录页面!!<meta http-equiv=''refresh'' content='';url={}''/>",
request.getContextPath()+"/servlet/LoginUIServlet");
/**
* 输出结果:
* 注销成功!!秒后为您自动跳到登录页面!!
* <meta http-equiv='refresh' content=';url=/webmvcframework/servlet/LoginUIServlet'/>
*/
System.out.println(tempStr);
String message = String.format(
"注销成功!!秒后为您自动跳到登录页面!!<meta http-equiv='refresh' content=';url=%s'/>",
request.getContextPath()+"/servlet/LoginUIServlet");
request.setAttribute("message",message);
request.getRequestDispatcher("/message.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}

  用户登录成功后,会将登录的用户信息存储在session中,所以我们要将存储在session中的user删除掉,这样就可以实现用户注销了。

  用户登录成功后就会跳转到index.jsp页面,在index.jsp页面中放一个【退出登陆】按钮,当点击【退出登陆】按钮时,就访问LogoutServlet,将用户注销。

  index.jsp的代码如下:

<%@ page language="java" pageEncoding="UTF-"%>
<%--为了避免在jsp页面中出现java代码,这里引入jstl标签库,利用jstl标签库提供的标签来做一些逻辑判断处理 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML>
<html>
<head>
<title>首页</title>
<script type="text/javascript">
function doLogout(){
//访问LogoutServlet注销当前登录的用户
window.location.href="${pageContext.request.contextPath}/servlet/LogoutServlet";
}
</script>
</head>
<body>
<h>孤傲苍狼的网站</h>
<hr/>
<c:if test="${user==null}">
<a href="${pageContext.request.contextPath}/servlet/RegisterUIServlet" target="_blank">注册</a>
<a href="${pageContext.request.contextPath}/servlet/LoginUIServlet">登陆</a>
</c:if>
<c:if test="${user!=null}">
欢迎您:${user.userName}
<input type="button" value="退出登陆" onclick="doLogout()">
</c:if>
<hr/>
</body>
</html>

  测试开发好的注销功能,效果如下:

  

  到此,所有的功能都开发完成了,测试也通过了。

四、开发总结

  通过这个小例子,可以了解到mvc分层架构的项目搭建,在平时的项目开发中,也都是按照如下的顺序来进行开发的:

  1、搭建开发环境

    1.1 创建web项目

    1.2 导入项目所需的开发包

    1.3 创建程序的包名,在java中是以包来体现项目的分层架构的

  2、开发domain

  把一张要操作的表当成一个VO类(VO类只定义属性以及属性对应的get和set方法,没有涉及到具体业务的操作方法),VO表示的是值对象,通俗地说,就是把表中的每一条记录当成一个对象,表中的每一个字段就作为这个对象的属性。每往表中插入一条记录,就相当于是把一个VO类的实例对象插入到数据表中,对数据表进行操作时,都是直接把一个VO类的对象写入到表中,一个VO类对象就是一条记录。每一个VO对象可以表示一张表中的一行记录,VO类的名称要和表的名称一致或者对应。

  3、开发dao

    3.1 DAO操作接口:每一个DAO操作接口规定了,一张表在一个项目中的具体操作方法,此接口的名称最好按照如下格式编写:“I表名称Dao”。

      ├DAO接口里面的所有方法按照以下的命名编写:

        ├更新数据库:doXxx()

        ├查询数据库:findXxx()或getXxx()

    3.2 DAO操作接口的实现类:实现类中完成具体的增删改查操作

      ├此实现类完成的只是数据库中最核心的操作,并没有专门处理数据库的打开和关闭,因为这些操作与具体的业务操作无关。

  4、开发service(service 对web层提供所有的业务服务)

  5、开发web层

以上内容是小编给大家介绍的JavaWeb实现用户登录注册功能实例代码(基于Servlet+JSP+JavaBean模式),希望对大家有所帮助!

时间: 2016-05-27

在jsp中用bean和servlet联合实现用户注册、登录

声明:作者原创,版权所有.未经授权,不得转载 在jsp中用bean和servlet联合实现用户注册.登录 作者:imagebear版权:imagebear 本例需要的软件和运行环境:1.Windows2000 Server操作系统2.jdk1.43.JCreator2.5(java源码编辑调试器,吐血推荐!)4.Macromedia JRun MX5.Macromedia Dreamweaver MX(非必需)6.MySQL数据库(最好安装MySQL Control Center) 一.数据库设

Ionic+AngularJS实现登录和注册带验证功能

登录: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"> <title></title> <li

jsp基于XML实现用户登录与注册的实例解析(附源码)

简单的基于xml做数据库的登录与注册 主题介绍: 1.xml的读取和存储,主要是用到dom4j技术,(网络中的文件存储路径采用classLoader) 文件的读取和存储,写了一个工厂类 public class DocumentFactory { private static Document dom=null;//需要共享一个dom,所以需要设置为static private static String name="user.xml"; private static String f

js制作带有遮罩弹出层实现登录注册表单特效代码分享

本文实例讲述了js制作带有遮罩弹出层实现登录注册表单代码特效代码.分享给大家供大家参考.具体如下: 运行效果图:                     ----------------------查看效果   源码下载----------------------- 小提示:浏览器中如果不能正常运行,可以尝试切换浏览模式. jquery制作的带有遮罩弹出层实现登录注册等表单的特效源码,是一段实现了点击后在原始页面上弹出想用页面的代码.  为大家分享的js制作带有遮罩弹出层实现登录注册表单代码特效

JSP+MySQL实现网站的登录与注册小案例

为了练手,我就自己试着做了一个网站的登录与注册的小案例.由于没有做美化处理,所以界面并不是很好看. 网站实现的功能如下:  •用户首次注册功能  •用户登录功能 下面我将会分模块展示 注册模块 首先需要一个注册界面,如下register.jsp: <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOC

js实现登录与注册界面

完成登录与注册页面的HTML+CSS+JS,其中的输入项检查包括: 用户名6-12位 首字母不能是数字 只能包含字母和数字 密码6-12位 注册页两次密码是否一致 html代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>欢迎你,请先登陆!</title> <script type="

node.js实现登录注册页面

本文实例为大家分享了node.js登录注册页面展示的具体代码,供大家参考,具体内容如下 首先需要新建四个文件 一个服务器js 一个保存数据的txt 一个登陆.一个注册页面html 1.注册页面 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>regist</title> </head> <

原生js验证简洁注册登录页面

序 一个以js验证表单的简洁的注册登录页面,不多说直接上图 效果 主要文件 完整代码 1 sign_up.html 注册表单 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>sign-up</title> <link rel="stylesheet" href="css

JSP实现用户登录、注册和退出功能

本文讲述使用JSP实现用户登录,包括用户登录.注册和退出功能等. 1.系统用例图 2.页面流程图 3.数据库设计 本例使用oracle数据库 创建用户表 包括id,username,password和email,共4个字段 -- Create table create table P_USER ( id VARCHAR2(50) not null, username VARCHAR2(20), password VARCHAR2(20), email VARCHAR2(50) ) tablesp

Servlet+JavaBean+JSP打造Java Web注册与登录功能

采用Java Web所实现的MVC结构图如下,其中控制器部分采用Servlet来实现,模型部分采用JavaBean来实现,而大部分的视图采用Jsp页面来实现. 思想基础 JSP+JavaBean两层结构工作原理应该是比较熟悉的,也比较好理解. 但是有一点必须要清楚就是用户通过浏览器来发送网页的请求,此请求到达服务器后在服务器端查找对应的网页,如果是首次请求(第二次就不用解释执行了),对于JSP来说要生成Servlet,然后通过Servlet引擎来执行 Servlet,把调用JavaBean的结果

java web实现自动登录功能

本文实例为大家分享了java web实现自动登录功能的具体代码,供大家参考,具体内容如下 主要思路就是:当用户访问网站的首页时,浏览器端会先检擦浏览器中存在的cookie中是否又登录的用户的用户名,如果有,则直接跳转至用户登录好的界面,如果没有,则重定向至登录界面,在服务器端创建该用户登录的cookie,响应时,将创建的cookie返回至浏览器端保存. 一.用户访问首页时检查cookie是否存在. package ahpudong.com; import java.io.IOException;

Java Web 实现QQ登录功能一个帐号同一时间只能一个人登录

对于一个帐号在同一时间只能一个人登录,可以通过下面的方法实现: 1 .在用户登录时,把用户添加到一个ArrayList中 2 .再次登录时查看ArrayList中有没有该用户,如果ArrayList中已经存在该用户,则阻止其登录 3 .当用户退出时,需要从该ArrayList中删除该用户,这又分为三种情况 ① 使用注销按钮正常退出 ② 点击浏览器关闭按钮或者用Alt+F4退出,可以用JavaScript捕捉该页面关闭事件, 执行一段Java方法删除ArrayList中的用户 ③ 非正常退出,比如

java web中图片验证码功能的简单实现方法

用户在注册网站信息的时候基本上都要数据验证码验证.那么图片验证码功能该如何实现呢? 大概步骤是: 1.在内存中创建缓存图片 2.设置背景色 3.画边框 4.写字母 5.绘制干扰信息 6.图片输出 废话不多说,直接上代码 package com.lsgjzhuwei.servlet.response; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.Buffer

Java web过滤器验证登录防止未登录进入界面

今天用ssh2写了个简单的系统,发现了一个问题,我这系统必须先登录成功才能进入主页,但我在浏览器里直接输入主页地址,发现也能进入,这个肯定不好,毫无安全性可言,后经查资料发现需要登录过滤器,就试了下,发现果然可以避免未经登录即可进入主页的危险,下面是我整理出的详细步骤: 1.首先写一个权限过滤filter类,实现Filter接口 import java.io.IOException; import javax.servlet.Filter; import javax.servlet.Filter

java web response提供文件下载功能的实例讲解

webapp项目的结构如下图: download.html文件的内容如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>资源下载:</h1> <p> 单纯地使用a标签时,只有浏览器不能解析的文

java web实现邮箱发送功能

本文实例为大家分享了java web实现邮箱发送功能的具体代码,供大家参考,具体内容如下 1.邮箱协议 电子邮件的在网络中传输和网页一样需要遵从特定的协议,常用的电子邮件协议包括 SMTP,POP3,IMAP.其中邮件的创建和发送只需要用到 SMTP协议,所有本文也只会涉及到SMTP协议.SMTP 是 Simple Mail Transfer Protocol 的简称,即简单邮件传输协议. 2.需要使用的jar包 下载地址 3.代码实现 package com.bhkj.ShoppingMall

.NET微信开发之PC 端微信扫码注册和登录功能实现

一.前言 先声明一下,本文所注重点为实现思路,代码及数据库设计主要为了展现思路,如果对代码效率有着苛刻要求的项目切勿照搬. 相信做过微信开发的人授权这块都没少做过,但是一般来说我们更多的是为移动端的网站做授权,确切来说是在微信端下做的一个授权.今天遇到的一个问题是,项目支持微信端以及 PC 端,并且开放注册.要求做到无论在 PC 端注册或者是在微信端注册之后都可以在另外一个端进行登录.也就是说无论 PC 或是微信必须做到"你就是你"(通过某种方式关联). 二.寻找解决方案 按传统的方式

redis+php实现微博(一)注册与登录功能详解

本文实例讲述了redis+php实现微博注册与登录功能.分享给大家供大家参考,具体如下: (一).微博功能概况 微博用户账号注册 微博用户登录 微博发布 添加微博好友(粉丝) 微博推送 微博冷数据写入mysql数据库 (二).redis数据结构设计 这节分享微博用户注册与登录: 我们完全采用redis作为数据库来实现注册于登录 先来看一下redis数据结构的设计: 注册用户表:user set global:userid set user:userid:1:username zhangshan

java servlet结合mysql搭建java web开发环境

这次学servlet用的数据库是mysql,而且我当前是准备好好的学JAVAWeb了,所以关于javaweb的文章后面肯定还会继续的更新,前几天其实想学php,但是后面一个朋友的提醒,让我转向了javaweb. 因为我当前是做手机应用,所以学java还是打算从数据接口这块入手,这次讲解的流程将非常仔细...从我搭建的方式-----中途遇到的错误----->最后数据展示,我都会一一贴出来. 一.在ecplise下安装javaweb的开发环境: 这一步和前面一篇javaservlet+oracle是