第3章业务功能开发(用户登录:拦截器)

本文介绍了如何在Spring MVC项目中使用拦截器实现登录验证,确保只有已登录用户能访问业务资源,同时涉及会话管理和登录状态管理。通过LoginInterceptor类配置在`applicationContext-mvc.xml`中,配合`UserController`的处理逻辑,实现了登录、登出及会话清理功能。
摘要由CSDN通过智能技术生成

客户需求

登录验证.

用户访问任何业务资源,都需要进行登录验证.

*只有登录成功的用户才能访问业务资源

*没有登录成功的用户访问业务资源,跳转到登录页面

预计实现思路

1,登录验证:

   1)过滤器:
     a)implements Filter{
         --init
     --doFilter
     --destroy
       }
     b)配置过滤器:web.xml
   2)拦截器:
     a)提供拦截器类:implements HandlerInterceptor{
              --pre
              --post
              --after
                     }
     b)配置拦截器:springmvc.xml

本次选择拦截器实现该需求

1.在crm/settings/web中创建interceptor包,该包下创建LoginInterceptor类

 2.LoginInterceptor类

package com.it.crm.settings.web.interceptor;

import com.it.crm.commons.contants.Contants;
import com.it.crm.settings.entity.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class LoginInterceptor implements HandlerInterceptor {

    //在控制器方法之前执行,如果符合要求则放行到UserController类,否则截断请求
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        HttpSession session = httpServletRequest.getSession();
        User user= (User) session.getAttribute(Contants.SESSION_USER);
        if (user==null){
            httpServletResponse.sendRedirect(httpServletRequest.getContextPath());//代表“/crm”,该路径自动跳转到登录页面
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

3.applicationContext-mvc.xml文件,添加拦截器

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
    <!-- dispatcherServlet截获所有URL请求 -->
    <mvc:default-servlet-handler />
    <!-- 组件扫描器:spring mvc 扫描包下的controller -->
    <context:component-scan base-package="com.it.crm.web.controller"/>
    <context:component-scan base-package="com.it.crm.settings.web.controller"/>
    <context:component-scan base-package="com.it.crm.workbench.web.controller"/>
    <!-- 配置注解驱动 -->
    <mvc:annotation-driven/>
    <!-- 配置视图解析器 -->
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <mvc:interceptors>
        <mvc:interceptor>
<!--            配置拦截的请求-->
            <mvc:mapping path="/settings/**"/>
            <mvc:mapping path="/workbench/**"/>
<!--            配置排除拦截的请求(优先级高)-->
            <mvc:exclude-mapping path="/settings/qx/user/toLogin.do"/>
            <mvc:exclude-mapping path="/settings/qx/user/login.do"/>
            <bean class="com.it.crm.settings.web.interceptor.LoginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
    <!-- 配置文件上传解析器 id:必须是multipartResolver-->
    <!--<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="#{1024*1024*80}"/>
        <property name="defaultEncoding" value="utf-8"/>
    </bean>-->
</beans>

4.UserController类保持不变

package com.it.crm.settings.web.controller;

import com.it.crm.commons.contants.Contants;
import com.it.crm.commons.entity.ReturnObject;
import com.it.crm.commons.utils.DateUtils;
import com.it.crm.settings.entity.User;
import com.it.crm.settings.service.UserService;
import com.sun.deploy.net.HttpResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Controller
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/settings/qx/user/toLogin.do")
    public String toLogin(){
        return "settings/qx/user/login";
    }

    @RequestMapping(value = "/settings/qx/user/login.do")
    @ResponseBody
    public Object login(String loginAct, String loginPwd, String isRemPwd, HttpServletRequest request, HttpServletResponse response, HttpSession session){
        //封装参数
        Map<String,Object> map=new HashMap<>();
        map.put("loginAct",loginAct);
        map.put("loginPwd",loginPwd);
        map.put("isRemPwd",isRemPwd);
        //调用service层方法,查询用户
        User user = userService.queryUserByActAndPwd(map);
        //根据查询结果生成响应信息
        ReturnObject returnObject=new ReturnObject();
        if (user==null){
            //登录失败,用户名或密码错误
            returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
            returnObject.setMessage("用户名或密码错误");
        }else {//进一步判断账号是否合法
            if (DateUtils.formateDateTime(new Date()).compareTo(user.getExpireTime())>0){
                //登录失败,账号已过期
                returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
                returnObject.setMessage("账号已经过期");
            }else if ("0".equals(user.getLockState())){
                //登录失败,状态被锁定
                returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
                returnObject.setMessage("状态被锁定");
            }else if (!user.getAllowIps().contains(request.getRemoteAddr())){
                //登录失败,ip受限
                returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
                returnObject.setMessage("ip受限");
            }else{
                //登录成功
                returnObject.setCode(Contants.RETURN_OBJECT_CODE_SUCCESS);
                //把user保存到session中
                session.setAttribute(Contants.SESSION_USER,user);
                //如果需要记住密码,则往外写cookie
                if("true".equals(isRemPwd)){
                    Cookie loginAct1 = new Cookie("loginAct", user.getLoginAct());
                    loginAct1.setMaxAge(60*60*24*10);
                    response.addCookie(loginAct1);
                    Cookie loginPwd1 = new Cookie("loginPwd", user.getLoginPwd());
                    loginPwd1.setMaxAge(60*60*24*10);
                    response.addCookie(loginPwd1);
                }else{
                    //把没有过期的cookie删除
                    Cookie c1=new Cookie("loginAct","1");
                    c1.setMaxAge(0);
                    response.addCookie(c1);
                    Cookie c2=new Cookie("loginPwd","2");
                    c2.setMaxAge(0);
                    response.addCookie(c2);
                }
            }
        }
        return returnObject;
    }

    @RequestMapping(value = "/settings/qx/user/logout.do")
    public String logout(HttpServletResponse response,HttpSession session){
        //清空cookie
        Cookie c1=new Cookie("loginAct","1");
        c1.setMaxAge(0);
       response.addCookie(c1);
       Cookie c2=new Cookie("loginPwd","2");
       c2.setMaxAge(0);
       response.addCookie(c2);
        //销毁session
        session.invalidate();
        //跳转到首页
        return "redirect:/";
    }
}

5.login.jsp登录界面保持不变

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core_1_1" %>
<%
	String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
%>
<html>
<head>
<meta charset="UTF-8">
	<base href="<%=basePath%>">
<link href="jquery/bootstrap_3.3.0/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="jquery/jquery-1.11.1-min.js"></script>
<script type="text/javascript" src="jquery/bootstrap_3.3.0/js/bootstrap.min.js"></script>

    <script type="text/javascript">
    $(function () {

    	//给整个浏览器窗口添加键盘按下事件
		$(window).keydown(function (event) {
			//如果按的是回车键,则提交登录请求
			if (event.keyCode==13){
				$("#loginBtn").click();
			}
		})

        //给登录按钮添加单击事件
       $("#loginBtn").click(function () {
          //收集参数
           var loginAct=$.trim($("#loginAct").val());
           var loginPwd=$.trim($("#loginPwd").val());
           var isRemPwd=$("#isRemPwd").prop("checked");
           //表单验证
           if (loginAct==""){
               alert("用户名不能为空!");
               return;
           }if (loginPwd==""){
               alert("密码不能为空!");
               return;
           }
           //点击登录后显示正在验证
		   $("#msg").html("正在努力验证中。。。")

               //发送请求
               $.ajax({
                   url:'settings/qx/user/login.do',
                   data:{
                       loginAct:loginAct,
                       loginPwd:loginPwd,
                       isRemPwd:isRemPwd
                   },
                   type:'post',
                   dataType:'json',
                   success:function (data) {
                       if (data.code=="1"){
                           //登录成功,跳转到业务的主页面
                           window.location.href="workbench/index.do";
                       }else {
                           //登录失败,显示提示信息
                           $("#msg").html(data.message);
                       }
                   }
               });

       });
    });
    </script>

</head>
<body>
	<div style="position: absolute; top: 0px; left: 0px; width: 60%;">
		<img src="image/IMG_7114.JPG" style="width: 100%; height: 90%; position: relative; top: 50px;">
	</div>
	<div id="top" style="height: 50px; background-color: #3C3C3C; width: 100%;">
		<div style="position: absolute; top: 5px; left: 0px; font-size: 30px; font-weight: 400; color: white; font-family: 'times new roman'">CRM &nbsp;<span style="font-size: 12px;">客户关系管理系统</span></div>
	</div>
	
	<div style="position: absolute; top: 120px; right: 100px;width:450px;height:400px;border:1px solid #D5D5D5">
		<div style="position: absolute; top: 0px; right: 60px;">
			<div class="page-header">
				<h1>登录</h1>
			</div>
			<form action="workbench/index.html" class="form-horizontal" role="form">
				<div class="form-group form-group-lg">
					<div style="width: 350px;">
						<input class="form-control" id="loginAct" type="text" value="${cookie.loginAct.value}" placeholder="用户名">
					</div>
					<div style="width: 350px; position: relative;top: 20px;">
						<input class="form-control" id="loginPwd" type="password" value="${cookie.loginPwd.value}" placeholder="密码">
					</div>
					<div class="checkbox"  style="position: relative;top: 30px; left: 10px;">
						<label>
                            <c:if test="${not empty cookie.loginAct and  not empty cookie.loginPwd}">
                                <input type="checkbox" id="isRemPwd" checked/>
                            </c:if>
                            <c:if test="${empty cookie.loginAct and empty cookie.loginPwd}">
                                <input type="checkbox" id="isRemPwd">
                            </c:if>
							 十天内免登录
						</label>
						&nbsp;&nbsp;
						<span id="msg" style="color: red;"></span>
					</div>
					<button type="button" id="loginBtn" class="btn btn-primary btn-lg btn-block"  style="width: 350px; position: relative;top: 45px;">登录</button>
				</div>
			</form>
		</div>
	</div>
</body>
</html>

项目测试

运行项目后可以正常进入登录页面

测试直接进入主页面

 点击访问后会重新跳转到登录界面

输入正确的账号密码登录后,进入主页面,不关服务器,可以关闭浏览器,在session默认的生命周期内,直接访问主页面,仍然可以不登录直接进入工作台主页面。但如果点击安全退出会清除session,即使不关闭浏览器,再次访问工作台主页面仍然不能访问,需要登录后访问。

如下图,关闭浏览器,仍然可以直接访问首页面不需要登录

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

做一道光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值