day0910 JSP 与案例

Author:相忠良
Email: [email protected]
起始于:May 2, 2018
最后更新日期:May 12, 2018

声明:本笔记依据传智播客方立勋老师 Java Web 的授课视频内容记录而成,中间加入了自己的理解。本笔记目的是强化自己学习所用。若有疏漏或不当之处,请在评论区指出。谢谢。
涉及的图片,文档写完后,一次性更新。

day0910 JSP 与案例

1. jsp 与 javabean

新建 day09 web 项目。

什么是 JavaBean?
答:JavaBean通常用于封装数据,它是遵循特定写法的java类,通常有如下特点:

  • 这个java类必须有一个无参构造函数;
  • 属性必须私有化;
  • 私有化属性必须由public类型的setter或getter方法暴露给其他程序,且方法命名需遵守一定的命名规范。

jsp 提供了三个关于 JavaBean 组件的动作元素,即 jsp 标签,分别为:

  • <jsp:useBean>:用于在 jsp 页面中查找或实例化1个 JavaBean 组件;
  • <jsp:setProperty>:相当于 setter 方法;
  • <jsp:getProperty>:相当于 getter 方法。

jsp中通过使用<jsp:useBean>标签,返回1个 JavaBean 对象(若对象存在,返回该对象,若不存在就 new 1个新的 JavaBean 对象并存到指定域中)。

在 cn.wk.domain 包中建立 Person 类:

package cn.wk.domain;

public class Person {
    private String name = "张三";
    private int age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

新建 1.jsp 文件,代码如下:

<body>
  <jsp:useBean id="person" class="cn.wk.domain.Person" scope="page"></jsp:useBean>
  <%=person.getName() %>
</body>

上面代码,从 page 域查找 person 对象,若无则建。
查看 1.jsp 翻译后的java代码片段,如下:

cn.wk.domain.Person person = null;

person = (cn.wk.domain.Person) _jspx_page_context.getAttribute("person", javax.servlet.jsp.PageContext.PAGE_SCOPE);
if (person == null){
  person = new cn.wk.domain.Person();
  _jspx_page_context.setAttribute("person", person, javax.servlet.jsp.PageContext.PAGE_SCOPE);
}

浏览器打开1.jsp,查看结果。

<jsp:useBean>标签的内容只在创建 JavaBean 实例的时候才执行。如下:

<body>
  <jsp:useBean id="person" class="cn.wk.domain.Person" scope="session">
    bbbbb  <%-- 此处只有创建 javabean 实例时才执行 --%>
  </jsp:useBean>

  <%=person.getName() %>
</body>

注意,上面代码 scope="session",意味着只要会话不关闭,person 对象就一直存在。若存在的话,<jsp:useBean>标签的内容就不会再次执行。

2.jsp涉及4个内容:

  • 手工为bean属性赋值;
  • 用请求参数给bean的属性赋值;
  • 用所有请求参数为 bean 的属性赋值;
  • jsp:getProperty标签直接输出。

2.jsp如下:

<body>
  <jsp:useBean id="person" class="cn.wk.domain.Person"/>

  <!-- 手工为 bean 属性赋值 -->
  <jsp:setProperty name="person" property="name" value="xxxx"/>
  <%=person.getName() %><br/>

  <!-- 用请求参数给bean的属性赋值 -->
  <!-- http://localhost:8080/day09/2.jsp?name=uuu&age=18 -->
  <jsp:setProperty property="name" name="person" param="name"/>
  <jsp:setProperty property="age" name="person" param="age"/>
  <%=person.getName() %><br/>
  <%=person.getAge() %><br/>

  <br/>---------------------------<br/>

  <!-- 用所有请求参数为 bean 的属性赋值 -->
  <jsp:setProperty property="*" name="person"/>
  <%=person.getName() %><br/>
  <%=person.getAge() %><br/>

  <!-- getProperty标签输出为字符串,为空时输出 null 字符串 -->
  <jsp:getProperty property="name" name="person"/><br/>
  <jsp:getProperty property="age" name="person"/>

</body>

注意:getProperty标签输出为字符串,为空时输出 null 字符串。

2. jsp 开发模式和 web 计算器案例

jsp 开发模式:

