User作用:
//存放用户实体。提供属性,get/set方法
UserDao
//实现对文件数据的操作。是service的底层
//发送反馈给service
service
//提供可实现的功能
//service不具体实现,调度UserDao。接收UserDao实现的反馈。
//发送反馈给servlet
servlet
//调度。
//接收service功能的反馈。
//完成相关信息、异常消息的存放。返回给jsp用以显示
用户提交表单 jsp
如果异常,使用EL表达式输出异常信息。
传递验证码图片
servlet封装表单,传递(调用)给service#regist servlet
封装:toBean ***导包。
service.regist()
接收service结果。
service#regist。用于接收注结果。根据注册功能对应的文件操作。转发给userdao完成。自身用于接收反馈信息。
先调用userdao#findByName中查询
返回null正常:调用userdao#add添加
添加完成。跳转登陆界面。
返回异常:获取异常信息,保存到request域。转发回注册界面
userdao查询与添加。是否存在。存在则不添加。不存在则添加 完成后反馈给上层。
知识点,dom4j对xpath的操作。 ***需要导包jaxen-1.1-beta-6.jar
findByName
得到doc
使用xpath查找
没找到:返回null
找到了,返回注册异常。
add
得到doc
得到根节点
创建新元素
设值。
回写。
user数据的底层设置和获取方法。
底层文件:xml
xml格式:每个用户一个属性为username和password
//xml文件配置
考虑根元素
考虑属性
//表单提交
考虑提交地址:项目名 + web.xml中对应的Url-pattern属性值
提交方式:EL表达式、JSTL-core库标签
EL表达式:${pageContext.request.contextPath}/RegistServlet
JSTL-core库标签:
//创建方法时:
考虑是否需要返回值,返回值类型
考虑参数
//requst应用理解:
多用于servlet与jsp页面的数据请求共享
eg:1)保存错误信息到request中,(设置属性及信息)可以在jsp界面用EL表达式输出。
EL表达式的优势:有值回输出,无值不输出
2)用于用户名回显。
//EL表达式应用理解:
在jsp页面中输出域中内容,输出集合中内容。
//session感想
保存一次对话的信息
可用于数据回显等操作。
//xpath感想
用于查找xml文件节点。极其方便。
//输入验证时 考虑输入为空情况
//jsp插入图片:
需设置src !
设置id
//jsp调用JavaScript代码
jsp页面需要动态效果时,需编写JavaScript代码用数据呈现动态效果。 eg:图片切换。
//超链接调用JavaScript代码
点击元素时启动 JavaScript。
遗留问题:
异常处理的交互流程。
封装表单数据的过程。
####package Domain
//实体类
//存放用户实体。提供属性,get/set方法
public class User {
private String username;
private String password;
private String verifyCode;
public String getVerifyCode() {
return verifyCode;
}
public void setVerifyCode(String verifyCode) {
this.verifyCode = verifyCode;
}
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 User() {
super();
// TODO Auto-generated constructor stub
}
public User(String username, String password, String verifyCode) {
super();
this.username = username;
this.password = password;
this.verifyCode = verifyCode;
}
}
####package Dao
//实现对文件数据的操作。是service的底层
//发送反馈给service
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import Domain.User;
public class UserDao {
private String path = "E:/users.xml";
/**
* 按用户名查询
*
* @param username
* @return
* @author 一万年行不行
*/
/*
* 步骤:
* 1.得到doc
* 2.使用xpath查找
* 没找到:返回null
* 找到了,返回注册异常。
*/
public User findByUsername(String username) {
// 创建解析器
SAXReader reader = new SAXReader();
try {
//通过解析器得到document
Document doc = reader.read(path);
//通过xpath查询元素,返回给ele
Element ele = (Element) doc.selectSingleNode("//user[@username='"+ username + "']");
//校验ele是否为null,如果为null,返回null
if (ele == null)
return null;
//找到了,则需要返回一个user对象,
//表示(user.username)用户找到了,在登陆功能中,也可直接调用user对象比对密码
//此时ele为元素,不能作为对象返回。
//需要创建出一个user 提取出ele元素的属性值, 赋给user
//返回
User user = new User();
String attrUsername = ele.attributeValue("username");// 获取该元素的名为username属性值
String attrPassword = ele.attributeValue("password");// 获取该元素的名为password属性值
user.setUsername(attrUsername);
user.setPassword(attrPassword);
return user;
} catch (DocumentException e) {
throw new RuntimeException(e); //?有什么用
}
}
/**
* 添加用户
*
* @param user
* @author 一万年行不行
*/
public void add(User user) {
/*
1.得到doc
2.得到根节点
3.创建新元素
4.设值。
5.回写。
*/
SAXReader reader = new SAXReader();
try {
// 得到Document
Document doc = reader.read(path);
// 得到根元素
Element root = doc.getRootElement();
// 通过根元素创建新元素
Element userEle = root.addElement("user");
// 为userEle设置属性
userEle.addAttribute("username", user.getUsername());
userEle.addAttribute("password", user.getPassword());
//保存文档
// 创建格式化器
OutputFormat format = OutputFormat.createPrettyPrint();
// 创建XmlWriter
XMLWriter writer;
try {
//将回写对象放进流中,保证该流对象为"UTF-8"。
writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream(path), "UTF-8"), format);
writer.write(doc);
writer.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
} catch (DocumentException e) {
throw new RuntimeException(e);
}
}
}
####package service
/**
* @author 一万年行不行
* 自定义异常,只需要给出父类中的构造器。方便用来创建对象
*/
public class UserException extends Exception {
public UserException() {
super();
// TODO Auto-generated constructor stub
}
public UserException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public UserException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public UserException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}
public class UserService {
private UserDao userDao = new UserDao();
/**
* 注册功能
* @param user
* @throws UserException
* @author 一万年行不行
*/
public void regist(User user) throws UserException {
//查询是否存在
User _user = userDao.findByUsername(user.getUsername());
//存在,抛异常
if(_user != null) throw new UserException("用户名" + user.getUsername() + ", 已被注册过了!");
//不存在,添加
userDao.add(user);
}
/**
* 登录功能
* @param form
* @return
* @throws UserException
* @author 一万年行不行
*/
public User login(User form) throws UserException {
// 1. 使用form中的username进行查询,得到User user
User user = userDao.findByUsername(form.getUsername());
// 2. 如果返回null,说明用户名不存在,抛出异常,异常信息为“用户名不存在”
if(user == null) throw new UserException("用户名不存在!");
//找到用户名了
//3. 比较user的password和form的password,如果不同,抛出异常,异常信息为“密码错误!”
if(!form.getPassword().equals(user.getPassword())) {
throw new UserException("密码错误!");
}
//返回数据库中查询出来的user,而不是form,因为form中只有用户名和密码,而user是所有用户信息!
return user;
}
}
####package web.servlet
/**
* @author 一万年行不行
*/
public class LoginServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//依赖userservice
UserService userService = new UserService();
//封装表单数据(form)为User对象。
User form = CommonUtils.toBean(request.getParameterMap(), User.class);
try {
//调用登陆
User user = userService.login(form);
//登陆成功,返回user,保存用户信息到session
request.getSession().setAttribute("sessionUser",user);
//登陆成功,重定向到新的页面。 .sendRedirect();重定向方法。
response.sendRedirect(request.getContextPath() +"/user/welcome.jsp");
} catch(UserException e) {
//登陆异常
//设置异常信息到request请求域中,
request.setAttribute("msg", e.getMessage());
//保存form表单数据 用于回显
request.setAttribute("user", form);
//转发回登陆界面。显示request域中错误信息。
request.getRequestDispatcher("/user/login.jsp").forward(request, response);
}
}
}
/**
* @author 一万年行不行
*/
public class RegistServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 依赖userservice
UserService userService = new UserService();
// 封装表单数据
User form = CommonUtils.toBean(request.getParameterMap(), User.class);
/*
表单校验
* 1. 创建一个Map,装载所有的表单错误信息
* 2.校验。
* 失败,向map添加错误信息,其中key为表单字段名称
* 3.查看map长度是否大于0,
* a.大于0。有错误!
* 处理错误:保存map到request中,保存form到request中,转发到regist.jsp
* b.等于0。没有错误,向下执行!
*/
// 1. 创建一个Map,装载所有的表单错误信息
Map errors = new HashMap();
// 2.校验。
// 对用户名进行校验,获取表单的username
String username = form.getUsername();
//用户名不为空,trim();表示去掉空格。
if (username == null || username.trim().isEmpty()) {
//为空,向map中存放错误信息。
errors.put("username", "用户名不能为空!");
} else if (username.length() < 3 || username.length() > 15) {
errors.put("username", "用户名长度必须在3~15之间!");
}
// 对密码进行校验
String password = form.getPassword();
if (password == null || password.trim().isEmpty()) {
errors.put("password", "密码不能为空!");
} else if (password.length() < 3 || password.length() > 15) {
errors.put("password", "密码长度必须在3~15之间!");
}
// 对验证码进行校验 获取保存到session中的验证码
String sessionVerifyCode = (String) request.getSession().getAttribute(
"session_vcode");
// 获取表单中验证码字节
String verifyCode = form.getVerifyCode();
if (verifyCode == null || verifyCode.trim().isEmpty()) {
errors.put("verifyCode", "验证码不能为空!");
} else if (verifyCode.length() != 4) {
errors.put("verifyCode", "验证码长度必须为4!");
} else if (!verifyCode.equalsIgnoreCase(sessionVerifyCode)) {
errors.put("verifyCode", "验证码错误!");
}
// 处理错误: 判断map是否为空,不为空,说明存在错误
if (errors != null && errors.size() > 0) {
// 1. 保存errors到request域
request.setAttribute("errors", errors);
//2. 保存form到request域,为了回显
request.setAttribute("user", form);
//3. 转发到regist.jsp
request.getRequestDispatcher("/user/regist.jsp").forward(request,
response);
return;
}
//验证格式正确后,开始注册
try {
//调用userService的regist()方法,传递form过去
userService.regist(form);
//没有异常:输出注册成功!
response.getWriter().print(
"注册成功!
点击这里去登录");
} catch (UserException e) {
//得到异常:获取异常信息,保存到request域,转发到regist.jsp中显示
// 获取异常信息,保存到request域
request.setAttribute("msg", e.getMessage());
// 还要保存表单数据,到request域
request.setAttribute("user", form);// 用来在表单中回显!
// 转发到regist.jsp
request.getRequestDispatcher("/user/regist.jsp").forward(request,
response);
}
}
}
public class VerifyCodeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1. 创建验证码类
VerifyCode vc = new VerifyCode();
//2. 得到验证码图片
BufferedImage image = vc.getImage();
//3. 把图片上的文本保存到session中
request.getSession().setAttribute("session_vcode", vc.getText());
//4. 把图片响应给客户端
VerifyCode.output(image, response.getOutputStream());
}
}
####注册界面
注册
${msg}
####登陆界面
登录
${msg }
<%--${pageContext.request.contextPath }/RegistServlet --%>
####欢迎界面
欢迎登录本系统
滚! //防止未登陆用户直接访问此页面。
${sessionScope.sessionUser }