0
点赞
收藏
分享

微信扫一扫

利用Graviton2和S3免费套餐搭建私人网盘

Gaaidou 2023-11-02 阅读 63

前言

拦截器是Spring MVC框架提供的一种强大的机制,用于在请求到达控制器之前或之后进行预处理和后处理。它可以拦截并处理请求,对请求进行必要的修改或验证,以及在请求返回给客户端之前进行额外的操作。拦截器可以帮助我们实现各种需求,如身份验证、日志记录、性能监控等。

在本篇博文中,我们将深入研究拦截器的概念、工作原理和使用方法。我们将学习如何创建和配置拦截器,以及如何将其应用于Spring MVC应用程序中。最后,我们还将探讨一些实际应用场景,并给出一些拦截器的最佳实践。

一、前期准备

1、新建项目,结构如下

2、导入依赖
    <dependencies>
    
        <!-- springmvc 依赖,会将spring的核心包一并添加进来 -->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.23</version>
        </dependency>
     
 
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
        </dependency>
 
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.5</version>
        </dependency>
 
 
 
    </dependencies>
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">
    
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
 
 
</web-app>
4、新建 User 类
@Data
public class User {

    private String userName;
    private String password;

}
5、新建一个 LoginService 接口
public interface LoginService {

    /**
     * 登录认证
     * @param userName
     * @param password
     * @return
     */
    User auth(String userName,String password);

}
6、新建一个 LoginServiceImpl 实现类
@Service
public class LoginServiceImpl implements LoginService {
    @Override
    public User auth(String userName, String password) {

        if ("qiu".equals(userName) && "123".equals(password)){
            User user = new User();
            user.setUserName(userName);
            user.setPassword(password);
            return user;
        }
        throw new RuntimeException("账号密码错误");
    }
}
7、新建一个 index.html 页面
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>home page</h1>
</body>
</html>

二、实现拦截器

1、编写一个 controller 
@RestController
@RequiredArgsConstructor
public class UserController {

    private final LoginService service;

    @PostMapping("/auth")
    public ResultVO login(String userName, String password, HttpSession session){
        User auth = service.auth(userName, password);
        session.setAttribute("user",auth);
        return new ResultVO();
    }

}
2、编写登录页面 login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
    <script src="js/JQuery文件.txt.js"></script>
</head>
<body>

<h1>用户登录</h1>
<form id="f1">
    账号:<input type="text" name="userName"/><br>
    密码:<input type="password" name="password"/><br>
    <input type="button" value="登录"/>
</form>
<script>
    $(function(){
        $(':button').on('click', function(){
            let formData = $('#f1').serialize();
            $.ajax({
                url: '../auth',
                type: 'post',
                data: formData,
                success: function (result) {
                    if(result.code === 200) {
                        location.href = 'index.html';
                    }
                },
                error:function (error) {
                    alert(error)
                }
            });
        });
    })
</script>

</body>
</html>
3、编写拦截器
/**
 * @Date 2023-10-27
 * @Author qiu
 * 认证拦截器
 * 拦截所有的请求,如果未登录则返回 401(未登录,未认证) 状态码
 */
@Slf4j
public class AuthInterceptor implements HandlerInterceptor {

    /**
     * 在调用 controller 的请求方法之前执行
     * 如果此方法返回 false ,则请求不会继续往下执行
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("执行 preHandle 方法");
        HttpSession session = request.getSession();
        // 如果 session 为 null 表示用户未登录
        if ( session.getAttribute("user") == null ){
            ResultVO resultVO = new ResultVO();
            // 设置 401 状态码
            resultVO.setCode(HttpStatus.UNAUTHORIZED.value());
            resultVO.setMessage("未登录,请登录!");
            response.setContentType("application/json;charset=utf-8");
            String json = new ObjectMapper().writeValueAsString(resultVO);
            response.getWriter().println(json);
            return false;
        }
        return true;
    }

    /**
     * 在调用 controller 方法之后,返回之前执行
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("执行 postHandle 方法");
    }

    /**
     * 调用 controller 方法并返回之后执行
     * (注意:只有在 preHandle 返回 TRUE ,才会执行)
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("执行 afterCompletion 方法");
    }
}
4、配置 dispatcher-servlet.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: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">


    <!-- 扫描 -->
    <context:component-scan base-package="edu.nf.ch10"/>
    <!-- mvc 注解驱动器 -->
    <mvc:annotation-driven/>
    <!-- 静态资源处理器 -->
    <mvc:default-servlet-handler/>
    <!-- 内部资源视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!-- 配置拦截器 -->
    <mvc:interceptors>
        <!-- 装配具体的拦截器 -->
        <mvc:interceptor>
            <!-- 设置哪些请求会经过这个拦截器 -->
            <mvc:mapping path="/**"/>
            <!-- 排除哪些请求不经过这个拦截器 -->
            <mvc:exclude-mapping path="/static/login.html"/>
            <mvc:exclude-mapping path="/auth"/>
            <mvc:exclude-mapping path="/static/js/**"/>
            <!-- 装配具体的拦截器 -->
            <bean class="edu.nf.ch10.interceptor.AuthInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>




</beans>
5、运行效果
1)非登录效果
2)登录效果
 

 

三、使用拦截器的好处

使用拦截器的好处包括:

  1. 统一处理:可以在拦截器中统一处理一些公共业务逻辑,比如权限校验、日志记录等,避免重复代码的出现。

  2. 粒度控制:可以根据具体的业务场景,选择拦截器拦截请求,实现粒度控制,从而更好地满足业务需求。

  3. 解耦合:通过拦截器可以将多个模块的功能解耦合,降低各组件之间的耦合度,提高代码可维护性和可扩展性。

  4. 提高安全性:通过拦截器可以对请求进行安全控制,比如防止SQL注入、XSS攻击等,提高Web应用系统的安全性。

  5. 性能优化:通过拦截器可以对请求进行缓存、预处理等操作,以提高Web应用系统的性能。

总之,使用拦截器可以帮助我们更好地管理请求,增强代码的可维护性和可读性,提高Web应用系统的安全性和性能。

四、gitee 案例

地址:ch10 · qiuqiu/SpringMVC - 码云 - 开源中国 (gitee.com) 

举报

相关推荐

0 条评论