教你使用JavaWeb实现无处不在的登陆注册

登陆注册,基本上是打开所有app都需要做的事情了,在这个大数据时代,登陆注册是最基础但也是最重要的用户数据。今天就手把手教你制作:

在各大信息管理系统中,登录功能是必不可少的,他的作用就是验证用户的身份,判断用户是否是本站的会员,只有会员才能访问当前系统

实现:

1.用户填写账号和密码,提交到后台2.后台获取到账号和密码后,将其发送到数据库中进行查询3.查询结果如果为null,说明用户填写的账号或者密码有误,应该回到登录页面并提示用户重新输入4.查询结果如果不为null,说明用户填写的账号和密码正确,将对应的账户信息共享到session中(在后面的请求,我们还需要继续使用当前登录的用户信息),然后跳转到网站的主页面

按照上面的步骤,我们使用下面的代码完成了相应功能1.登录页面

<form class="form-horizontal" action="/login" method="post">

    <div class="form-group">

用户名</label>

        <div class="col-sm-9">

            <input type="text" name="name" class="form-control" id="inputEmail3">

        </div>

    </div>

    <div class="form-group">

密   码</label>

        <div class="col-sm-9">

            <input type="password" name="password" class="form-control" id="inputPassword3">

        </div>

    </div>

    <div class="form-group">

        <label for="inputPassword3" class="col-sm-3 control-label"></label>

        <div class="col-sm-9">

登录</button>

        </div>

    </div>

页面中存在很多布局相关的代码,大家可以直接略过,重点看表单元素相关的标签即可LoginServlet

@WebServlet("/login")

public class LoginServlet extends HttpServlet {

    private IEmployeeService service = new EmployeeServiceImpl();

    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String name = req.getParameter("name");

        String password = req.getParameter("password");

        Employee currentUser = service.login(name, password);

        if(currentUser==null){

//登录失败

req.setAttribute("errorMsg","亲,账户或者密码错误");

            req.getRequestDispatcher("/login.jsp").forward(req,resp);

            return;

        }else{

//登录成功

            req.getSession().setAttribute("USER_IN_SESSION",currentUser);

            resp.sendRedirect("/employee");

            return;

        }

SQL:

SELECT * FROM employee WHERE name = ? AND password = ?

登录失败效果

登录成功效果

用户注销功能的主要作用是保护用户的账户安全,在用户点击安全退出的时候,我们需要将本次会话相关的session信息删除

删除的方式有下面两种:1.删除当前登录的用户信息存在问题:本次会话的其他信息还是保存在内存中,没有及时清理

@WebServlet("/logout")

public class LogoutServlet extends HttpServlet {

    private IEmployeeService service = new EmployeeServiceImpl();

    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        req.getSession().removeAttribute("USER_IN_SESSION");

        resp.sendRedirect("/login.jsp");

    }

}

2.销毁整个session(推荐)

@WebServlet("/logout")

public class LogoutServlet extends HttpServlet {

    private IEmployeeService service = new EmployeeServiceImpl();

    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        req.getSession().invalidate();

        resp.sendRedirect("/login.jsp");

    }

}

验证码

验证码是每个系统必不可少的功能,主要是用来防止系统被恶意攻击,如果没有这个功能,那么我们的系统就如同没有上锁的家门一样,小偷随时能进来干坏事

所以我们来看看,在登录的时候如何使用验证码,其他模块如果要使用,原理一样

1.首先,需要在登录页面显示出验证码的图片,用户可以根据图片中的文字进行填写2.同时,在生成验证码的时候,我们需要将正确的验证码保存到session中,供后面校验使用3.用户填写好验证码后,提交表单,后台校验注:生成验证码的代码不是我们这里的重点,以后如果需要,在网上一搜一箩筐,所以我就不贴出来了

校验代码

//校验验证码是否正确

String randomcode_in_session = (String) req.getSession().getAttribute("RANDOMCODE_IN_SESSION");

