【JavaWeb】用Servlet实现用户登录/注册

导读:用Servlet可以实现用户的登录和注册。这里只是把数据放在ServletContext和Session中,并没有存在数据库。


准备:

首先要创建一个User的类,用来封装用户的各种属性,并为其设置getter/setter方法。

public class User {
    private String username;
    private String password;
    private String nickname;
    private String sex;
    private String hobby;
    private String path;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    //其它属性的getter/setter
}

然后由于需要把用户数据存放到全局ServletContext当中,所以需要创建一个InitServlet,用来初始化全局对象。需要制定loadOnstartup属性。

@WebServlet("/InitServlet",loadOnStartup=2)
public class InitServlet extends HttpServlet {
    @Override
    public void init() throws ServletException {
        //创建一个List集合用于保存用户的注册信息
        List<User> list=new ArrayList<User>();
        //将list保存到ServletContext中
        //在这里,也就是只要Tomcat一启动,所有注册的用户信息都会存储在这个List中,
        //如果Tomcat关闭,则数据清空。实际情况应该在数据库中保存。
        this.getServletContext().setAttribute("list",list);
    }
}

如果用户上传的图片名字一样,会覆盖掉。所以还需要对用户上传的图片名字进行处理,让其唯一化。 

public class UploadUtils {
    public static String getUUIDFileName(String fileName){
        //获取扩展名
        int idx=fileName.lastIndexOf(".");
        String extension=fileName.substring(idx);
        return UUID.randomUUID().toString().replace("-","")+extension;
    }
}

 最后,还需要编写一个处理Cookie的类,用于Cookie处理。

public class CookieUtils {
    public static Cookie findCookie(Cookie[] cookies,String name){
        if(cookies==null){
            //没有携带cookie
            return null;
        }else{
            for(Cookie cookie:cookies){
                if(name.equals(cookie.getName())){
                    return cookie;
                }
            }
            //没带包含username的cookie
            return null;
        }
    }
}

注册: 

regist.jsp用于注册,由于form表单需要上传文件,所以enctype需要="multipart/form-data"。表单的数据提交到RegistServlet中。

<form action="/reg_login/RegistServlet" method="post" enctype="multipart/form-data">
    <table>
        <tr>
            <td class="td1">用户名</td>
            <td><input type="text" class="input1" name="username"></td>
        </tr>
        <!--其它用户属性-->       
        </table>
</form>

在RegistServlet中,首先要尝试从regist.jsp中发来的请求,是由含有文件对象。如果有,就解析这个对象。

@WebServlet("/RegistServlet")
public class RegistServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            //定义一个Map集合用于保存接收到的数据
            Map<String,String> map=new HashMap<String, String>();
            //1.创建一个磁盘文件项工厂对象
            DiskFileItemFactory diskFileItem = new DiskFileItemFactory();
            //2.创建一个文件解析类
            ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItem);
            //3.解析request请求,返回的List集合,每一个元素是FileItem对象,包含username password nickname sex upload hobby等属性
            List<FileItem> list=servletFileUpload.parseRequest(request);
            //由于hobby是复选框,每一个用户,有多个hobby,所以定义一个HobbyList集合,用于保存用户所有兴趣爱好
            List<String> hobbyList=new ArrayList<String>();
            //获取上传文件路径用
            String url=null;

