关于用户注册、登陆、注销小项目

时间:2022-06-13 08:44:34

学习黑马程序员小项目: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>

其中:${msg}为错误提示,后台抛出异常处理在前台显示。

回显用户名:<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="admin@qq.com" />
</users>


XmlUserDao.java

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



XmlDaoUtils

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);
}
}

}



UserService

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);
}

}



test

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("piaoqian@itcast.cn");
dao.addUser(user);
}
}