String randomCode = req.getParameter("randomCode");

if (!StringUtils.isNullOrEmpty(randomCode) && !StringUtils.isNullOrEmpty(randomcode_in_session)) {

    if (!randomCode.equals(randomcode_in_session)) {

        Cookie nameCookie = new Cookie("name", name);

        Cookie passwordCookie = new Cookie("password", password);

        resp.addCookie(nameCookie);

        resp.addCookie(passwordCookie);

handleError(req, resp, "亲,验证码错误");

        return;

    }

} else {

handleError(req, resp, "验证码不能为空或者验证码已失效");

    return;

}

private void handleError(HttpServletRequest req, HttpServletResponse resp, String errorMsg)

throws ServletException, IOException

    req.getSession().setAttribute("errorMsg", errorMsg);

    resp.sendRedirect("/login.jsp");

}

当用户没填写验证码或者session中的验证码失效,都应该给出错误提示如果用户填写的和session中保存的验证码不匹配,给出错误提示

如此,当验证码不正确的时候,我们就不会继续做登录校验,必须等用户填写出正确的验证码才可以,而这一点,机器是无法做到的

记住账

该功能的目的主要是想在用户一次登录之后,下次可以不再重新填写账号,增加用户体验

想要实现该功能,我们需要在后台将用户的账号信息进行共享

但是,我们应该使用什么来完成共享呢?

来,想想我们的需求,我今天早上十点第一次登陆系统,使用完之后,关闭浏览器,下午还需要登陆几次,明天后天...那么我想在这种需求下都可以不再填写账号

在这样的需求下,我相信大家能够想到一个答案---cookieCookie是将数据保存在浏览器中,而且,我们可以设置保存的时间,可以在关闭浏览器之后仍然能够继续使用所以,Cookie就是我们在这个需求中的最佳解决方案

在登录的业务逻辑添加如下代码,将账号相关信息保存到使用Cookie进行保存

//记住我

        String rememberMe = req.getParameter("rememberMe");

        if (!StringUtils.isNullOrEmpty(rememberMe)) {

//将用户信息保存到Cookie中

            Cookie nameCookie = new Cookie("name", name);

            nameCookie.setMaxAge(60 * 60 * 24);

            Cookie rememberMeCookie = new Cookie("rememberMe", rememberMe);

            rememberMeCookie.setMaxAge(60 * 60 * 24);

            resp.addCookie(nameCookie);

            resp.addCookie(rememberMeCookie);

        } else {

//将用户信息从Cookie中移除

            Cookie[] cookies = req.getCookies();

            for (Cookie cookie : cookies) {

                if ("name".equals(cookie.getName())  || "rememberMe".equals(cookie.getName())) {

                    cookie.setMaxAge(0);

                    resp.addCookie(cookie);

                }

            }

        }

然后,在登录页面获取到Cookie中的数据即可

<div class="form-group">

用户名</label>

    <div class="col-sm-9">

        <input type="text" name="name" class="form-control" id="inputEmail3"

               value="${cookie.name.value}">

    </div>

</div>

<label>

    <input type="checkbox" name="rememberMe"

        ${empty cookie.rememberMe.value?"":"checked='checked'"}> Remember me

</label>

当选择了记住我后,登录错误回到登录页面,此时能够自动获取到上次的账号信息

录检查

在用户没有登录的情况下,不允许访问系统中除登录以外的其他模块,如果访问,应该直接回到登录页面在javaweb中,这个问题的最佳解决方案就是使用过滤器(Filter)

过滤器:能够在访问到达目标资源之前对请求做预处理,在响应离开之前对响应做预处理

在我们这个需求中,是需要对请求做预处理的,检查用户在请求当前资源之前,是否已经登录

实现步骤:1.定义过滤器:CheckLoginFilter

public class CheckLoginFilter implements Filter {

    private List<String> needCheckURIs;

