1.搭建开发环境
1.1 导入项目所需的开发包:
dom4j-1.6.1.jar
jaxen-1.1-beta-6.jar
commons-beanutils-1.8.0.jar
commons-logging.jar
jstl.jar
standard.jar
1.2 创建程序的包名
1.3 在类目录下面,创建用于保存用户数据的xml文件(users.xml)-- 简单实现XML代替数据库users.xml
<?xml version="1.0" encoding="UTF-8"?>
<users>
<user id="51db22dc-f861-417b-b929-588aec86237e" username="abc" password="123" email="abc@sina.com.cn" birthday="1990-8-5 0:00:00"/>
</users>
View Code
2、开发实体user
1.1 User.java
package com.lich.domain;
import java.util.Date;
public class User {
private String id;
private String username;
private String password;
private String email;
private Date birthday;
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;
}
}
View Code
3、开发dao
3.1 开发UserDaoXmlImpl.java
package com.lich.dao.impl;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import com.lich.dao.UserDao;
import com.lich.domain.User;
import com.lich.utils.XmlUtils;
//根据业务需求来写
public class UserDaoXmlImpl implements UserDao {
public User find(String username,String password){
try{
Document document = XmlUtils.getDocument();
Element e = (Element) document.selectSingleNode("//user[@username='"+username+"' and @password='"+password+"']");
if(e==null){
return null;
}
User user = new User();
user.setId(e.attributeValue("id"));
user.setEmail(e.attributeValue("email"));
user.setPassword(e.attributeValue("password"));
user.setUsername(e.attributeValue("username"));
String birth = e.attributeValue("birthday");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
user.setBirthday(sdf.parse(birth));
return user;
}catch (Exception e) {
throw new RuntimeException(e);
}
}
public void add(User user){
try{
Document document = XmlUtils.getDocument();
Element root = document.getRootElement();
Element user_node = root.addElement("user"); //创建user结点,并挂到root
user_node.setAttributeValue("id", user.getId());
user_node.setAttributeValue("username", user.getUsername());
user_node.setAttributeValue("password", user.getPassword());
user_node.setAttributeValue("email", user.getEmail());
user_node.setAttributeValue("birthday", user.getBirthday().toLocaleString());
XmlUtils.write2Xml(document);
}catch (Exception e) {
throw new RuntimeException(e);
}
}
public User find(String username){
try{
Document document = XmlUtils.getDocument();
Element e = (Element) document.selectSingleNode("//user[@username='"+username+"']");
if(e==null){
return null;
}
User user = new User();
user.setId(e.attributeValue("id"));
user.setEmail(e.attributeValue("email"));
user.setPassword(e.attributeValue("password"));
user.setUsername(e.attributeValue("username"));
String birth = e.attributeValue("birthday");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
user.setBirthday(sdf.parse(birth));
return user;
}catch (Exception e) {
throw new RuntimeException(e);
}
}
}
View Code
3.2 UserDao.java 抽取接口
View Code
3.3 开发工具类: XmlUtils
package com.lich.utils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class XmlUtils {
private static String filename = "users.xml";
public static Document getDocument() throws DocumentException{
URL url = XmlUtils.class.getClassLoader().getResource(filename);
String realpath = url.getPath();
SAXReader reader = new SAXReader();
return reader.read(new File(realpath));
}
public static void write2Xml(Document document) throws IOException{
URL url = XmlUtils.class.getClassLoader().getResource(filename);
String realpath = url.getPath();
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(new FileOutputStream(realpath), format );
writer.write( document );
writer.close();
}
}
View Code
3.4 开发测试类 UserDaoTest
package junit.test;
import java.util.Date;
import org.junit.Test;
import com.lich.dao.UserDao;
import com.lich.dao.impl.UserDaoXmlImpl;
import com.lich.domain.User;
public class UserDaoTest {
@Test
public void testAdd(){
User user = new User();
user.setId("1002");
user.setUsername("bbb");
user.setPassword("123");
user.setEmail("bb@sina.com");
Date date = new Date();
user.setBirthday(date);
UserDao dao = new UserDaoXmlImpl();
dao.add(user);
}
@Test
public void testFind(){
UserDao dao = new UserDaoXmlImpl();
User user = dao.find("aaa","123");
System.out.println(user);
}
@Test
public void testFindByUsername(){
UserDao dao = new UserDaoXmlImpl();
User user = dao.find("sss");
System.out.println(user);
}
}
View Code
4、开发service(service 对web层提供所有的业务服务)
4.1 开发BusinessService
public void registerUser(User user) throws UserExistException
public User loginUser(String username,String password);
package com.lich.service.impl;
import com.lich.dao.UserDao;
import com.lich.dao.impl.UserDaoXmlImpl;
import com.lich.domain.User;
import com.lich.exception.UserExistException;
import com.lich.service.BusinessService;
//根据需求分析
public class BusinessServiceImpl implements BusinessService {
UserDao dao = new UserDaoXmlImpl();
//提供注册信息
/* (non-Javadoc)
* @see com.lich.service.impl.BusinessService#registerUser(com.lich.domain.User)
*/
public void registerUser(User user) throws UserExistException{
if( dao.find(user.getUsername())!=null){
//抛编译时异常:目的为了上一层程序处理这个异常,给用户友好提示.
throw new UserExistException("注册的用户已存在!!!");
}
dao.add(user);
}
/* (non-Javadoc)
* @see com.lich.service.impl.BusinessService#loginUser(java.lang.String, java.lang.String)
*/
public User loginUser(String username,String password){
return dao.find(username, password);
}
}
View Code
4.2 抽取接口
package com.lich.service;
import com.lich.domain.User;
import com.lich.exception.UserExistException;
public interface BusinessService {
//提供注册信息
void registerUser(User user) throws UserExistException;
User loginUser(String username, String password);
}
View Code
5、开发web层
5.1 开发注册
5.1.1 写一个RegisterUIServlet为用户提供注册界面,它收到请求,跳到register.jsp
package com.lich.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 {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/jsp/register.jsp").forward(
request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
View Code
5.1.2 写register.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 style="text-align: center;">
<form action="${pageContext.request.contextPath}/servlet/RegisterServlet" method="post">
<table width="60%" border="1" >
<tr>
<td>用户名</td>
<td>
<input type="text" name="username" value="${formbean.username }">${formbean.errors.username }
</td>
</tr>
<tr>
<td>密码</td>
<td>
<input type="password" name="password" value="${formbean.password }">${formbean.errors.password }
</td>
</tr>
<tr>
<td>确认密码</td>
<td>
<input type="password" name="password2" value="${formbean.password2 }">${formbean.errors.password2 }
</td>
</tr>
<tr>
<td>邮箱</td>
<td>
<input type="text" name="email" value="${formbean.email }">${formbean.errors.email }
</td>
</tr>
<tr>
<td>生日</td>
<td>
<input type="text" name="birthday" value="${formbean.birthday }">${formbean.errors.birthday }
</td>
</tr>
<tr>
<td>
<input type="reset" value="清空">
</td>
<td>
<input type="submit" value="注册">
</td>
</tr>
</table>
</form>
</body>
</html>
View Code
5.1.3 register.jsp提交请求,交给RegisterServlet处理
package com.lich.web.controller;
import java.io.IOException;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
import com.lich.domain.User;
import com.lich.exception.UserExistException;
import com.lich.service.BusinessService;
import com.lich.service.impl.BusinessServiceImpl;
import com.lich.utils.WebUtils;
import com.lich.web.formbean.RegisterFormBean;
public class RegisterServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
RegisterFormBean formbean = WebUtils.request2Bean(request,RegisterFormBean.class);
// 表单校验
if (formbean.validate() == false) {
request.setAttribute("formbean", formbean);
request.getRequestDispatcher("/WEB-INF/jsp/register.jsp").forward(
request, response);
return;
}
//把表单的数据填充到javabean中
User user = new User();
try {
//注册字符串到日期的转换器
ConvertUtils.register(new DateLocaleConverter(), Date.class);
BeanUtils.copyProperties(user, formbean);
user.setId(WebUtils.makeId());
BusinessService service = new BusinessServiceImpl();
service.registerUser(user);
request.setAttribute("message", "注册成功!!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
}catch (UserExistException e) {
formbean.getErrors().put("username", "注册用户已存在!!");
request.setAttribute("formbean", formbean);
request.getRequestDispatcher("/WEB-INF/jsp/register.jsp").forward(request, response);
} catch (Exception e) {
e.printStackTrace(); //在后台记录异常
request.setAttribute("message", "对不起,注册失败!!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
View Code
5.1.4 写RegisterServlet注意:
a.设计用于校验表单数据RegisterFormbean
package com.lich.web.formbean;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
public class RegisterFormBean {
private String username;
private String password;
private String password2;
private String email;
private String birthday;
private Map<String,String> errors = new HashMap();
public Map<String, String> getErrors() {
return errors;
}
public void setErrors(Map<String, String> 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;
}
/*
private String username; 用户名不能为空,并且要是3-8的字符 abcdABcd
private String password; 密码不能为空,并且要是3-8的数字
private String password2; 两次密码要一致
private String email; 可以为空,不为空要是一个合法的邮箱
private String birthday; 可以为空,不为空时,要是一个合法的日期
*
*/
public boolean validate(){
boolean isOk = true;
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位的字母!!");
}
}
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位的数字!!");
}
}
//private String password2; 两次密码要一致
if(this.password2!=null){
if(!this.password2.equals(this.password)){
isOk = false;
errors.put("password2", "两次密码不一致!!");
}
}
//private String email; 可以为空,不为空要是一个合法的邮箱
// flx_itcast@sina.com.cn
if(this.email!=null){
if(!this.email.matches("\\w+@\\w+(\\.\\w+)+")){
isOk = false;
errors.put("email", "邮箱不是一个合法邮箱!!");
}
}
//private String birthday; 可以为空,不为空时,要是一个合法的日期
if(this.birthday!=null){
try{
DateLocaleConverter conver = new DateLocaleConverter();
conver.convert(this.birthday);
}catch (Exception e) {
isOk = false;
errors.put("birthday", "生日必须要是一个日期!!");
}
}
return isOk;
}
}
View Code
b.写WebUtils工具类,封装请求数据到formbean中
package com.lich.utils;
import java.util.Enumeration;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.beanutils.BeanUtils;
////把request对象中的请求参数封装到bean中
public class WebUtils {
//用一个对象来接受处理请求,传给一个类字节码来创建类接收.使用泛型来应对调用
public static <T> T request2Bean(HttpServletRequest request,Class<T> clazz){
try{
T bean = clazz.newInstance();
//username=aa password=bb email=aa@sina.com
Enumeration e = request.getParameterNames();
while(e.hasMoreElements()){
String name = (String) e.nextElement(); //username=aaa password=123
String value = request.getParameter(name);
BeanUtils.setProperty(bean, name, value);
}
return bean;
}catch (Exception e) {
throw new RuntimeException(e);
}
}
/*
*自动产生唯一用户编号ID
*/
public static String makeId(){
//UUID 128 36位字符
return UUID.randomUUID().toString();
}
}
View Code
c、如果校验失败跳回到register.jsp,并回显错误信息
d、如果校验通过,调用service向数据库中注册用户
5.2 开发登陆
5.2.1 写一个LoginUIServlet为用户提供注册界面,它收到请求,跳到login.jsp
package com.lich.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 {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,
response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
View Code
<%@ 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>
<form action="${pageContext.request.contextPath }/servlet/LoginServlet" method="post">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
<input type="submit" value="登陆">
</form>
</body>
</html>
View Code
5.2.2 login.jsp提交给LoginServlet处理登陆请求
package com.lich.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 com.lich.domain.User;
import com.lich.service.BusinessService;
import com.lich.service.impl.BusinessServiceImpl;
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
BusinessService service = new BusinessServiceImpl();
User user = service.loginUser(username, password);
if(user==null){
request.setAttribute("message", "对不起,用户名或密码有误!!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;
}
request.getSession().setAttribute("user", user);
request.setAttribute("message", "恭喜:"+user.getUsername()+",登陆成功!本页将在5秒后跳到首页!!<meta http-equiv='refresh' content='5;url=/UserLogin/index.jsp'");
request.getRequestDispatcher("/message.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
View Code
其它 开发中常见:
① 自定义异常包: com.lich.exception.UserExistException
package com.lich.exception;
public class UserExistException extends Exception {
public UserExistException() {
super();
// 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
}
public UserExistException(String message, Throwable cause) {
super(message, cause);
// 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
}
}
View Code
② 全局消息显示页面 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>
View Code
③ 简单网站首页 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>
<script type="text/javascript">
function doLogout(){
window.location.href="${pageContext.request.contextPath}/servlet/LogoutServlet";
}
</script>
</head>
<body>
<h1>XX网站</h1>
<br/><br/>
<c:if test="${user==null}">
<a href="${pageContext.request.contextPath }/servlet/RegisterUIServlet" target="_blank">注册</a>
<a href="${pageContext.request.contextPath }/servlet/LoginUIServlet">登陆</a>
</c:if>
<c:if test="${user!=null}">
欢迎您:${user.username }
<input type="button" value="退出登陆" onclick="doLogout()">
</c:if>
<hr/>
</body>
</html>
View Code
④ 注销页面LogoutServlet
package com.lich.web.UI;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LogoutServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.getSession().removeAttribute("user");
request.setAttribute("message", "注销成功,本页将在5秒后跳到首页!!<meta http-equiv='refresh' content='5;url=/UserLogin/index.jsp'");
request.getRequestDispatcher("/message.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
View Code
总结:该网站虽然简单,但涵盖开发中使用的三层架构中心思想,认真领会MVC开发模式,学与思相结合,不断practice,相信编码水平会有质的提高.