JavaWeb了解之入门篇5(入门练习)

目录

1. 新建JavaWeb项目、导入jar包

新建JavaWeb项目

项目目录

dom4j.jar =>操作XML文件
jaxen-xxx.jar =>解析XPath表达式
commons-beanutils-xxx.jar => 工具类,用于处理bean对象
commons-logging.jar => commons-beanutils-xxx.jar的依赖包
taglibs-standard-jstlel-1.2.5 => jstl标签库和EL表达式依赖包
commons-collections.jar

jar包,存放于WEB_INF的lib目录下

2. 新建jsp

WEB-INF 下
    index.jsp
    message.jsp

WEB-INF 下建立pages目录 +
    login.jsp
    register.jsp

index.jsp

<%@ page language="java"  pageEncoding="UTF-8"%>
<%--为了避免在jsp页面中出现java代码,这里引入jstl标签库,利用jstl标签库提供的标签来做一些逻辑判断处理 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>


  
    首页
     
  
  
    

网站


注册 登陆 欢迎您:${user.userName}

message.jsp

<%@ page language="java" pageEncoding="UTF-8"%>


  
    全局消息显示页面
  
  
    ${message}
  

login.jsp

<%@ page language="java" pageEncoding="UTF-8"%>


  
    用户登陆
  
  
    
用户名:
密码:

register.jsp

<%@ page language="java" pageEncoding="UTF-8"%>


    
        用户注册
    
    
        
用户名 <%--使用EL表达式${}提取存储在request对象中的formbean对象中封装的表单数据(formbean.userName)以及错误提示消息(formbean.errors.userName)--%> ${formbean.errors.userName}
密码 ${formbean.errors.userPwd}
确认密码 ${formbean.errors.confirmPwd}
邮箱 ${formbean.errors.email}
生日 ${formbean.errors.birthday}

3. 创建java类

开发顺序

domain→          模型层
dao→             数据库接口层
dao.impl→        数据库实现层
service→         服务(逻辑处理)接口层
service.impl→    服务实现层
web.UI→          跳转jsp层(放在WEB-INF下外界通过url访问不到)
web.controller→  处理jsp逻辑层
web.filter→      过滤层
web.listener→    监听层
util→            工具层
junit.test
exception        异常层
web.formbean     表单验证层
  1. 模型层

建包com.sst.cx.domain
新建User.java

package com.sst.cx.domain;
import java.util.Date;
public class User {
       private static final long serialVersionUID = -4313782718477229465L;
        // 用户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;
        }
}
  1. 数据库接口层

建包com.sst.cx.dao
新建IUserDao.java

package com.sst.cx.dao;
import com.sst.cx.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);
}
  1. 数据库实现层

建包com.sst.cx.dao.impl
新建UserDaoImpl.java

package com.sst.cx.dao.impl;
import java.text.SimpleDateFormat;
import org.dom4j.Document;
import org.dom4j.Element;
import com.sst.cx.dao.IUserDao;
import com.sst.cx.domain.User;
import com.sst.cx.util.XmlUtils;
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.addAttribute("id", user.getId());
                user_node.addAttribute("userName", user.getUserName());
                user_node.addAttribute("userPwd", user.getUserPwd());
                user_node.addAttribute("email", user.getEmail());
                SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
                user_node.addAttribute("birthday", sdf.format(user.getBirthday()));
                XmlUtils.write2Xml(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);
            }
        }
}
  1. 服务(逻辑处理)接口层

建包com.sst.cx.service
新建IUserService.java

package com.sst.cx.service;
import com.sst.cx.domain.User;
import com.sst.cx.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);
}
  1. 服务实现层

建包com.sst.cx.service.impl
新建UserServiceImpl.java

package com.sst.cx.service.impl;
import com.sst.cx.dao.IUserDao;
import com.sst.cx.dao.impl.UserDaoImpl;
import com.sst.cx.domain.User;
import com.sst.cx.exception.UserExistException;
import com.sst.cx.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);
    }
}
  1. web.UI

建包com.sst.cx.web.UI
新建LoginUIServlet.java

package com.sst.cx.web.UI;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/LoginUIServlet")
public class LoginUIServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    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);
    }
}

新建RegisterUIServlet.java

package com.sst.cx.web.UI;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/RegisterUIServlet")
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);
    }
}
  1. 处理jsp逻辑层

建包com.sst.cx.web.controller
新建LoginServlet.java

