三层架构模式(MVC)案例:登录注册功能实现

1.搭建开发环境

  1.1 导入项目所需的开发包:

     dom4j-1.6.1.jar
          jaxen-1.1-beta-6.jar
          commons-beanutils-1.8.0.jar
          commons-logging.jar
          jstl.jar
          standard.jar

      

  1.2 创建程序的包名

      

  1.3 在类目录下面,创建用于保存用户数据的xml文件(users.xml)-- 简单实现XML代替数据库users.xml

<?xml version="1.0" encoding="UTF-8"?>

<users> 
  <user id="51db22dc-f861-417b-b929-588aec86237e" username="abc" password="123" email="abc@sina.com.cn" birthday="1990-8-5 0:00:00"/>
</users>
View Code

2、开发实体user
  1.1 User.java  

package com.lich.domain;
import java.util.Date;
public class User {
    private String id;
    private String username;
    private String password;
    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 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;
    }
    
}
View Code

3、开发dao

  3.1 开发UserDaoXmlImpl.java

package com.lich.dao.impl;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;

import com.lich.dao.UserDao;
import com.lich.domain.User;
import com.lich.utils.XmlUtils;

//根据业务需求来写
public class UserDaoXmlImpl implements UserDao {
    public User find(String username,String password){
    
        try{
            Document document = XmlUtils.getDocument();
            Element e = (Element) document.selectSingleNode("//user[@username='"+username+"' and @password='"+password+"']");
            if(e==null){
                return null;
            }
            User user = new User();
            user.setId(e.attributeValue("id"));
            user.setEmail(e.attributeValue("email"));
            user.setPassword(e.attributeValue("password"));
            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);
        }
    }
    
    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("password", user.getPassword());
            user_node.setAttributeValue("email", user.getEmail());
            user_node.setAttributeValue("birthday", user.getBirthday().toLocaleString());
        
            XmlUtils.write2Xml(document);
            
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
        
    }
    
    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.setPassword(e.attributeValue("password"));
            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);
        }
    }
}
View Code

  3.2 UserDao.java 抽取接口

View Code

   3.3  开发工具类: XmlUtils

package com.lich.utils;

import java.io.File;

import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public class XmlUtils {
    
    private static String filename = "users.xml";
    
    public static Document getDocument() throws DocumentException{
        
        URL url = XmlUtils.class.getClassLoader().getResource(filename);
        String realpath = url.getPath();
        
        SAXReader reader = new SAXReader();
        return reader.read(new File(realpath));
        
    }
    
    public static void write2Xml(Document document) throws IOException{
        
        URL url = XmlUtils.class.getClassLoader().getResource(filename);
        String realpath = url.getPath();
        
        OutputFormat format = OutputFormat.createPrettyPrint();
        XMLWriter writer = new XMLWriter(new FileOutputStream(realpath), format );
        writer.write( document );
        writer.close();

    }
    
}
View Code

  3.4  开发测试类 UserDaoTest

package junit.test;
import java.util.Date;

import org.junit.Test;

import com.lich.dao.UserDao;
import com.lich.dao.impl.UserDaoXmlImpl;
import com.lich.domain.User;

public class UserDaoTest {
    @Test
    public void testAdd(){
        User user = new User();
        user.setId("1002");
        user.setUsername("bbb");
        user.setPassword("123");
        user.setEmail("bb@sina.com");
        
        Date date = new Date();
        user.setBirthday(date);
        
        UserDao dao = new UserDaoXmlImpl();
        dao.add(user);
        
    }
    @Test
    public void testFind(){
        UserDao dao = new UserDaoXmlImpl();
        User user = dao.find("aaa","123");
        System.out.println(user);
    }
    @Test
    public void testFindByUsername(){
        UserDao dao = new UserDaoXmlImpl();
        User user = dao.find("sss");
        System.out.println(user);
    }
}
View Code

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

  4.1  开发BusinessService
             public void registerUser(User user) throws UserExistException
             public User loginUser(String username,String password);

package com.lich.service.impl;

import com.lich.dao.UserDao;
import com.lich.dao.impl.UserDaoXmlImpl;
import com.lich.domain.User;
import com.lich.exception.UserExistException;
import com.lich.service.BusinessService;

//根据需求分析
public class BusinessServiceImpl implements BusinessService {
    
    UserDao dao = new UserDaoXmlImpl();
    //提供注册信息
    /* (non-Javadoc)
     * @see com.lich.service.impl.BusinessService#registerUser(com.lich.domain.User)
     */
    public void registerUser(User user) throws UserExistException{
        if( dao.find(user.getUsername())!=null){
            //抛编译时异常:目的为了上一层程序处理这个异常,给用户友好提示.
            throw new UserExistException("注册的用户已存在!!!");
        }
        dao.add(user);
    }
    /* (non-Javadoc)
     * @see com.lich.service.impl.BusinessService#loginUser(java.lang.String, java.lang.String)
     */
    public User loginUser(String username,String password){
        return dao.find(username, password);
    }
}
View Code

     4.2  抽取接口

