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 开发模式图,也包含了三层架构。
上图中为方便层的分离,设立了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 Library
的jstl-impl.jar
中WEB-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 导开发包:
-- 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 代码目录结构
代码思路待整理。
5.2 WebRoot中的代码
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>
<span><input type="submit" name="submit"
value="注 册"></span>
</div>
</form>
</div>
<div id="footer">这是页脚,也可添加图片</div>
</body>
</html>
5.3 src目录中的代码
模拟数据库的 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"));
}
}
购物车开发模块,略过。