文章目录
前言
很多时候,都可以用拦截器来实现用户登录的权限的判断:当用户进行登录的时候,如果想要直接进入一个网站的首页面,那么点击对应的前端页面的主页面按钮之后,那么就需要在后台进行权限检验,判断用户是不是已经登录过,也就是说session中有没有存放数据,如果没有存放数据,那么就需要跳转到登录页面,反之则直接进入首页,而这就可以通过拦截器来处理,下面我们进入springmvc拦截器的使用步骤吧!!!
一、springmvc拦截器是什么?
拦截器是springmvc定义的一个功能,它跟原生的servlet中的filter过滤器有同样的功能,不过它使用起来更加方便, 首先客户端发起请求进入DispatcherServlet,再进入我们自定义的拦截器,拦截器实现的是HandlerIntercepter接口,如果拦截成功.
就向客服端返回拦截器响应信息。
如果验证通过,就进入对应的controller,然后结果一系列操作,返回controller响应信息。
二、使用步骤
1.导入相关的依赖
pom.xml:
代码如下(示例):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>spring_intercepter</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</project>
3.web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--1.注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--关联一个springmvc的配置文件:【servlet-name】-servlet.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!--启动级别-1:随着tomcat的启动而启动-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--/ 匹配所有的请求;(不包括.jsp)-->
<!-- 匹配所有的请求;(包括.jsp)-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 配置请求过滤器,编码格式设为UTF-8,避免中文乱码 -->
<filter>
<filter-name>charsetfilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>charsetfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
4.springmvc核心配置文件
<?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: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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
<context:component-scan base-package="com.lhh.controller"/>
<!-- 让Spring MVC不处理静态资源 -->
<mvc:default-servlet-handler />
<!--
支持mvc注解驱动
在spring中一般采用@RequestMapping注解来完成映射关系
要想使@RequestMapping注解生效
必须向上下文中注册DefaultAnnotationHandlerMapping
和一个AnnotationMethodHandlerAdapter实例
这两个实例分别在类级别和方法级别处理。
而annotation-driven配置帮助我们自动完成上述两个实例的注入。
-->
<mvc:annotation-driven />
<!--视图解析器:DispatcherServlet给他的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!--定义拦截器,每写一个拦截器,那么就需要在springmvc的核心配置文件当中进行配置-->
<mvc:interceptors>
<mvc:interceptor>
<!--拦截一个请求-->
<!--<mvc:mapping path="/xxx"/>-->
<!--需要拦截的请求,这里是拦截所有的请求-->
<mvc:mapping path="/**"/>
<!--定义请求由哪个bean来进行处理-->
<bean class="com.lhh.config.UserInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>
5.controller层
package com.lhh.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@Controller
@RequestMapping("/user")
public class UserControlelr {
/*用户登录,传递参数,调用该方法*/
@RequestMapping("/login")
public String login( String username, String password, HttpServletRequest request, Model model){
System.out.println("88888888888888");
HttpSession session = request.getSession();
session.setAttribute("userLoginInfo","xxx");
model.addAttribute("username",username);
return "main";
}
/*用户点击登录,请求传过来,调用该方法,跳到login页面*/
@RequestMapping("/goLogin")
public String goLogin(){
return "login";
}
@RequestMapping("/main")
public String goMain(){
return "main";
}
@RequestMapping("/logout")
public String logout(HttpSession session){
//因为要退出登录,所以需要将session中的数据清除
session.removeAttribute("userLoginInfo");
return "login";
}
}
6.拦截器定义
package com.lhh.config;
import org.springframework.web.servlet.AsyncHandlerInterceptor;
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 UserInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
System.out.println("request.getRequestURI()="+request.getRequestURI());
//在index.jsp页面点击首页,然后因为没有用户的登录信息,所以需要跳转到登录页面,(此时也是第一次登录,那么应该放行,不然输入了用户名和密码之后还是不会登进去
// 因为session并没有存放数据,会走下面的请求转发,服务器内部再次跳到登录页面)
if(request.getRequestURI().contains("login")){
return true;
}
/*如果session中带有参数,那么已经登录过,直接放行,可以进首页*/
if (session.getAttribute("userLoginInfo") != null) {
return true;
}
/*直接请求登录,用户直接点击了登录按钮放行*/
if (request.getRequestURI().contains("goLogin")) {
return true;
}
//请求转发跳到登录页面,因为不能直接登录,属于第一次登录。
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
return false;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
登录页面login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/user/login" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="pwd"><br>
<input type="submit" value="提交"><br>
</form>
</body>
</html>
7.前端代码
主页面main.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>首页</h1>
<h2>${
username}</h2>
<a href="${pageContext.request.contextPath}/user/logout" style="text-decoration: none">注销用户</a>
</body>
</html>
index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h1><a href="${pageContext.request.contextPath}/user/goLogin">登录</a></h1>
<h1><a href="${pageContext.request.contextPath}/user/main">首页</a></h1>
</body>
</html>
配置tomcat服务器:
贴一下项目结构:
运行截图,点击登录: ![在这里插入图片描述](https://img-blog.csdnimg.cn/2020100810184524.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNDg2Nzc1,size_16,color_FFFFFF,t_70#pic_center)
再次回到index.jsp点击首页,那么就可以直接登录了,因为之前已经用“的士速递”进行登录过了。
总结
写一个拦截器,对请求进行拦截,需要让自己的类实现springmvc中的HandlerInterceptor接口,然后实现接口中的方法,一般来说,只需要写preHandle()方法即可,(而postHandle()和afterHandle()方法两个想法用于跟日志相关的操作,后续应该会使用到。)就可以实现在请求发送,调用相关的方法的时候,先进行拦截,处理,处理完毕之后,根据处理的结果判断放行还是不放行。
另外,还有写一个细节,那就是,每次导完依赖的时候,需要在file–>project-structure---->artifacts中把lib文件添加到WEB-INF下,并把pom.xml中的依赖都导入到lib文件夹下(没有lib文件夹需要手动创建)。