  • jsp + javabean
  • servlet + jsp + javabean

double 不能进行精确货币运算,BigDecimal 可进行精确货币运算。如下:

// 不精确计算
// double a=0.1;
// double b=0.006;
// System.out.println(a+b);

// 精确计算
BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.006");
System.out.println(a.add(b));
System.out.println(a.divide(b, 10, BigDecimal.ROUND_CEILING));

web 计算器完整案例如下:

cn.wk.domain.CulculatorBean 类如下:

public class CulculatorBean {
    private String firstNum = "0";
    private char operator = '+';
    private String secondNum = "0";
    private String result;

    public void calculate() {
        BigDecimal firstNum = new BigDecimal(this.firstNum);
        BigDecimal secondNum = new BigDecimal(this.secondNum);
        switch (this.operator) {
        case '+': {
            this.result = firstNum.add(secondNum).toString();
            break;
        }
        case '-': {
            this.result = firstNum.subtract(secondNum).toString();
            break;
        }
        case '*': {
            this.result = firstNum.multiply(secondNum).toString();
            break;
        }
        case '/': {
            if (secondNum.doubleValue() == 0) {
                throw new RuntimeException("除数为0!");
            }
            this.result = firstNum.divide(secondNum, 10,
                    BigDecimal.ROUND_HALF_UP).toString();
            break;
        }

        default:
            throw new RuntimeException("运算符错误!");
        }
    }

    public String getFirstNum() {
        return firstNum;
    }

    public void setFirstNum(String firstNum) {
        this.firstNum = firstNum;
    }

    public char getOperator() {
        return operator;
    }

    public void setOperator(char operator) {
        this.operator = operator;
    }

    public String getSecondNum() {
        return secondNum;
    }

    public void setSecondNum(String secondNum) {
        this.secondNum = secondNum;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }
}

calculator.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>
    <jsp:useBean id="calculator" class="cn.wk.domain.CulculatorBean" scope="page"/>
    <jsp:setProperty property="*" name="calculator"/>
    <%
        try {
            calculator.calculate();
        } catch (Exception e) {
            out.write(e.getMessage());
        }
    %>

    <br/>-----------------------------------------------<br/>
    计算结果是:<jsp:getProperty property="firstNum" name="calculator"/>
    <jsp:getProperty property="operator" name="calculator"/>
    <jsp:getProperty property="secondNum" name="calculator"/>
    =
    <jsp:getProperty property="result" name="calculator"/>
    <br/>-----------------------------------------------<br/>   

  <form action="/day09/calculator.jsp" method="post">
    <table width=40% border="1">
        <tr>
            <td colspan="2">简单的计算器</td>
        </tr>

        <tr>
            <td>第一个参数</td>
            <td>
                <input type="text" name="firstNum">
            </td>
        </tr>

        <tr>
            <td>操作符</td>
            <td>
                <select name="operator">
                    <option value="+">+</option>
                    <option value="-">-</option>
                    <option value="*">*</option>
                    <option value="/">/</option>
                </select>
            </td>
        </tr>

        <tr>
            <td>第二个参数</td>
            <td>
                <input type="text" name="secondNum">
            </td>
        </tr>

        <tr>
            <td colspan="2">
                <input type=submit value="计算">
            </td>
        </tr>       
    </table>
    </form>
  </body>
</html>

3. MVC 开发模式

下图为 mvc 开发模式图,也包含了三层架构。
1

上图中为方便层的分离,设立了dao 接口,service接口。
因jsp是view,用户直接访问的话,并无数据。所以应将jsp保护起来,保护方法是在 WEB-INF 目录下建立jsp目录,并将jsp文件放入该目录。
上图又展示了各种包名。
针对 jsp 页面中不能写 java 代码的要求,就需用到 EL 表达式和 jstl。后面学它们。

4. EL 表达式和 JSTL 快速入门

EL表达式:用来输出数据。

关于EL的列子,day09项目的 3.jsp 和 javabean 文件 Person.java:

<body>
  <%
    String data="aaa";
    request.setAttribute("data", data);
  %>

  ${data} <%-- 相当于 pageContext.findArrtibute("data"); page->reuquest->session->application --%>
</body>
package cn.wk.domain;

public class Person {
    private String name="张三";
    private int age;