package com.lich.service;

import com.lich.domain.User;
import com.lich.exception.UserExistException;

public interface BusinessService {

    //提供注册信息
    void registerUser(User user) throws UserExistException;

    User loginUser(String username, String password);

}
View Code

5、开发web层
     5.1 开发注册

    5.1.1  写一个RegisterUIServlet为用户提供注册界面,它收到请求,跳到register.jsp

package com.lich.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;

public class RegisterUIServlet extends HttpServlet {

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

            request.getRequestDispatcher("/WEB-INF/jsp/register.jsp").forward(
                request, response);

    }

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

}
View Code

    5.1.2  写register.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>用户注册</title>
  </head>
  
  <body style="text-align: center;">
    
    <form action="${pageContext.request.contextPath}/servlet/RegisterServlet" method="post">
    
    <table width="60%" border="1" >
        <tr>
            <td>用户名</td>
            <td>
                <input type="text" name="username" value="${formbean.username }">${formbean.errors.username }
            </td>
        </tr>
        
        <tr>
            <td>密码</td>
            <td>
                <input type="password" name="password" value="${formbean.password }">${formbean.errors.password }
            </td>
        </tr>
        
        <tr>
            <td>确认密码</td>
            <td>
                <input type="password" name="password2" value="${formbean.password2 }">${formbean.errors.password2 }
            </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>
View Code

   

   5.1.3  register.jsp提交请求,交给RegisterServlet处理

package com.lich.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 com.lich.domain.User;
import com.lich.exception.UserExistException;
import com.lich.service.BusinessService;
import com.lich.service.impl.BusinessServiceImpl;
import com.lich.utils.WebUtils;
import com.lich.web.formbean.RegisterFormBean;

public class RegisterServlet extends HttpServlet {

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

        RegisterFormBean formbean = WebUtils.request2Bean(request,RegisterFormBean.class);
        // 表单校验
        if (formbean.validate() == false) {
            request.setAttribute("formbean", formbean);
            request.getRequestDispatcher("/WEB-INF/jsp/register.jsp").forward(
                    request, response);
            return;
        }

        //把表单的数据填充到javabean中
        User user = new User();
        
        try {
            //注册字符串到日期的转换器
            ConvertUtils.register(new DateLocaleConverter(), Date.class);
            BeanUtils.copyProperties(user, formbean);
            user.setId(WebUtils.makeId());
            BusinessService service = new BusinessServiceImpl();
            service.registerUser(user);
            
            request.setAttribute("message", "注册成功!!");
            request.getRequestDispatcher("/message.jsp").forward(request, response);
            
        }catch (UserExistException e) {
            formbean.getErrors().put("username", "注册用户已存在!!");
            request.setAttribute("formbean", formbean);
            request.getRequestDispatcher("/WEB-INF/jsp/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);
    }

}
View Code

    5.1.4  写RegisterServlet注意:

       a.设计用于校验表单数据RegisterFormbean

package com.lich.web.formbean;

import java.util.HashMap;
import java.util.Map;

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


public class RegisterFormBean {

    private String username;
    private String password;
    private String password2;
    private String email;
    private String birthday;
    
    private Map<String,String> errors = new HashMap();
    
    
    public Map<String, String> getErrors() {
        return errors;
    }
    public void setErrors(Map<String, String> errors) {
        this.errors = errors;
    }
    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 getPassword2() {
        return password2;
    }
    public void setPassword2(String password2) {
        this.password2 = password2;
    }
    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;
    }
    