package com.sst.cx.web.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sst.cx.domain.User;
import com.sst.cx.service.IUserService;
import com.sst.cx.service.impl.UserServiceImpl;
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
       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(
                        "对不起,用户名或密码有误!!请重新登录!2秒后为您自动跳到登录页面!!

新建LogoutServlet.java

package com.sst.cx.web.controller;
import java.io.IOException;
import java.text.MessageFormat;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/LogoutServlet")
public class LogoutServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
       public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 移除存储在session中的user对象,实现注销功能
            request.getSession().removeAttribute("user");
            // 由于字符串中包含有单引号,在这种情况下使用MessageFormat.format方法拼接字符串时就会有问题
            // MessageFormat.format方法只是把字符串中的单引号去掉,不会将内容填充到指定的占位符中
            String tempStr1 = MessageFormat.format(
                    "注销成功!!3秒后为您自动跳到登录页面!!", 
                    request.getContextPath()+"/LoginUIServlet");
            System.out.println(tempStr1);//输出结果:注销成功!!3秒后为您自动跳到登录页面!!
            System.out.println("---------------------------------------------------------");
            /**
             * 要想解决"如果要拼接的字符串包含有单引号,那么MessageFormat.format方法就只是把字符串中的单引号去掉,不会将内容填充到指定的占位符中"这个问题,
             * 那么可以需要使用单引号引起来的字符串中使用2个单引号引起来,例如:""
             * 这样MessageFormat.format("","index.jsp")就可以正常返回
             * 
             */
            String tempStr2 = MessageFormat.format(
                    "注销成功!!3秒后为您自动跳到登录页面!!", 
                    request.getContextPath()+"/LoginUIServlet");
            /**
             * 输出结果:
             * 注销成功!!3秒后为您自动跳到登录页面!!
             * 
             */
            System.out.println(tempStr2);
            String message = String.format(
                    "注销成功!!3秒后为您自动跳到登录页面!!", 
                    request.getContextPath()+"/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);
        }
}

新建RegisterServlet.java

package com.sst.cx.web.controller;
import java.io.IOException;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
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.sst.cx.domain.User;
import com.sst.cx.exception.UserExistException;
import com.sst.cx.service.IUserService;
import com.sst.cx.service.impl.UserServiceImpl;
import com.sst.cx.util.WebUtils;
import com.sst.cx.web.formbean.RegisterFormBean;
@WebServlet("/RegisterServlet")
public class RegisterServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    /**
         1、接收客户端提交到服务端的表单数据。
      2、校验表单数据的合法性,如果校验失败跳回到register.jsp,并回显错误信息。
      3、如果校验通过,调用service层向数据库中注册用户。
     */
       public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 将客户端提交的表单数据封装到RegisterFormBean对象中
            RegisterFormBean formbean = WebUtils.request2Bean(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(
                        "注册成功!!3秒后为您自动跳到登录页面!!", 
                        request.getContextPath()+"/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);
        }
}
  1. jsp验证层

建包com.sst.cx.web.formbean
新建RegisterFormBean.java

package com.sst.cx.web.formbean;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
public class RegisterFormBean {
    // RegisterFormBean中的属性与register.jsp中的表单输入项的name一一对应
    //
    private String userName;
    //
    private String userPwd;
    //
    private String confirmPwd;
    //
    private String email;
    //
    private String birthday;    
    /**
     * 存储校验不通过时给用户的错误提示信息
     */
    private Map errors = new HashMap();
    public Map getErrors() {
        return errors;
    }
    public void setErrors(Map errors) {
        this.errors = errors;
    }
    /*
     * validate方法负责校验表单输入项
     * 表单输入项校验规则:
     *         private String userName; 用户名不能为空,并且要是3-8的字母 abcdABcd 
     *         private String userPwd; 密码不能为空,并且要是3-8的数字
     *         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]{3,8}")) {
                isOk = false;
                errors.put("userName", "用户名必须是3-8位的字母!!");
            }
        }
        if (this.userPwd == null || this.userPwd.trim().equals("")) {
            isOk = false;
            errors.put("userPwd", "密码不能为空!!");
        } else {
            if (!this.userPwd.matches("\\d{3,8}")) {
                isOk = false;
                errors.put("userPwd", "密码必须是3-8位的数字!!");
            }
        }
        // private String password2; 两次密码要一致
        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;
    }
}
  1. 工具层

建包com.sst.cx.util
新建WebUtils.java

package com.sst.cx.util;
import java.util.Enumeration;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.beanutils.BeanUtils;
// 封装客户端提交的表单数据到formbean中
public class WebUtils {
    /**
     * 将request对象转换成T对象
     * @param request 
     * @param clazz
     * @return
     */
    public static  T request2Bean(HttpServletRequest request,Class clazz){
        try{
            T bean = clazz.newInstance();
            Enumeration 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();
    }
}

新建XmlUtils.java

package com.sst.cx.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
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 = "DB.xml";
    public static Document getDocument() throws DocumentException{
        URL url = XmlUtils.class.getClassLoader().getResource(filename);
        String realpath = url.getPath();
        File file = null;
        try {
            file = new File(URLDecoder.decode(realpath,"UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        SAXReader reader = new SAXReader();
        return reader.read(file);
    }
    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(URLDecoder.decode(realpath,"UTF-8")), format );
        writer.write( document );
        writer.close();

    }
}
  1. 异常层

建包com.sst.cx.exception
新建UserExistException.java

package com.sst.cx.exception;
public class UserExistException extends Exception{
    public UserExistException() {
        super();
    }
    public UserExistException(String message, Throwable cause) {
        super(message, cause);
    }
    public UserExistException(String message) {
        super(message);
    }
    public UserExistException(Throwable cause) {
        super(cause);
    }
    
}

src下新建DB.XML




其他

出错了,查一下出错的原因,可能需要导入其他jar包.重启Tomcat
 org.dom4j.DocumentException找不到xml
URLDecoder.decode(realpath,"UTF-8")

你可能感兴趣的:(JavaWeb了解之入门篇5(入门练习))