接下来,遍历FileItem组成的List。 先判断是普通属性,还是文件上传属性,下面代码处理的是普通属性。

            //4.遍历集合,获得每个FileItem,判断是表单项还是文件上传项
            for(FileItem fileItem:list){
                //判断是普通项还是文件上传项
                if(fileItem.isFormField()){
                    //得到属性名字
                    String name=fileItem.getFieldName();
                    //得到属性值
                    String value=fileItem.getString("UTF-8");
                    //如果是hobby属性
                    if("hobby".equals(name)){
                        //得到该hobby的值
                        String hobbyValue = fileItem.getString("UTF-8");
                        //添加到hobbyList
                        hobbyList.add(hobbyValue);
                        //去掉list的[]
                        hobbyValue=hobbyList.toString().substring(1,hobbyList.toString().length()-1);//[xx,yy]-->xx,yy
                        //属性键值对中添加,添加完成后类似 {hobby:xxx,xxx,xx}
                        map.put(name,hobbyValue);
                    }
                    //如果是其它属性,直接添加。
                    else{
                        map.put(name,value);
                    }

接着,处理文件上传项。

                }else{
                    //文件上传
                    String fileName=fileItem.getName();
                    if(fileItem!=null &&!"".equals(fileName)){
                        String uuidFileName=UploadUtils.getUUIDFileName(fileName);
                        //获得文件上传的数据,即图片数据流is
                        InputStream is=fileItem.getInputStream();
                        //获得文件上传后保存的位置,这里也是Tomcat部署out/下的upload文件夹
                        String path=this.getServletContext().getRealPath("/upload");
                        //输出文件路径
                        url=path+"\\"+uuidFileName;
                        //输出流
                        OutputStream os=new FileOutputStream(url);
                        //输入输出对接
                        int len=0;
                        byte[] b=new byte[1024];
                        while((len=is.read(b))!=-1){
                            os.write(b,0,len);
                        }
                        is.close();
                        os.close();
                    }
                }
            }

处理完毕后,从ServletContext中获取最开始建立的List<User> userList。但在这里之前,需要进行判断用户名的唯一性。 如果用户名已经存在,则跳回/regist.jsp,并附带一条出错信息

            //将注册用户的信息存入到全局的list集合中:
            List<User> userList=(List<User>) this.getServletContext().getAttribute("list");
            //校验用户名是否存在
            for(User u:userList){
                if(u.getUsername().equals(map.get("username"))){
                    //若存在,则需要重新注册,所以需要重新跳转到regist.jsp,并附带出错信息,所以有req.setAttr。
                    request.setAttribute("msg","用户名已存在!");
                    request.getRequestDispatcher("/regist.jsp").forward(request,response);
                    return;
                }
            }

如果用户名不存在,则创建User实例,将从请求中获取的属性,放入这个User实例。再把User实例添加进userList,最后把userList添加到全局的ServletContext中

            //不存在,则封装到USER当中
            User user=new User();
            user.setUsername(map.get("username"));
            user.setPassword(map.get("password"));
            user.setSex(map.get("sex"));
            user.setNickname(map.get("nickname"));
            user.setHobby(map.get("hobby"));
            user.setPath(url);
            //将User添加到全局的UserList中
            userList.add(user);
            //后台显示当前已经存在的用户
            for(User u :userList){
                System.out.println(u);
            }
            //再把UserList写回到全局list中。
            this.getServletContext().setAttribute("list",userList);
            //注册成功后,跳转登录页面。
            //为了能在登录页面的用户名中直接输入好刚才注册的用户,需要发送一个请求。
            request.getSession().setAttribute("username",user.getUsername());
            response.sendRedirect(request.getContextPath()+"/login.jsp");
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
    }

最后,将页面跳转到登录页面/login.jsp,并附带一条Session属性,用于在登录的时候,用户名处出现刚刚注册的用户名。


处理用户名重名:上面说到,如果用户名已经存在,则要跳回regist.jsp,重新注册,并附带一条出错信息。所以需要在regist.jsp中添加以下代码。

<%
    String msg="";
    if(request.getAttribute("msg")!=null){
        msg=(String)request.getAttribute("msg");
    }
%>
    <h3><font color="red"><%=msg%></font> </h3>
    <!--注册表单-->

登录:

login.jsp中的登录表单,用于提交用户名、密码和记住用户名信息。表单提交到LoginServlet。

        <form action="/reg_login/LoginServlet" method="post">
            <table>
                <tr>
                    <td class="td1">用户名</td>
                                                                       <!--设置用户名登录框的默认值-->
                    <td><input type="text" class="input1" name="username" value="<%=username%>"></td>
                </tr>
                <tr>
                <td class="td1">密码</td>
                <td><input type="password" class="input1" name="password"></td>
                </tr>
                <tr>
                <td class="td1" colspan="2">
                    <input type="checkbox" name="remember" value="true" checked="checked"> 记住用户名</td>
                </tr>
                <tr>
                    <td colspan="2">
                        <div class="btn-red">
                            <input type="submit" value="登录" id="login-btn">
                        </div>
                    </td>
                </tr>
            </table>
        </form>

