学习黑马程序员小项目:User 项目源代码下载:http://download.csdn.net/detail/itjavawfc/8110221
通过小项目:主要了解用户注册登陆注销要做的那些逻辑处理
项目分析图
项目结构图:
在index.jsp主页中:
用到jstl标签:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<body> <h1>我的网站</h1><hr> <c:if test="${sessionScope.user==null}"> 欢迎光临!游客! <a href="${pageContext.request.contextPath }/regist.jsp">注册</a> <a href="${pageContext.request.contextPath }/login.jsp">登录</a> </c:if> <c:if test="${sessionScope.user!=null}"> 欢迎回来!${sessionScope.user.username }! <a href="${pageContext.request.contextPath }/servlet/LogoutServlet">注销</a> </c:if> </body>
在登陆页面中:
<body> <div align="center"> <h1>我的网站_登录</h1><hr> <font color="red"><strong>${msg }</strong></font> <form action="${pageContext.request.contextPath }/servlet/LoginServlet" method="POST"> <table border="1"> <tr> <td>用户名:</td> <td><input type="text" name="username" <strong>value="<UserTag:URLDecoder content="${cookie.remname.value }" encode="utf-8"/>"</strong>/></td> </tr> <tr> <td>密码:</td> <td><input type="password" name="password"/></td> </tr> <tr> <td><input type="submit" value="登录"/></td> <td><input type="checkbox" value="ok" name="remname" <strong><c:if test="${cookie.remname!=null }"> checked="checked" </c:if></strong> />记住用户名</td> </tr> </table> </form> </div> </body>
回显用户名:<strong>value="<UserTag:URLDecoder content="${cookie.remname.value }" encode="utf-8"/>"</strong>/></td>这个地方完全可以直接从cookie中取出来
${cookie.remname:记住用户名和复选框,根据cookie来判断。
LoginServlet中
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=utf-8"); UserService service = new UserService(); <strong>//1.获取客户端提交的用户名密码</strong> String username = request.getParameter("username"); String password = request.getParameter("password"); <strong>//2.调用Service中的方法检查用户名密码</strong> User user = service.isUser(username, password); if(user == null){ <strong>//3.如果不正确则提示</strong> request.setAttribute(<strong>"msg"</strong>, "用户名密码不正确!"); request.getRequestDispatcher("/login.jsp").forward(request, response); return; }else{ <strong>//4.正确则登录用户后重定向回到主页</strong> request.getSession().setAttribute("user", user); if("ok".equals(request.getParameter("remname"))){ //如果用户勾选过记住用户则发送cookie另浏览器保存用户名 Cookie remNameC = new Cookie("remname",URLEncoder.encode(user.getUsername(), "utf-8")); remNameC.setPath(request.getContextPath()); remNameC.setMaxAge(3600*24*30); response.addCookie(remNameC); }else{ //如果用户没有勾选记住用户名则删除记住用户名的cookie Cookie remNameC = new Cookie("remname",""); remNameC.setPath(request.getContextPath()); remNameC.setMaxAge(0); response.addCookie(remNameC); } response.sendRedirect(request.getContextPath()+"/index.jsp"); } }
在Regist.jsp中
<head> <script type="text/javascript"> function <strong>changeImg</strong>(img){ img.src = img.src+"?time="+new Date().getTime(); } </script> </head> <body style="text-align: center;"> <h1>我的网站_注册</h1><hr> <font color="red">${msg }</font> <form action="${pageContext.request.contextPath}/servlet/RegistServlet" method="POST" > <table border="1"> <tr> <td>用户名</td> <td><input type="text" name="username" value="<strong>${param.username </strong>}" /></td> </tr> <tr> <td>密码</td> <td><input type="password" name="password" /></td> </tr> <tr> <td>确认密码</td> <td><input type="password" name="password2" /></td> </tr> <tr> <td>昵称</td> <td><input type="text" name="nickname" v<strong>alue="${param.nickname }</strong>"/></td> </tr> <tr> <td>邮箱</td> <td><input type="text" name="email" <strong>value="${param.email }</strong>" /></td> </tr> <tr> <td>验证码</td> <td><input type="text" <strong>name="valistr"</strong> /></td> </tr> <tr> <td><input type="submit" value="注册" /></td> <strong><td><img src="${pageContext.request.contextPath }/servlet/ValiImg" style="cursor: pointer" onclick="changeImg(this)"/></td</strong>> </tr> </table> </form> </body>
用户名,昵称,邮箱在输入错误的时候可以回显到页面表格中,这样可以避免输入错误过程中避免重复书写
在Register.java中
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); UserService service = new UserService(); <strong>//1.检验验证码</strong> String valistr = request.getParameter("valistr"); String valistr2 = (String) request.getSession().getAttribute("valistr"); if(valistr == null || valistr2==null || !valistr.equals(valistr2)){ request.setAttribute("msg", "验证码不正确!"); request.getRequestDispatcher("/regist.jsp").forward(request, response); return; } <strong>//2.封装数据校验数据</strong> User user = new User(); <strong>BeanUtils.populate(user, request.getParameterMap());直接将请求过来的参数转换成map,避免使用大连的user.set()方法</strong> user.checkValue(); <strong>//3.调用Service中的方法添加用户</strong> service.registUser(user); <strong>//4.登录用户</strong> request.getSession().setAttribute("user", user); //将用户写到session中去 <strong>//5.提示注册成功3秒回到主页</strong> response.getWriter().write("恭喜您注册成功!3秒回到主页...."); response.setHeader("refresh", "3;url="+request.getContextPath()+"/index.jsp"); }catch (MsgException e) { request.setAttribute("msg", e.getMessage()); request.getRequestDispatcher("/regist.jsp").forward(request, response); return; }catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } }
LogoutServlet非常简单
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { <strong>if(request.getSession(false)!=null && request.getSession().getAttribute("user")!=null){ request.getSession().invalidate(); }</strong> response.sendRedirect(request.getContextPath()+"/index.jsp"); }
绘图的Servlet
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setDateHeader("Expires", -1); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache"); //1.在内存中构建出一张图片 int height = 30; int width = 120; int xpyl = 5; int ypyl = 22; int bang = 20; BufferedImage img = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); //2.获取图像上的画布 Graphics2D g = (Graphics2D) img.getGraphics(); //3.设置背景色 g.setColor(Color.LIGHT_GRAY); g.fillRect(0, 0, width, height); //4.设置边框 g.setColor(Color.BLUE); g.drawRect(0, 0, width-1, height-1); //5.画干扰线 for(int i = 0;i<5;i++){ g.setColor(Color.RED); g.drawLine(randNum(0, width), randNum(0, height), randNum(0, width), randNum(0, height)); } //6.写字 <span style="white-space:pre"> </span><span style="white-space:pre"> </span> String base =//此处字符不好显示,看源码即可。 <span style="white-space:pre"> </span> StringBuffer buffer = new StringBuffer(); <span style="white-space:pre"> </span> for(int i = 0; i<4;i++){ <span style="white-space:pre"> </span>g.setColor(new Color(randNum(0,255),randNum(0,255),randNum(0,255))); <span style="white-space:pre"> </span>g.setFont(new Font("黑体",Font.BOLD,bang)); <span style="white-space:pre"> </span>int r = randNum(-45,45); <span style="white-space:pre"> </span>g.rotate(1.0*r/180*Math.PI, xpyl+(i*30), ypyl); <span style="white-space:pre"> </span>String s = base.charAt(randNum(0, base.length()-1))+""; <span style="white-space:pre"> </span>buffer.append(s); <span style="white-space:pre"> </span>g.drawString(s, xpyl+(i*30), ypyl); <span style="white-space:pre"> </span>g.rotate(1.0*-r/180*Math.PI, xpyl+(i*30), ypyl); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span> <strong>request.getSession().setAttribute("valistr", buffer.toString()); //将图片中的字体放入Session中去</strong>
<strong> </strong><span style="white-space:pre"> </span> System.out.println(buffer.toString()); <span style="white-space:pre"> </span>//将图片输出到浏览器 <span style="white-space:pre"> </span>ImageIO.write(img, "jpg", response.getOutputStream()); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>private Random rand = new Random(); <span style="white-space:pre"> </span>private int randNum(int begin,int end){ <span style="white-space:pre"> </span>return rand.nextInt(end-begin)+begin; <span style="white-space:pre"> </span>}
上面的业务逻辑非常清楚展示了登陆注册注销的过程。
下面看看DAO Servlece Model层,可以单独拿出学习:学习xml解析【XPath】
User.java
package com.itheima.domain; import java.io.Serializable; import com.itheima.exception.MsgException; public class User implements Serializable { private String username; private String password; private String password2; private String nickname; private String email; 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 getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return username+":"+password; } public void checkValue() throws MsgException{ if(username==null || "".equals(username)){ throw new MsgException("用户名不能为空!"); } if(password==null || "".equals(password)){ throw new MsgException("密码不能为空!"); } if(password2==null || "".equals(password2)){ throw new MsgException("确认密码不能为空!"); } if(!password.equals(password2)){ throw new MsgException("两次密码不一致!"); } if(nickname==null || "".equals(nickname)){ throw new MsgException("昵称不能为空!"); } if(email==null || "".equals(email)){ throw new MsgException("邮箱不能为空!"); } if(!email.matches("^\\w+@\\w+(\\.\\w+)+$")){ throw new MsgException("邮箱格式不正确!"); } } }
user.xml
<?xml version="1.0" encoding="utf-8"?> <users> <user username="admin" password="admin" nickname="admin" email="[email protected]" /> </users>
package com.itheima.dao; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import com.itheima.domain.User; import com.itheima.util.XmlDaoUtils; public class XmlUserDao { /** * 根据用户名查找用户 * @param username 用户名 * @return 根据用户名找到的用户信息bean,如果没找到返回null */ public User findUserByUserName(String username){ Document dom = XmlDaoUtils.getDom(); Element root = dom.getRootElement(); //在xml中查找具有username属性值等于传入的用户名的元素 List<Element> list = root.selectNodes("//user[@username='"+username+"']"); if(list.size()>0){//大于0说明找到了这个用户 Element userEle = list.get(0); //将找到的用户信息封装到bean后返回 User user = new User(); user.setUsername(userEle.attributeValue("username")); user.setPassword(userEle.attributeValue("password")); user.setNickname(userEle.attributeValue("nickname")); user.setEmail(userEle.attributeValue("email")); return user; }else{//说明没有找到这个用户 return null; } } /** * 添加用户 * @param user 要添加的用户信息bean */ public void addUser(User user){ Document dom = XmlDaoUtils.getDom(); Element root = dom.getRootElement(); //凭空创建出一个<user>元素,根据传入的user信息,设置此元素的属性 Element userEle = DocumentHelper.createElement("user"); userEle.setAttributeValue("username", user.getUsername()); userEle.setAttributeValue("password", user.getPassword()); userEle.setAttributeValue("nickname", user.getNickname()); userEle.setAttributeValue("email", user.getEmail()); //挂载到<users>元素上 root.add(userEle); //回写到xml文件中 XmlDaoUtils.refXml(); } /** * 根据用户名密码查找对应的用户 * @param username 用户名 * @param password 密码 * @return 找到的用户,如果找不到则返回null */ public User findUserByUNandPSW(String username,String password){ Document dom = XmlDaoUtils.getDom(); Element root = dom.getRootElement(); //在xml中查找具有username属性值等于传入的用户名 并且 password 等于传入密码的元素 List<Element> list = root.selectNodes("//user[@username='"+username+"' and @password='"+password+"']"); if(list.size()>0){//大于0说明找到了这个用户 Element userEle = list.get(0); //将找到的用户信息封装到bean后返回 User user = new User(); user.setUsername(userEle.attributeValue("username")); user.setPassword(userEle.attributeValue("password")); user.setNickname(userEle.attributeValue("nickname")); user.setEmail(userEle.attributeValue("email")); return user; }else{//说明没有找到这个用户 return null; } } }
public class XmlDaoUtils { private static Document dom = null; private static String path = XmlDaoUtils.class.getClassLoader().getResource("users.xml").getPath(); private XmlDaoUtils() { } static{ try{ SAXReader reader = new SAXReader(); dom = reader.read(path); }catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } public static Document getDom(){ return dom; } public static void refXml(){ try { XMLWriter writer = new XMLWriter(new FileOutputStream(path),OutputFormat.createPrettyPrint()); writer.write(dom); writer.close(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } }
package com.itheima.service; import com.itheima.dao.XmlUserDao; import com.itheima.domain.User; import com.itheima.exception.MsgException; public class UserService { private XmlUserDao dao = new XmlUserDao(); /** * 添加用户 * @param user * @throws MsgException */ public void registUser(User user) throws MsgException{ //1.检查用户名是否已经存在,如果已经存在则提示 if(dao.findUserByUserName(user.getUsername())!=null){ throw new MsgException("用户名已经存在!"); } //2.如果不存在则调用dao中的方法添加用户 dao.addUser(user); } /** * 检查用户名密码是否正确 * @param username * @param password */ public User isUser(String username,String password){ return dao.findUserByUNandPSW(username, password); } }
package com.itheima.test; import org.junit.Test; import com.itheima.dao.XmlUserDao; import com.itheima.domain.User; public class XmlUserDaoTest { @Test public void testFindUserByUserName(){ XmlUserDao dao = new XmlUserDao(); User user = dao.findUserByUserName("adminxxx"); System.out.println(user); } @Test public void testFindUserByNMandPSW(){ XmlUserDao dao = new XmlUserDao(); User user = dao.findUserByUNandPSW("admin", "adminxx"); System.out.println(user); } @Test public void testAddUser(){ XmlUserDao dao = new XmlUserDao(); User user = new User(); user.setUsername("朴乾"); user.setPassword("123"); user.setNickname("小朴朴"); user.setEmail("[email protected]"); dao.addUser(user); } }