zoukankan      html  css  js  c++  java
  • day0910 JSP 与案例

    Author:相忠良
    Email: ugoood@163.com
    起始于: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="aa@sina.com" 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 aa@aaa.com 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("bb@163.com");
    		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("bb@163.com");
    		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"));
    	}
    }
    

    购物车开发模块,略过。

  • 相关阅读:
    赋值运算 就是 +*/ 什么的啦
    利用application,cookies,sessino以及文件文件操作制作计数器和投票的综合实例(按学习进程更新)
    实现二级联动菜单 C#,带完整数据库 SQL
    写入、读取 cookie 无聊顺便复习了下前面学的东西!
    两级联动菜单之ListBox.item.add做法
    利用textbox接收两个数,列出一个数组,并做简单的运算
    .net服务器控件列表19个
    循环显示checkboxlist控件项的时候,count到底要不要 1
    validation验证控件案例以及正则表达式中几个特殊符号的说明!
    上传文件 动作详解(最简单的这种)
  • 原文地址:https://www.cnblogs.com/ZhongliangXiang/p/9027977.html
Copyright © 2011-2022 走看看