在LoginServlet中,首先获取login.jsp传过来的请求,再获取全局userList,遍历已经存在的userList,与传过来的username和password进行一一对比,如果两者都能匹配上,就表示登录成功。

如果用户勾选了“记住用户名”,那么就需要将username存放到Cookies中。 

登录成功后,就跳转到成功的success.jsp。

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取登录的用户名和密码
        String username=request.getParameter("username");
        String password=request.getParameter("password");
        //从ServletContext中获取保存用户信息的集合
        List<User> list=(List<User>) this.getServletContext().getAttribute("list");
        for(User user:list){
            //用户名匹配
            if(username.equals(user.getUsername())){
                //密码匹配
                if(password.equals(user.getPassword())){
                    //登录成功,记住Cookie
                    //前提是复选框要勾选
                    String remember=request.getParameter("remember");
                    if("true".equals(remember))
                    {
                        Cookie cookie=new Cookie("username",user.getUsername());
                        //设置有效路径和有效时间
                        cookie.setPath("/reg_login");
                        //设置有效时间
                        cookie.setMaxAge(60*60*24);
                        //将cookie回写到浏览器
                        response.addCookie(cookie);
                    }
                    //登录成功后,跳转至success.jsp页面,并设置一个session值,用于显示“欢迎xxx”
                    request.getSession().setAttribute("user",user);
                    response.sendRedirect("/reg_login/success.jsp");
                    return;
                }
            }
        }

如果用户名或者密码,匹配不上,那就转回到login.jsp,并附带错误信息。

        //遍历完所有,无匹配,就登录失败
        request.setAttribute("msg","用户名或密码错误!");
        //转回到login.jsp,重新进行登录,并附带错误信息
        request.getRequestDispatcher("/login.jsp").forward(request,response);
    }

这样,LoginServlet的编写就完成了。


成功页面

<%
	if(session.getAttribute("user")!=null){
		User user=(User)session.getAttribute("user");
		System.out.println(user.getPath());
		//得到文件名
		int idx=user.getPath().lastIndexOf('\\');
		String fileName=user.getPath().substring(idx+1);

%>
	<div class="login">
		<div class="header">
			<h1>登录成功</h1>
		</div>
	<div class="content">
		<table align="center">
			<tr>
				<td align="center"><img src="<%=request.getContextPath()%>/upload/<%=fileName%>" /></td>
			</tr>
			<tr>
				<td align="center">欢迎<%=user.getNickname()%>,登录成功!</td>
			</tr>
		</table>
	</div>
	</div>
<%
	}else{
%>
<!--直接访问success.jsp-->
<div class="login">
	<div class="header">
		<h1>您还没有登录!请先去<a href="login.jsp">登录</a>!</h1>
	</div>
</div>
<%
	}
%>

 处理登录失败和Cookie:如果登录失败,会附带出错信息到login.jsp。如果有Cookie信息,则不需要从request中获取用户名。所以在login.jsp中还需要添加如下代码:

        <%
            String username="";
            //获得cookie
            Cookie[] cookies =request.getCookies();
            //从Cookie数组中查找指定名称的cookie
            Cookie cookie=CookieUtils.findCookie(cookies,"username");

            if(cookie!=null){
                username=cookie.getValue();
            }
            if(session.getAttribute("username")!=null){
                username=(String)session.getAttribute("username");
            }

            String msg="";
            if(request.getAttribute("msg")!=null){
                msg=(String) request.getAttribute("msg");
            }
        %>
        <!--显示错误信息-->
        <h3><font color="red"><%=msg%></font> </h3>
        <!--登录表单-->

 

评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值