    public Person() {
        super();
    }
    public Person(String name) {
        super();
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

例:用 jstl + el 完成集合迭代,4.jsp:
涉及使用指令<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>,它可从工程中的JSTL 1.2.1 Libraryjstl-impl.jarWEB-INF目录中c.tld文件中的<uri>标签中找到。

<%@ page language="java" import="java.util.*,cn.wk.domain.Person"
    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>使用jstl+el完成集合迭代</title>
</head>

<body>
    <!-- 迭代list集合 -->
    <%
        List list = new ArrayList();
        list.add(new Person("zhang6"));
        list.add(new Person("zhang4"));
        list.add(new Person("zhang5"));

        request.setAttribute("list", list);
    %>

    <c:forEach var="person" items="${list}">
        ${person.name}<br />
    </c:forEach>

    <br />-----------------------------------<br />

    <!-- 迭代map集合 -->
    <%
        Map map = new LinkedHashMap();
        map.put("aa", new Person("aaaa"));
        map.put("bb", new Person("bbbb"));
        map.put("cc", new Person("cccc"));
        map.put("dd", new Person("dddd"));
        map.put("11", new Person("eeee")); // 这可能出问题,看下面解决方法

        request.setAttribute("map", map);
    %>

    <c:forEach var="entry" items="${map}">
        ${entry.key} : ${entry.value.name}<br />
    </c:forEach>

</body>
</html>

关于 if 的标签:

<!-- 代表用户登录了 -->
<c:if test="${user!=null}">欢迎您:${user.username}</c:if>

<c:if test="${user==null}">
  用户名:<input type="text"> <br />
  密码:<input type="text">
</c:if>

5. mvc 案例

项目名字:day09_user
功能:开发一个用户注册和登录功能,数据库用users.xml文件模拟。
方立勋老师提示:“Web 应用不管哪个模块的开发,其实都大同小异,希望所有同学通过这个用户模块,掌握一个软件的开发步骤,并认真体会软件三层架构开发思想!!!!!并且课后一定要自己动手去写!!!”

  1. 搭建开发环境
    1.1 导开发包:
    -- dom4j(dom4j-1.6.1.jar)
    -- jstl(我电脑建工程时自带)
    -- beanUtils(commons-beanutils-1.7.0.jar)
    -- log4j(commons-logging-1.1.jar)
    1.2 创建组织程序包:
    -- cn.wk.domain
    -- cn.wk.dao
    -- cn.wk.dao.impl
    -- cn.wk.service
    -- cn.wk.service.impl
    -- cn.wk.web.controller (处理请求的servlet)
    -- cn.wk.web.UI (为用户提供用户界面)
    -- cn.wk.utils
    -- junit.test
    -- WEB-INF/jsp 目录保存网站所有的 jsp
    1.3 创建代表数据库的xml文件
    -- 在类目录下创建一个代表数据库的users.xml文件

5.1 代码目录结构

2

3

代码思路待整理。

5.2 WebRoot中的代码

3

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>
</head>

<body style="text-align:center;">

    <h1>xxxx网站</h1>
    <br />
    <div style="text-align:right;">
        <c:if test="${user!=null}">
        欢迎您:${user.nickname} <a href="${pageContext.request.contextPath}/servlet/LogoutServlet">注销</a>
        </c:if>

        <c:if test="${user==null}">
            <a
                href="${pageContext.request.contextPath}/servlet/RegisterUIServlet">注册</a>
            <a href="${pageContext.request.contextPath}/servlet/LoginUIServlet">登录</a>
        </c:if>
    </div>
    <hr>

</body>
</html>

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>

login.jsp如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>登录界面</title>
<%-- <link tpye="text/css" rel="stylesheet"
    href="${pageContext.request.contextPath}/css/login.css"> 加css--%>
</head>

<body>
    <div id="container">
        <div id="image">
            <div id="form">
                <form action="${pageContext.request.contextPath}/servlet/LoginServlet" method="post">
                    <div class="input">
                        用户:<input class="inputtext" type="text" name="username" />
                    </div>

                    <div class="input">
                        密码:<input class="inputtext" type="password" name="password" />
                    </div>

                    <div id="btn">
                        <input class="btn" type="button" value="注册"
                            onclick="window.location.href='register.jsp'" />
                        <input class="btn" type="submit" value="登录" />
                    </div>
                </form>
            </div>
        </div>
    </div>
</body>
</html>

register.jsp如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312"/> <!-- 这可能是个坑 -->
<title>注册界面</title>
</head>

<body>
    <div id="header">
        这是页头,可添加图片<img src="">
    </div>

    <div id="main">
        <div id="notice">
            <h2>注册须知:</h2>
            1. 需遵守法律; 2. 在本网站发表的文章,本站都具有最终编辑权。
        </div>

        <form
            action="${pageContext.request.contextPath}/servlet/RegisterServlet"
            method="post">

            <table id="formtable">
                <tr>
                    <td>登录账号:</td>
                    <td>
                        <input type="text" name="username" value="${form.username}">
                        <span>${form.errors.username}</span>
                    </td>
                </tr>

                <tr>
                    <td>密码:</td>
                    <td>
                        <input type="password" name="password" value="${form.password}">
                        <span>${form.errors.password}</span>
                    </td>
                </tr>

                <tr>
                    <td>确认密码:</td>
                    <td>
                        <input type="password" name="password2" value="${form.password2}">
                        <span>${form.errors.password2}</span>
                    </td>
                </tr>

                <tr>
                    <td>电子邮箱:</td>
                    <td>
                        <input type="text" name="email" value="${form.email}">
                        <span>${form.errors.email}</span>
                    </td>
                </tr>

                <tr>
                    <td>生日:</td>
                    <td>
                        <input type="text" name="birthday" id="birthday"
                        title="点击选择" onClick="showCalendar(this.id)" value="${form.birthday}">
                        <span>${form.errors.birthday}</span>
                    </td>
                </tr>

                <tr>
                    <td>您的昵称:</td>
                    <td>
                        <input type="text" name="nickname" value="${form.nickname}">

                        <span>${form.errors.nickname}</span>
                    </td>
                </tr>

                <tr>
                    <td>图片认证:</td>
                    <td><input type="text" name="checkcode"><img src="#" height="20px"></td>
                </tr>
            </table>

            <div id="formsubmit">
                <span><input type="reset" name="reset" value="重 置"></span>
                &nbsp;&nbsp; <span><input type="submit" name="submit"
                    value="注 册"></span>
            </div>

        </form>
    </div>

    <div id="footer">这是页脚,也可添加图片</div>
</body>
</html>

5.3 src目录中的代码

2

模拟数据库的 users.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<users>
    <user id="20160918" username="aaa" password="123" email="[email protected]" birthday="1980-09-09"
        nickname="小强" />
</users>

UserDao:

package cn.wk.dao;
public interface UserDao {

    void add(User user);

    User find(String username, String password);

    // 查找注册的用户是否在数据库中存在
    boolean find(String username);
}

UserDaoImpl:

package cn.wk.dao.impl;

public class UserDaoImpl implements UserDao {
    public void add(User user) {
        try {
            Document document = XmlUtils.getDocument();
            Element root = document.getRootElement();

            Element user_tag = root.addElement("user");
            user_tag.setAttributeValue("id", user.getId());
            user_tag.setAttributeValue("username", user.getUsername());
            user_tag.setAttributeValue("password", user.getPassword());
            user_tag.setAttributeValue("email", user.getEmail());
            user_tag.setAttributeValue("birthday",
                    user.getBirthday() == null ? "" : user.getBirthday()
                            .toLocaleString());
            user_tag.setAttributeValue("nickname", user.getNickname());

            XmlUtils.write2Xml(document);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public User find(String username, String password) {
        try {
            Document document = XmlUtils.getDocument();
            // 从所有的user标签中查找用户应和密码匹配的
            Element e = (Element) document
                    .selectSingleNode("//user[@username='" + username
                            + "' and @password='" + password + "']");
            if (e == null)
                return null;

            User user = new User();
            String date = e.attributeValue("birthday"); // "" 1980-09-09
            if (date == null || date.equals("")) {
                user.setBirthday(null);
            } else {
                SimpleDateFormat df = new SimpleDateFormat("yyyy-mm-dd");
                user.setBirthday(df.parse(date));
            }

            user.setEmail(e.attributeValue("email"));
            user.setId(e.attributeValue("id"));
            user.setNickname(e.attributeValue("nickname"));
            user.setPassword(e.attributeValue("password"));
            user.setUsername(e.attributeValue("username"));
            return user;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // 查找注册的用户是否在数据库中存在
    public boolean find(String username) {
        try {
            Document document = XmlUtils.getDocument();

            Element e = (Element) document
                    .selectSingleNode("//user[@username='" + username + "']");
            if (e == null)
                return false;
            else
                return true;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

User:

package cn.wk.domain;

import java.util.Date;

public class User {
    private String id;
    private String username;
    private String password;
    private String email;
    private Date birthday;
    private String nickname;

    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;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
}

UserExistException:

package cn.wk.exception;
public class UserExistException extends Exception {
    public UserExistException() {
        // 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
    }

    public UserExistException(String message, Throwable cause) {
        super(message, cause);
        // 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
    }
}

BusinessService:

package cn.wk.service;

public interface BusinessService {

    // 对web层提供注册服务
    void register(User user) throws UserExistException;

    // 对web层提供登录服务
    User login(String username, String password);
}

BusinessServiceImpl:

package cn.wk.service.impl;

// 对 web 层提供所有的业务服务
public class BusinessServiceImpl implements BusinessService {

    private UserDao dao = new UserDaoImpl(); // 可用工厂模式 或 spring 解耦,以后解耦

    // 对web层提供注册服务
    public void register(User user) throws UserExistException {
        // 先判断当前要注册的用户是否存在
        boolean b = dao.find(user.getUsername());
        if (b) {
            // 发现要注册的用户已存在,则给web层抛checked异常,提醒web层处理这个异常,给用户一个友好提示
            throw new UserExistException();
        } else {
            user.setPassword(ServiceUtils.md5(user.getPassword()));
            dao.add(user);
        }
    }

    // 对web层提供登录服务
    public User login(String username, String password) {// aaa 123
        password = ServiceUtils.md5(password);
        return dao.find(username, password);
    }
}

ServiceUtils:

package cn.wk.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import sun.misc.BASE64Encoder;

public class ServiceUtils {

    public static String md5(String message) {

        try {
            MessageDigest md = MessageDigest.getInstance("md5");
            byte[] md5 = md.digest(message.getBytes());

            BASE64Encoder encoder = new BASE64Encoder();
            return encoder.encode(md5);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
}

WebUtils:

package cn.wk.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;

public class WebUtils {

    // 传进来的类型是 T,该方法返回的对象类型也是 T,用到泛型
    public static <T> T request2Bean(HttpServletRequest request,
            Class<T> beanClass) {

        try {
            // 1. 创建要封装数据的bean
            T bean = beanClass.newInstance();

            // 2. 把request中数据整到bean中
            Enumeration e = request.getParameterNames();
            while(e.hasMoreElements()){
                //username password email birthday
                String name = (String) e.nextElement();
                // aaaa 123 [email protected] 1980-01-01
                String value = request.getParameter(name);
                BeanUtils.setProperty(bean, name, value);
            }
            return bean;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // 想把 form 转成 user
    public static void copyBean(Object src, Object dest){

        /*
        form:
        private String username;
        private String password;
        private String password2;
        private String email;
        private String birthday;
        private String nickname;
        private Map errors = new HashMap();

        user:
        private String id;
        private String username;
        private String password;
        private String email;
        private Date birthday;
        private String nickname;        
        */

        // 两个 bean 属性不同,需注册一个日期转换器
        ConvertUtils.register(new Converter() {
            @Override
            public Object convert(Class type, Object value) {
                if (value == null) {
                    return null;
                }
                String str = (String) value;
                if (str.trim().equals("")) {
                    return null;
                }

                // 此时无 1980-11-32 这种情况了
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                try {
                    return df.parse(str);
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
            }
        }, Date.class);

        try {
            BeanUtils.copyProperties(dest, src);
        } catch (Exception e) {         
            throw new RuntimeException(e);
        }
    }

    // 为user的id属性产生全球唯一的id
    public static String generateID(){
        return UUID.randomUUID().toString();
    }
}

XmlUtils:

package cn.wk.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;

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

public class XmlUtils {

    // 获取 xml 文件路径
    private static String filepath;
    static {
        filepath = XmlUtils.class.getClassLoader().getResource("users.xml")
                .getPath();
    }

    public static Document getDocument() throws Exception {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File(filepath));
        return document;
    }

    public static void write2Xml(Document document) throws Exception {
        // Pretty print the document to System.out
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(new FileOutputStream(filepath), format);
        writer.write(document);
        writer.close();
    }
}

LoginServlet:

package cn.wk.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 cn.wk.domain.User;
import cn.wk.service.impl.BusinessServiceImpl;

// 处理登录请求
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        BusinessServiceImpl service = new BusinessServiceImpl();
        User user = service.login(username, password);
        if (user != null) {
            // 登录成功后,session中存个登录标记
            request.getSession().setAttribute("user", user);
            // 跳转到首页
            response.sendRedirect(request.getContextPath() + "/index.jsp");
            return;
        }

        // 用户名 密码 不匹配
        request.setAttribute("message", "用户名或密码错误!!");
        request.getRequestDispatcher("/message.jsp").forward(request, response);
    }

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

LogoutServlet:

package cn.wk.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 javax.servlet.http.HttpSession;

// 处理用户注销请求
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");
        // 不创建新session,只得内存中的session
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.removeAttribute("user"); // 移除注销标记
        }

        // 注销成功,跳到全局消息显示页面,显示注销成功消息,并控制消息显示页面过3秒后跳到首页
        request.setAttribute("message",
                "注销成功,浏览器将在3秒后调至首页!!<meta http-equiv='refresh' content='3;url="
                        + request.getContextPath() + "/index.jsp'>");
        request.getRequestDispatcher("/message.jsp").forward(request, response);
    }

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

RegisterServlet:

package cn.wk.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 cn.wk.domain.User;
import cn.wk.exception.UserExistException;
import cn.wk.service.impl.BusinessServiceImpl;
import cn.wk.utils.WebUtils;
import cn.wk.web.formbean.RegisterForm;

// 处理注册请求
public class RegisterServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");

        // 1. 对提交表单的字段进行合法性校验(把表单数据封装到formbean)
        RegisterForm form = WebUtils.request2Bean(request, RegisterForm.class);
        boolean b = form.validate();

        // 2. 如果校验失败,跳回到表单页面,回显校验失败信息
        if(!b){
            request.setAttribute("form", form); // 传递错误消息
            request.getRequestDispatcher("/WEB-INF/jsp/register.jsp").forward(request, response);
            return;
        }

        // 3. 如果校验成功,则调用service处理注册请求
        User user = new User();
        WebUtils.copyBean(form, user); // 把form搞进user,得实现两个bean的拷贝
        user.setId(WebUtils.generateID());

        BusinessServiceImpl service = new BusinessServiceImpl();
        try {
            service.register(user);
            // 6. 如果service处理成功,则跳转到网站的全局消息显示页面,为用户显示注册成功的消息
            request.setAttribute("message", "恭喜您,注册成功!!");
            request.getRequestDispatcher("/message.jsp").forward(request, response);
            return;
        } catch (UserExistException e) {

            // 4. 如果service处理不成功,并且不成功的原因是注册用户已存在,则跳回到注册页面,显示注册用户已存在
            form.getErrors().put("username", "注册的用户名已存在!!");
            request.setAttribute("form", form);
            request.getRequestDispatcher("/WEB-INF/jsp/register.jsp").forward(
                    request, response);
            return;
        }catch(Exception e){

            // 5. 如果service处理不成功,并且不成功的原因是其他问题的话,则跳转到网站的全局消息显示页面,为用户显示友好错误消息
            e.printStackTrace();
            request.setAttribute("message", "服务器出现未知错误!!!");
            request.getRequestDispatcher("/message.jsp").forward(
                    request, response);
            return;
        }
    }

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

RegisterForm:

package cn.wk.web.formbean;

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

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

public class RegisterForm {
    private String username;
    private String password;
    private String password2;
    private String email;
    private String birthday; // 小心,这里不是Date,该类将记录表单数据,全字符串
    private String nickname;

    // private String checkcode; // 以后再说

    private Map errors = new HashMap(); // 定义集合,存储失败消息,并传递给 service

    /*
     * 对 对象进行校验,规则如下: 1. 用户名不能为空,并且是3-8位字母 2. 密码不为空,且3-8位数字 3.
     * 确认密码不能为空,且要和第一次的一致 4. 电子邮箱不为空,且是一个合法邮箱 5. 生日可为空,不为空时,必须是一个日期 6.
     * 昵称不可为空,且必是汉字
     */
    public boolean validate() {
        boolean isOK = true;

        // 1. 用户名不能为空,并且是3-8位字母
        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位字母!!");
            }
        }

        // 2. 密码不为空,且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位数字!!");
            }
        }

        // 3. 确认密码不能为空,且要和第一次的一致
        if (this.password2 == null || this.password2.trim().equals("")) {
            isOK = false;
            errors.put("password2", "确认密码不能为空!!");
        } else {
            if (!this.password.equals(this.password2)) {
                isOK = false;
                errors.put("password2", "两次密码要一致!!");
            }
        }

        // 4. 电子邮箱不为空,且是一个合法邮箱
        if (this.email == null || this.email.trim().equals("")) {
            isOK = false;
            errors.put("email", "电子邮箱不能为空!!");
        } else {
            if (!this.email.matches("\\w+@\\w+(\\.\\w+)+")) {
                isOK = false;
                errors.put("email", "电子邮箱格式不对!!");
            }
        }

        // 5. 生日可为空,不为空时,必须是一个日期
        if (this.birthday != null && !this.birthday.trim().equals("")) {
            try {// 日期格式校验 应该用这个
                DateLocaleConverter dlc = new DateLocaleConverter();
                dlc.convert(this.birthday, "yyyy-MM-dd");
            } catch (Exception e) {
                isOK = false;
                errors.put("birthday", "日期格式不对!!");
            }
        }

        // 6. 昵称不可为空,且必是汉字
        if (this.nickname == null || this.nickname.trim().equals("")) {
            isOK = false;
            errors.put("nickname", "昵称不能为空!!");
        }
        else {
            if (!this.nickname.matches("[\u4e00-\u9fa5]+")) {
                isOK = false;
                errors.put("nickname", "昵称必须是汉字!!");
            }
        }
        // 注意中文乱码问题:
        // 要在 RegisterServlet.java 中 加入 request.setCharacterEncoding("UTF-8");
        // 否则 表单输入中文后,取出来的是乱码,无法通过是否为汉字的测试

        return isOK; // 闯过前面所有关卡,isOK 为 true
    }

    public Map getErrors() {
        return errors;
    }

    public void setErrors(Map 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;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
}

LoginUIServlet:

package cn.wk.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 {
    @Override
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

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

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

RegisterUIServlet:

package cn.wk.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 {

    @Override
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

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

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

ServiceTest:

package junit.test;

import java.util.Date;

import org.junit.Test;

import cn.wk.domain.User;
import cn.wk.exception.UserExistException;
import cn.wk.service.BusinessService;
import cn.wk.service.impl.BusinessServiceImpl;

public class ServiceTest {

    @Test
    public void testRegister(){

        User user = new User();
        user.setBirthday(new Date());
        user.setEmail("[email protected]");
        user.setId("575638345");
        user.setNickname("小李子");
        user.setPassword("123");
        user.setUsername("ggg");

        BusinessService service = new BusinessServiceImpl();
        try {
            service.register(user);
            System.out.println("注册成功!");
        } catch (UserExistException e) {
            System.out.println("用户已存在!");
        }
    }

    @Test
    public void testLogin(){
        BusinessService service = new BusinessServiceImpl();
        User user = service.login("ggg", "123");
        System.out.println(user);
    }
}

UserDaoTest:

package junit.test;

import java.util.Date;

import org.junit.Test;

import cn.wk.dao.UserDao;
import cn.wk.dao.impl.UserDaoImpl;
import cn.wk.domain.User;

public class UserDaoTest {
    @Test
    public void testAdd() {
        User user = new User();
        user.setBirthday(new Date());
        user.setEmail("[email protected]");
        user.setId("575638345");
        user.setNickname("小李子");
        user.setPassword("123");
        user.setUsername("bbb");

        UserDao dao = new UserDaoImpl();
        dao.add(user);
    }

    @Test
    public void testFind() {
        UserDao dao = new UserDaoImpl();
        dao.find("aaa", "123");
    }

    @Test
    public void testFindByName() {
        UserDao dao = new UserDaoImpl();
        System.out.println(dao.find("ssdaaa"));
    }
}

购物车开发模块,略过。

猜你喜欢

转载自www.cnblogs.com/ZhongliangXiang/p/9027977.html
今日推荐