300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 基于Servlet+JSP+JavaBean开发模式的用户登录注册

基于Servlet+JSP+JavaBean开发模式的用户登录注册

时间:2020-06-22 08:56:39

相关推荐

基于Servlet+JSP+JavaBean开发模式的用户登录注册

基于Servlet+JSP+JavaBean开发模式的用户登录注册

一、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开发中,架构的层次是以包的形式体现出来的

一个良好的JavaWeb项目架构应该具有以上的11个包,这样显得层次分明,各个层之间的职责也很清晰明了,搭建JavaWeb项目架构时,就按照上面的1~11的序号顺序创建包:domain→dao→dao.impl→service→service.impl→web.controller→web.UI→web.filter→web.listener→util→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类具体代码如下:

1 package me.gacl.domain;2 3 import java.io.Serializable;4 import java.util.Date;5 /**6 * @author gacl7 * 用户实体类8 */9 public class User implements Serializable {10 11private static final long serialVersionUID = -4313782718477229465L;1213// 用户ID14private String id;15// 用户名16private String userName;17// 用户密码18private String userPwd;19// 用户邮箱20private String email;21// 用户生日22private Date birthday;23 24public String getId() {25 return id;26}27 28public void setId(String id) {29 this.id = id;30}31 32public String getUserName() {33 return userName;34}35 36public void setUserName(String userName) {37 this.userName = userName;38}39 40public String getUserPwd() {41 return userPwd;42}43 44public void setUserPwd(String userPwd) {45 this.userPwd = userPwd;46}47 48public String getEmail() {49 return email;50}51 52public void setEmail(String email) {53 this.email = email;54}55 56public Date getBirthday() {57 return birthday;58}59 60public void setBirthday(Date birthday) {61 this.birthday = birthday;62}63 }

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

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

IUserDao接口的具体代码如下:

1 package me.gacl.dao;2 3 import me.gacl.domain.User;4 5 public interface IUserDao {6 7/**8* 根据用户名和密码来查找用户9* @param userName10* @param userPwd11* @return 查到到的用户12*/13User find(String userName, String userPwd);14 15/**16* 添加用户17* @param user18*/19void add(User user);20 21/**根据用户名来查找用户22* @param userName23* @return 查到到的用户24*/25User find(String userName);26 }

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

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

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

UserDaoImpl类的具体代码如下:

1 package me.gacl.dao.impl;2 3 import java.text.SimpleDateFormat;4 import org.dom4j.Document;5 import org.dom4j.Element;6 import me.gacl.dao.IUserDao;7 import me.gacl.domain.User;8 import me.gacl.util.XmlUtils;9 10 /**11 * IUserDao接口的实现类12 * @author gacl13 */14 public class UserDaoImpl implements IUserDao {15 16@Override17public User find(String userName, String userPwd) {18 try{19 Document document = XmlUtils.getDocument();20 //使用XPath表达式来操作XML节点21 Element e = (Element) document.selectSingleNode("//user[@userName='"+userName+"' and @userPwd='"+userPwd+"']");22 if(e==null){23 return null;24 }25 User user = new User();26 user.setId(e.attributeValue("id"));27 user.setEmail(e.attributeValue("email"));28 user.setUserPwd(e.attributeValue("userPwd"));29 user.setUserName(e.attributeValue("userName"));30 String birth = e.attributeValue("birthday");31 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");32 user.setBirthday(sdf.parse(birth));33 34 return user;35 36 }catch (Exception e) {37 throw new RuntimeException(e);38 }39}40 41@SuppressWarnings("deprecation")42@Override43public void add(User user) {44 try{45 Document document = XmlUtils.getDocument();46 Element root = document.getRootElement();47 Element user_node = root.addElement("user"); //创建user结点,并挂到root48 user_node.setAttributeValue("id", user.getId());49 user_node.setAttributeValue("userName", user.getUserName());50 user_node.setAttributeValue("userPwd", user.getUserPwd());51 user_node.setAttributeValue("email", user.getEmail());52 53 SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");54 user_node.setAttributeValue("birthday", sdf.format(user.getBirthday()));55 56 XmlUtils.write2Xml(document);57 58 }catch (Exception e) {59 throw new RuntimeException(e);60 }61}62 63@Override64public User find(String userName) {65 try{66 Document document = XmlUtils.getDocument();67 Element e = (Element) document.selectSingleNode("//user[@userName='"+userName+"']");68 if(e==null){69 return null;70 }71 User user = new User();72 user.setId(e.attributeValue("id"));73 user.setEmail(e.attributeValue("email"));74 user.setUserPwd(e.attributeValue("userPwd"));75 user.setUserName(e.attributeValue("userName"));76 String birth = e.attributeValue("birthday");77 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");78 user.setBirthday(sdf.parse(birth));79 80 return user;81 82 }catch (Exception e) {83 throw new RuntimeException(e);84 }85}86 87 }

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

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

IUserService接口的具体代码如下:

1 package me.gacl.service;2 3 import me.gacl.domain.User;4 import me.gacl.exception.UserExistException;5 6 public interface IUserService {7 8/**9* 提供注册服务10* @param user11* @throws UserExistException12*/13void registerUser(User user) throws UserExistException;14 15/**16* 提供登录服务17* @param userName18* @param userPwd19* @return20*/21User loginUser(String userName, String userPwd);22 }

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

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

1 package me.gacl.service.impl;2 3 import me.gacl.dao.IUserDao;4 import me.gacl.dao.impl.UserDaoImpl;5 import me.gacl.domain.User;6 import me.gacl.exception.UserExistException;7 import me.gacl.service.IUserService;8 9 public class UserServiceImpl implements IUserService {10 11private IUserDao userDao = new UserDaoImpl();1213@Override14public void registerUser(User user) throws UserExistException {15 if (userDao.find(user.getUserName())!=null) {16 //checked exception 17 //unchecked exception18 //这里抛编译时异常的原因:是我想上一层程序处理这个异常,以给用户一个友好提示19 throw new UserExistException("注册的用户名已存在!!!");20 }21 userDao.add(user);22}23 24@Override25public User loginUser(String userName, String userPwd) {26 return userDao.find(userName, userPwd);27}28 29 }

3.4、开发web层

3.4.1、 开发注册功能

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

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

RegisterUIServlet的代码如下:

1 package me.gacl.web.UI;2 3 import java.io.IOException;4 import javax.servlet.ServletException;5 import javax.servlet.http.HttpServlet;6 import javax.servlet.http.HttpServletRequest;7 import javax.servlet.http.HttpServletResponse;8 /**9 * @author gacl10 * 为用户提供注册的用户界面的Servlet11 * RegisterUIServlet负责为用户输出注册界面12 * 当用户访问RegisterUIServlet时,就跳转到WEB-INF/pages目录下的register.jsp页面13 */14 public class RegisterUIServlet extends HttpServlet {15 16public void doGet(HttpServletRequest request, HttpServletResponse response)17 throws ServletException, IOException {18 request.getRequestDispatcher("/WEB-INF/pages/register.jsp").forward(request, response);19}20 21public void doPost(HttpServletRequest request, HttpServletResponse response)22 throws ServletException, IOException {23 doGet(request, response);24}25 26 }

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

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

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

register.jsp页面的代码如下:

1 <%@ page language="java" pageEncoding="UTF-8"%>2 <!DOCTYPE HTML>3 <html>4<head>5 <title>用户注册</title>6</head>7 8<body style="text-align: center;">9 <form action="${pageContext.request.contextPath}/servlet/RegisterServlet" method="post">10 <table width="60%" border="1">11 <tr>12 <td>用户名</td>13 <td>1415<input type="text" name="userName">16 </td>17 </tr>18 <tr>19 <td>密码</td>20 <td>21<input type="password" name="userPwd">22 </td>23 </tr>24 <tr>25 <td>确认密码</td>26 <td>27<input type="password" name="confirmPwd">28 </td>29 </tr>30 <tr>31 <td>邮箱</td>32 <td>33<input type="text" name="email">34 </td>35 </tr>36 <tr>37 <td>生日</td>38 <td>39<input type="text" name="birthday">40 </td>41 </tr>42 <tr>43 <td>44<input type="reset" value="清空">45 </td>46 <td>47<input type="submit" value="注册">48 </td>49 </tr>50 </table>51 </form>52</body>53 </html>

register.jsp中的<formaction="${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代码如下:

1 package me.gacl.web.formbean;2 3 import java.util.HashMap;4 import java.util.Map;5 6 import mons.beanutils.locale.converters.DateLocaleConverter;7 8 /**9 * 封装的用户注册表单bean,用来接收register.jsp中的表单输入项的值10 * RegisterFormBean中的属性与register.jsp中的表单输入项的name一一对应11 * RegisterFormBean的职责除了负责接收register.jsp中的表单输入项的值之外还担任着校验表单输入项的值的合法性12 * @author gacl13 *14 */15 public class RegisterFormBean {16 17//RegisterFormBean中的属性与register.jsp中的表单输入项的name一一对应18//<input type="text" name="userName"/>19private String userName;20//<input type="password" name="userPwd"/>21private String userPwd;22//<input type="password" name="confirmPwd"/>23private String confirmPwd;24//<input type="text" name="email"/>25private String email;26//<input type="text" name="birthday"/>27private String birthday;28 2930/**31* 存储校验不通过时给用户的错误提示信息32*/33private Map<String, String> errors = new HashMap<String, String>();34 35public Map<String, String> getErrors() {36 return errors;37}38 39public void setErrors(Map<String, String> errors) {40 this.errors = errors;41}42 43/*44* validate方法负责校验表单输入项45* 表单输入项校验规则:46* private String userName; 用户名不能为空,并且要是3-8的字母 abcdABcd 47* private String userPwd; 密码不能为空,并且要是3-8的数字48* private String confirmPwd; 两次密码要一致49* private String email; 可以为空,不为空要是一个合法的邮箱 50* private String birthday; 可以为空,不为空时,要是一个合法的日期51*/52public boolean validate() {53 54 boolean isOk = true;55 56 if (this.userName == null || this.userName.trim().equals("")) {57 isOk = false;58 errors.put("userName", "用户名不能为空!!");59 } else {60 if (!this.userName.matches("[a-zA-Z]{3,8}")) {61 isOk = false;62 errors.put("userName", "用户名必须是3-8位的字母!!");63 }64 }65 66 if (this.userPwd == null || this.userPwd.trim().equals("")) {67 isOk = false;68 errors.put("userPwd", "密码不能为空!!");69 } else {70 if (!this.userPwd.matches("\\d{3,8}")) {71 isOk = false;72 errors.put("userPwd", "密码必须是3-8位的数字!!");73 }74 }75 76 // private String password2; 两次密码要一致77 if (this.confirmPwd != null) {78 if (!this.confirmPwd.equals(this.userPwd)) {79 isOk = false;80 errors.put("confirmPwd", "两次密码不一致!!");81 }82 }83 84 // private String email; 可以为空,不为空要是一个合法的邮箱85 if (this.email != null && !this.email.trim().equals("")) {86 if (!this.email.matches("\\w+@\\w+(\\.\\w+)+")) {87 isOk = false;88 errors.put("email", "邮箱不是一个合法邮箱!!");89 }90 }91 92 // private String birthday; 可以为空,不为空时,要是一个合法的日期93 if (this.birthday != null && !this.birthday.trim().equals("")) {94 try {95 DateLocaleConverter conver = new DateLocaleConverter();96 conver.convert(this.birthday);97 } catch (Exception e) {98 isOk = false;99 errors.put("birthday", "生日必须要是一个日期!!");100 }101 }102 103 return isOk;104}105 106public String getUserName() {107 return userName;108}109 110public void setUserName(String userName) {111 this.userName = userName;112}113 114public String getUserPwd() {115 return userPwd;116}117 118public void setUserPwd(String userPwd) {119 this.userPwd = userPwd;120}121 122public String getConfirmPwd() {123 return confirmPwd;124}125 126public void setConfirmPwd(String confirmPwd) {127 this.confirmPwd = confirmPwd;128}129 130public String getEmail() {131 return email;132}133 134public void setEmail(String email) {135 this.email = email;136}137 138public String getBirthday() {139 return birthday;140}141 142public void setBirthday(String birthday) {143 this.birthday = birthday;144}145 }

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

1 package me.gacl.util;2 3 import java.util.Enumeration;4 import java.util.UUID;5 import javax.servlet.http.HttpServletRequest;6 import mons.beanutils.BeanUtils;7 8 /**9 * @author gacl10 * 把request对象中的请求参数封装到bean中11 */12 public class WebUtils {13 14/**15* 将request对象转换成T对象16* @param request 17* @param clazz18* @return19*/20public static <T> T request2Bean(HttpServletRequest request,Class<T> clazz){21 try{22 T bean = clazz.newInstance();23 Enumeration<String> e = request.getParameterNames(); 24 while(e.hasMoreElements()){25 String name = (String) e.nextElement();26 String value = request.getParameter(name);27 BeanUtils.setProperty(bean, name, value);28 }29 return bean;30 }catch (Exception e) {31 throw new RuntimeException(e);32 }33}3435/**36* 生成UUID37* @return38*/39public static String makeId(){40 return UUID.randomUUID().toString();41}4243 }

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

1 package me.gacl.web.controller;2 3 import java.io.IOException;4 import java.util.Date;5 import javax.servlet.ServletException;6 import javax.servlet.http.HttpServlet;7 import javax.servlet.http.HttpServletRequest;8 import javax.servlet.http.HttpServletResponse;9 import mons.beanutils.BeanUtils;10 import mons.beanutils.ConvertUtils;11 import mons.beanutils.locale.converters.DateLocaleConverter;12 import me.gacl.domain.User;13 import me.gacl.exception.UserExistException;14 import me.gacl.service.IUserService;15 import me.gacl.service.impl.UserServiceImpl;16 import me.gacl.util.WebUtils;17 import me.gacl.web.formbean.RegisterFormBean;18 /**19 * 处理用户注册的Servlet20 * @author gacl21 *22 */23 public class RegisterServlet extends HttpServlet {24 25public void doGet(HttpServletRequest request, HttpServletResponse response)26 throws ServletException, IOException {27 //将客户端提交的表单数据封装到RegisterFormBean对象中28 RegisterFormBean formbean = WebUtils.request2Bean(request,RegisterFormBean.class);29 //校验用户注册填写的表单数据30 if (formbean.validate() == false) {//如果校验失败31 //将封装了用户填写的表单数据的formbean对象发送回register.jsp页面的form表单中进行显示32 request.setAttribute("formbean", formbean);33 //校验失败就说明是用户填写的表单数据有问题,那么就跳转回register.jsp34 request.getRequestDispatcher("/WEB-INF/pages/register.jsp").forward(request, response);35 return;36 }37 38 User user = new User();39 try {40 // 注册字符串到日期的转换器41 ConvertUtils.register(new DateLocaleConverter(), Date.class);42 BeanUtils.copyProperties(user, formbean);//把表单的数据填充到javabean中43 user.setId(WebUtils.makeId());//设置用户的Id属性44 IUserService service = new UserServiceImpl();45 //调用service层提供的注册用户服务实现用户注册46 service.registerUser(user);47 String message = String.format(48 "注册成功!!3秒后为您自动跳到登录页面!!<meta http-equiv='refresh' content='3;url=%s'/>", 49 request.getContextPath()+"/servlet/LoginUIServlet");50 request.setAttribute("message",message);51 request.getRequestDispatcher("/message.jsp").forward(request,response);52 53 } catch (UserExistException e) {54 formbean.getErrors().put("userName", "注册用户已存在!!");55 request.setAttribute("formbean", formbean);56 request.getRequestDispatcher("/WEB-INF/pages/register.jsp").forward(request, response);57 } catch (Exception e) {58 e.printStackTrace(); // 在后台记录异常59 request.setAttribute("message", "对不起,注册失败!!");60 request.getRequestDispatcher("/message.jsp").forward(request,response);61 }62}63 64public void doPost(HttpServletRequest request, HttpServletResponse response)65 throws ServletException, IOException {66 doGet(request, response);67}68 69 }

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

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

1 <%@ page language="java" pageEncoding="UTF-8"%>2 <!DOCTYPE HTML>3 <html>4<head>5 <title>用户注册</title>6</head>7 8<body style="text-align: center;">9 <form action="${pageContext.request.contextPath}/servlet/RegisterServlet" method="post">10 <table width="60%" border="1">11 <tr>12 <td>用户名</td>13 <td>14<%--使用EL表达式${}提取存储在request对象中的formbean对象中封装的表单数据(formbean.userName)以及错误提示消息(formbean.errors.userName)--%>15<input type="text" name="userName" value="${formbean.userName}">${formbean.errors.userName}16 </td>17 </tr>18 <tr>19 <td>密码</td>20 <td>21<input type="password" name="userPwd" value="${formbean.userPwd}">${formbean.errors.userPwd}22 </td>23 </tr>24 <tr>25 <td>确认密码</td>26 <td>27<input type="password" name="confirmPwd" value="${formbean.confirmPwd}">${formbean.errors.confirmPwd}28 </td>29 </tr>30 <tr>31 <td>邮箱</td>32 <td>33<input type="text" name="email" value="${formbean.email}">${formbean.errors.email}34 </td>35 </tr>36 <tr>37 <td>生日</td>38 <td>39<input type="text" name="birthday" value="${formbean.birthday}">${formbean.errors.birthday}40 </td>41 </tr>42 <tr>43 <td>44<input type="reset" value="清空">45 </td>46 <td>47<input type="submit" value="注册">48 </td>49 </tr>50 </table>51 </form>52</body>53 </html>

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

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

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

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

3.4.2、 开发登录功能

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

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

LoginUIServlet的代码如下:

1 package me.gacl.web.UI;2 3 import java.io.IOException;4 5 import javax.servlet.ServletException;6 import javax.servlet.http.HttpServlet;7 import javax.servlet.http.HttpServletRequest;8 import javax.servlet.http.HttpServletResponse;9 10 /**11 * @author gacl12 * LoginUIServlet负责为用户输出登陆界面13 * 当用户访问LoginUIServlet时,就跳转到WEB-INF/pages目录下的login.jsp页面14 */15 public class LoginUIServlet extends HttpServlet {16 17public void doGet(HttpServletRequest request, HttpServletResponse response)18 throws ServletException, IOException {19 20 request.getRequestDispatcher("/WEB-INF/pages/login.jsp").forward(request, response);21}22 23public void doPost(HttpServletRequest request, HttpServletResponse response)24 throws ServletException, IOException {25 doGet(request, response);26}27 28 }

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

login.jsp页面的代码如下:

1 <%@ page language="java" pageEncoding="UTF-8"%>2 <!DOCTYPE HTML>3 <html>4 <head>5<title>用户登陆</title>6 </head>7 8 <body>9<form action="${pageContext.request.contextPath }/servlet/LoginServlet" method="post">10 用户名:<input type="text" name="username"><br/>11 密码:<input type="password" name="password"><br/>12 <input type="submit" value="登陆">13</form>14 </body>15 </html>

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

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

LoginServlet的代码如下:

1 package me.gacl.web.controller;2 3 import java.io.IOException;4 5 import javax.servlet.ServletException;6 import javax.servlet.http.HttpServlet;7 import javax.servlet.http.HttpServletRequest;8 import javax.servlet.http.HttpServletResponse;9 10 import me.gacl.domain.User;11 import me.gacl.service.IUserService;12 import me.gacl.service.impl.UserServiceImpl;13 14 /**15 * 处理用户登录的servlet16 * @author gacl17 *18 */19 public class LoginServlet extends HttpServlet {20 21public void doGet(HttpServletRequest request, HttpServletResponse response)22 throws ServletException, IOException {23 24 //获取用户填写的登录用户名25 String username = request.getParameter("username");26 //获取用户填写的登录密码27 String password = request.getParameter("password");28 29 IUserService service = new UserServiceImpl();30 //用户登录31 User user = service.loginUser(username, password);32 if(user==null){33 String message = String.format(34 "对不起,用户名或密码有误!!请重新登录!2秒后为您自动跳到登录页面!!<meta http-equiv='refresh' content='2;url=%s'", 35 request.getContextPath()+"/servlet/LoginUIServlet");36 request.setAttribute("message",message);37 request.getRequestDispatcher("/message.jsp").forward(request, response);38 return;39 }40 //登录成功后,就将用户存储到session中41 request.getSession().setAttribute("user", user);42 String message = String.format(43 "恭喜:%s,登陆成功!本页将在3秒后跳到首页!!<meta http-equiv='refresh' content='3;url=%s'", 44 user.getUserName(),45 request.getContextPath()+"/index.jsp");46 request.setAttribute("message",message);47 request.getRequestDispatcher("/message.jsp").forward(request, response);48}49 50public void doPost(HttpServletRequest request, HttpServletResponse response)51 throws ServletException, IOException {52 doGet(request, response);53}54 55 }

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

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

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

3.4.3、 开发注销功能

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

LogoutServlet的代码如下:

1 package me.gacl.web.controller;2 3 import java.io.IOException;4 import java.text.MessageFormat;5 6 import javax.servlet.ServletException;7 import javax.servlet.http.HttpServlet;8 import javax.servlet.http.HttpServletRequest;9 import javax.servlet.http.HttpServletResponse;10 11 public class LogoutServlet extends HttpServlet {12 13public void doGet(HttpServletRequest request, HttpServletResponse response)14 throws ServletException, IOException {15 //移除存储在session中的user对象,实现注销功能16 request.getSession().removeAttribute("user");17 //由于字符串中包含有单引号,在这种情况下使用MessageFormat.format方法拼接字符串时就会有问题18 //MessageFormat.format方法只是把字符串中的单引号去掉,不会将内容填充到指定的占位符中19 String tempStr1 = MessageFormat.format(20 "注销成功!!3秒后为您自动跳到登录页面!!<meta http-equiv='refresh' content='3;url={0}'/>", 21 request.getContextPath()+"/servlet/LoginUIServlet");22 System.out.println(tempStr1);//输出结果:注销成功!!3秒后为您自动跳到登录页面!!<meta http-equiv=refresh content=3;url={0}/>23 System.out.println("---------------------------------------------------------");24 /**25* 要想解决"如果要拼接的字符串包含有单引号,那么MessageFormat.format方法就只是把字符串中的单引号去掉,不会将内容填充到指定的占位符中"这个问题,26* 那么可以需要使用单引号引起来的字符串中使用2个单引号引起来,例如:"<meta http-equiv=''refresh'' content=''3;url={0}''/>"27* 这样MessageFormat.format("<meta http-equiv=''refresh'' content=''3;url={0}''/>","index.jsp")就可以正常返回28* <meta http-equiv=''refresh'' content=''3;url=index.jsp'/>29*/30 String tempStr2 = MessageFormat.format(31 "注销成功!!3秒后为您自动跳到登录页面!!<meta http-equiv=''refresh'' content=''3;url={0}''/>", 32 request.getContextPath()+"/servlet/LoginUIServlet");33 /**34* 输出结果:35* 注销成功!!3秒后为您自动跳到登录页面!!36* <meta http-equiv='refresh' content='3;url=/webmvcframework/servlet/LoginUIServlet'/>37*/38 System.out.println(tempStr2);39 40 String message = String.format(41 "注销成功!!3秒后为您自动跳到登录页面!!<meta http-equiv='refresh' content='3;url=%s'/>", 42 request.getContextPath()+"/servlet/LoginUIServlet");43 request.setAttribute("message",message);44 request.getRequestDispatcher("/message.jsp").forward(request, response);45}46 47public void doPost(HttpServletRequest request, HttpServletResponse response)48 throws ServletException, IOException {49 doGet(request, response);50}51 52 }

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

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

index.jsp的代码如下:

1 <%@ page language="java" pageEncoding="UTF-8"%>2 <%--为了避免在jsp页面中出现java代码,这里引入jstl标签库,利用jstl标签库提供的标签来做一些逻辑判断处理 --%>3 <%@ taglib uri="/jsp/jstl/core" prefix="c"%>4 <!DOCTYPE HTML>5 <html>6 <head>7<title>首页</title>8<script type="text/javascript">9 function doLogout(){10 //访问LogoutServlet注销当前登录的用户11 window.location.href="${pageContext.request.contextPath}/servlet/LogoutServlet";12 }13</script>14 </head>15 16 <body>17<h1>孤傲苍狼的网站</h1>18<hr/>19<c:if test="${user==null}">20 <a href="${pageContext.request.contextPath}/servlet/RegisterUIServlet" target="_blank">注册</a>21 <a href="${pageContext.request.contextPath}/servlet/LoginUIServlet">登陆</a>22</c:if>23<c:if test="${user!=null}">24 欢迎您:${user.userName}25 <input type="button" value="退出登陆" οnclick="doLogout()">26</c:if>27<hr/>28 </body>29 </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层

点击此处下载项目源码

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。