JavaWeb笔记-14-验证登陆注册案例。学习感想

1、各个包在框架下的理解:

	User作用:
		//存放用户实体。提供属性,get/set方法
	
	UserDao
		//实现对文件数据的操作。是service的底层
		//发送反馈给service
	
	service
		//提供可实现的功能
		//service不具体实现,调度UserDao。接收UserDao实现的反馈。
		//发送反馈给servlet
		
	servlet
		//调度。
		//接收service功能的反馈。
		//完成相关信息、异常消息的存放。返回给jsp用以显示

2、注册流程:

用户提交表单  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

3、练习感想:

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

用户名:${errors.username}
密   码:${errors.password}
验证码: 换一张${errors.verifyCode }

####登陆界面

  

登录

${msg }

<%--${pageContext.request.contextPath }/RegistServlet --%>
用户名:
密 码:

####欢迎界面


欢迎登录本系统

滚! //防止未登陆用户直接访问此页面。 ${sessionScope.sessionUser }

你可能感兴趣的:(JavaWeb笔记-14-验证登陆注册案例。学习感想)