    /*
    private String username;  用户名不能为空,并且要是3-8的字符 abcdABcd
    private String password;  密码不能为空,并且要是3-8的数字
    private String password2; 两次密码要一致
    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]{3,8}")){
                isOk = false;
                errors.put("username", "用户名必须是3-8位的字母!!");
            }
        }
        
        
        if(this.password==null || this.password.trim().equals("")){
            isOk = false;
            errors.put("password", "密码不能为空!!");
        }else{
            if(!this.password.matches("\\d{3,8}")){
                isOk = false;
                errors.put("password", "密码必须是3-8位的数字!!");
            }
        }
        
        //private String password2; 两次密码要一致
        if(this.password2!=null){
            if(!this.password2.equals(this.password)){
                isOk = false;
                errors.put("password2", "两次密码不一致!!");
            }
        }
        
        //private String email;     可以为空,不为空要是一个合法的邮箱
        // flx_itcast@sina.com.cn
        if(this.email!=null){
            if(!this.email.matches("\\w+@\\w+(\\.\\w+)+")){
                isOk = false;
                errors.put("email", "邮箱不是一个合法邮箱!!");
            }
        }
        
        
        //private String birthday;  可以为空,不为空时,要是一个合法的日期
        if(this.birthday!=null){
            try{
                DateLocaleConverter conver = new DateLocaleConverter();
                conver.convert(this.birthday);
            }catch (Exception e) {
                isOk = false;
                errors.put("birthday", "生日必须要是一个日期!!");
            }
        }
        
        return isOk;
    }
    
}
View Code

       b.写WebUtils工具类,封装请求数据到formbean中

package com.lich.utils;

import java.util.Enumeration;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.BeanUtils;


把request对象中的请求参数封装到bean中
public class WebUtils {
    //用一个对象来接受处理请求,传给一个类字节码来创建类接收.使用泛型来应对调用
    public static <T> T request2Bean(HttpServletRequest request,Class<T> clazz){
        try{        
            T bean = clazz.newInstance();
            //username=aa password=bb email=aa@sina.com
            Enumeration e = request.getParameterNames(); 
            while(e.hasMoreElements()){
                String name = (String) e.nextElement();  //username=aaa password=123
                String value = request.getParameter(name);
                BeanUtils.setProperty(bean, name, value);
            }
            return bean;
        }catch (Exception e) {
            throw new RuntimeException(e);
        }
        
    }
    /*
     *自动产生唯一用户编号ID
     */
    public static String makeId(){
        //UUID   128 36位字符        
        return UUID.randomUUID().toString();
    }
    
}
View Code

                   c、如果校验失败跳回到register.jsp,并回显错误信息

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

  5.2 开发登陆

    5.2.1      写一个LoginUIServlet为用户提供注册界面,它收到请求,跳到login.jsp

 

package com.lich.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;

public class LoginUIServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,
                response);

    }

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

        doGet(request, response);
    }

}
View Code
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<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>
View Code

    5.2.2      login.jsp提交给LoginServlet处理登陆请求

 

   

 

package com.lich.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 com.lich.domain.User;
import com.lich.service.BusinessService;
import com.lich.service.impl.BusinessServiceImpl;

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");
            
            BusinessService service = new BusinessServiceImpl();
            User user = service.loginUser(username, password);
            if(user==null){
                request.setAttribute("message", "对不起,用户名或密码有误!!");
                request.getRequestDispatcher("/message.jsp").forward(request, response);
                return;
            }
            
            request.getSession().setAttribute("user", user);
            request.setAttribute("message", "恭喜:"+user.getUsername()+",登陆成功!本页将在5秒后跳到首页!!<meta http-equiv='refresh' content='5;url=/UserLogin/index.jsp'");
            request.getRequestDispatcher("/message.jsp").forward(request, response);
        }

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

            doGet(request, response);
        }


}
View Code

其它 开发中常见:

① 自定义异常包: com.lich.exception.UserExistException

package com.lich.exception;

public class UserExistException extends Exception {

    public UserExistException() {
        super();
        // TODO Auto-generated constructor stub
    }

    public UserExistException(String message, Throwable cause,
            boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
        // TODO Auto-generated constructor stub
    }

    public UserExistException(String message, Throwable cause) {
        super(message, cause);
        // TODO Auto-generated constructor stub
    }

    public UserExistException(String message) {
        super(message);
        // TODO Auto-generated constructor stub
    }

    public UserExistException(Throwable cause) {
        super(cause);
        // TODO Auto-generated constructor stub
    }

}
View Code

② 全局消息显示页面 message.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>全局消息显示页面</title>
  </head>
  
  <body>
    ${message }
  </body>
</html>
View Code

③ 简单网站首页 index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>首页</title>
    <script type="text/javascript">
        function doLogout(){
            window.location.href="${pageContext.request.contextPath}/servlet/LogoutServlet";
        }
    
    </script>
    
  </head>
  
  <body>
       
       <h1>XX网站</h1>
       <br/><br/>
       <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 }&nbsp;
       
       <input type="button" value="退出登陆" onclick="doLogout()">
   </c:if>
           
       <hr/>
  </body>
</html>
View Code

④ 注销页面LogoutServlet

package com.lich.web.UI;

import java.io.IOException;
import java.io.PrintWriter;

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 {

        request.getSession().removeAttribute("user");

        request.setAttribute("message", "注销成功,本页将在5秒后跳到首页!!<meta http-equiv='refresh' content='5;url=/UserLogin/index.jsp'");
        request.getRequestDispatcher("/message.jsp").forward(request, response);
    }

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

        doGet(request, response);
    }

}
View Code

 

 总结:该网站虽然简单,但涵盖开发中使用的三层架构中心思想,认真领会MVC开发模式,学与思相结合,不断practice,相信编码水平会有质的提高.

转载于:https://www.cnblogs.com/lichone2010/archive/2013/06/16/3138264.html

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值