    public void init(FilterConfig filterConfig) throws ServletException {

//获取到需要校验的资源名称(如果需要校验的资源较多,可以配置不需要校验的资源)

        String needCheckURI = filterConfig.getInitParameter("needCheckURI");

        String[] split = needCheckURI.split(",");

//将所有的资源名存放到集合中,待后面进行校验

        needCheckURIs = Arrays.asList(split);

    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)

                throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;

        HttpServletResponse resp = (HttpServletResponse) response;

//获取当前请求的资源名

        String requestURI = req.getRequestURI();

//如果当前请求的资源是不需要校验的,直接放行

        if(!needCheckURIs.contains(requestURI)){

            filterChain.doFilter(req, resp);

            return;

        }

//如果需要校验,判断用户是否登录,是,则放行,反之回到登录页面

        Object currentUser = req.getSession().getAttribute("USER_IN_SESSION");

        if (currentUser == null) {

            resp.sendRedirect("/login.jsp");

            return;

        }

        filterChain.doFilter(req, resp);

    }

    public void destroy() {

    }

}

2.将过滤器交给Tomcat服务器管理

<filter>

    <filter-name>CheckLoginFilter</filter-name>

    <filter-class>cn.wolfcode.javaweb.web.filter.CheckLoginFilter</filter-class>

    <init-param>

        <param-name>needCheckURI</param-name>

        <param-value>/employee,/department</param-value>

    </init-param>

</filter>

<filter-mapping>

    <filter-name>CheckLoginFilter</filter-name>

    <url-pattern>/*</url-pattern>

</filter-mapping>

有了该过滤器,用户就不能再没有登录的时候,直接访问相关资源了,做到了一个基本的安全控制

生成系统账户

当系统启动后,我们需要在用户表中存在一个最起码的管理员账户,这样,用户才能登录进来来管理整个系统

那么,如何实现在启动服务器的时候,完成这个需求呢?

其实解决方案很多,大家也都应该能想到1.ServletServlet默认情况下是在第一次访问的时候执行初始化操作但是也可以调整到启动服务器的时候,0初始化Servlet的时候,会执行当前Servlet的init方法所以,我们完全在该方法中来完成这个需求2.Filter过滤器的初始化就是在启动服务器的时候和Servlet一样,初始化的时候会执行Filter的init方法所以,也可以在Filter的init方法中完成该需求3.Listener前面学习过WEB中的监听器,知道他能够对作用域(创建/销毁)和作用域中的属性(添加/删除/修改)进行监听我们的需求是,在启动服务器的时候创建默认账户而在启动服务器的时候,application作用域对象会在这个时候创建综上,我们可以创建一个application作用对象监听器,在创建该对象的时候,完成默认账户的创建

上面三种方式都能完成我们的需求,但最终从责任分离原则方面考虑,我们应该选择使用监听器,实现如下创建监听器

public class SystemManagerCreaterListener implements ServletContextListener {

    private IEmployeeService service = new EmployeeServiceImpl();

    public void contextInitialized(ServletContextEvent servletContextEvent) {

//查询系统默认账户是否存在,如果不存在,创建一个默认账户

        Employee manager = service.selectSystemManager();

        if(manager==null){

            manager = new Employee();

            manager.setName("admin");

            manager.setPassword("1");

            manager.setAdmin(true);

            service.save(manager);

        }

    }

    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }

}

注册监听器

<listener>

    <listener-class>cn.wolfcode.javaweb.web.listener.SystemManagerCreaterListener</listener-class>

</listener>

如此,在启动服务器的时候,先会到员工表中查询,是否存在默认的管理员账户。

击查JavaWeb系列的其它文章

手把手教你做JavaWeb项目:项目需求分析手把手教你做JavaWeb项目:前台界面手把手教你做JavaWeb项目:多条件过滤

前往叩丁狼官网获取更多技术视频

这么接地气的demo,从现在起你也可以实现自己的登陆注册板块。你还在犹豫什么?赶快行动起来吧!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容