Spring MVC拦截器、文件上传和全局异常处理

目录

  • 1.拦截器
    • 1.1.什么是拦截器?
    • 1.2 拦截器的API
    • 1.3 拦截器的执行顺序
    • 1.5 自定义拦截器
    • 1.5 登录拦截器案例
  • 2.文件上传
    • 2.1 添加依赖
    • 2.2 配置文件上传解析器
    • 2.3 编写控制器
    • 2.4 编写jsp页面
    • 2.5 注意事项
  • 3.全局异常处理器
    • 3.1 异常处理思路
    • 3.2 创建异常处理器
    • 3.3 编写异常类
    • 3.4 配置异常处理器

1.拦截器

1.1.什么是拦截器?

​ Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理。例如通过拦截器可以进行权限验证、判断用户是否登录等。

​ 拦截器依赖于web框架,在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。

过滤器与拦截器的区别:拦截器是AOP思想的具体应用。

过滤器:

  • servlet规范中的一部分,任何java web工程都可以使用

  • 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截

拦截器:

  • 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用

  • 拦截器只会拦截访问的控制器方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的

1.2 拦截器的API

定义拦截器需要实现HandlerInterceptor接口,该接口中有三个方法:

  • preHandle()

控制层执行器方法前的拦截器(该方法时在控制层执行器方法前调用,当该方法返回结果为true则继续调用下一个拦截器,如果已经是最后一个拦截器,则调用控制层中的执行器方法;当该方法返回结果为false,则不会继续执行控制层执行器中的方法)

  • postHandle()

控制层方法返回时拦截器(该方法是控制层执行器方法执行之后,由DispatcherServlet在将结果响应给浏览器前调用的方法)

  • afterCompletion()

控制层方法结束后的拦截器(该方法在请求业务处理执行完全结束之后由DispatcherServlet调用执行)

1.3 拦截器的执行顺序

  • 单个拦截器的执行顺序

preHandle()postHandle()afterCompletion()

  • 多个拦截器的执行顺序
  1. 先按顺序执行所有拦截器的 preHandle方法

  2. 如果任何一个拦截器preHandle方法返回false。直接跳出不执行目标方法

    • 如果当前拦截器prehandler返回为true。则执行下一个拦截器的preHandle方法
    • 如果当前拦截器返回为false。直接倒序执行所有已经执行了的拦截器的 afterCompletion方法;
  3. 所有拦截器都返回True。执行目标方法

  4. 倒序执行所有拦截器的postHandle方法。

  5. 前面的步骤有任何异常都会直接倒序触发 afterCompletion

  6. 页面成功渲染完成以后,也会倒序触发 afterCompletion

1.5 自定义拦截器

我们要想自定义拦截器, 要求必须实现:HandlerInterceptor 接口。

  • 创建拦截器

配置web.xml 和 springmvc-servlet.xml 文件

package com.by.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class CustomHandlerInterceptor implements HandlerInterceptor {/*** 在控制器方法调用前执行* 返回值为是否中断*      true:表示继续执行(下一个拦截器或处理器)*      false:则会中断后续的所有操作,所以我们需要使用response来继续响应后续请求*/@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object object) throws Exception {System.out.println("HandlerInterceptor preHandle ....");return true;}/*** 在控制器方法调用后,解析视图前调用,我们可以对视图和模型做进一步渲染或修改* 可在modelAndView中加入数据,比如当前时间*/@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response, Object object, ModelAndView modelAndView) throws Exception {System.out.println("HandlerInterceptor postHandle ....");}/*** 整个请求完成,即视图渲染结束后调用,这个时候可以做些资源清理工作,或日志记录*/@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object object, Exception e) throws Exception {System.out.println("HandlerInterceptor afterCompletion ....");}
}
  • 配置拦截器
    <!--配置拦截器 --><mvc:interceptors><mvc:interceptor><!-- 匹配的是url路径 --><mvc:mapping path="/**"></mvc:mapping><bean class="com.by.interceptor.CustomHandlerInterceptor"></bean></mvc:interceptor></mvc:interceptors>
  • 测试

  • 编写controller

@Controller
@RequestMapping("/account")
public class AccountController {@RequestMapping("/findAccount12")public String findAccount12(Model model) {model.addAttribute("msg", "欢迎你 springmvc");System.out.println("controller的方法执行了......");return "success";}
}

1.5 登录拦截器案例

  • 创建拦截器
package com.by.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object object) throws Exception {String user = (String) request.getSession().getAttribute("user_session");if (user != null) {//已经登录,继续执行System.out.println("获得用户信息:"+user);return true;} else {//未登录,跳转到登录页面response.sendRedirect(request.getContextPath() +"/login.jsp");return false;}}
}
  • 配置拦截器
	<mvc:interceptors><mvc:interceptor><!-- 匹配的是url路径 --><mvc:mapping path="/**"></mvc:mapping><bean class="com.by.interceptor.LoginInterceptor"></bean></mvc:interceptor></mvc:interceptors>
  • 测试
  1. 编写controller
@Controller
@RequestMapping("/account")
public class AccountController {@RequestMapping("/findAccount13")public String findAccount13(Model model) {model.addAttribute("msg", "欢迎你 springmvc");System.out.println("controller的方法执行了......");return "success";}
}
  1. 在index.jsp里面定义超链接
<%session.setAttribute("user_session","User{name:张二狗,age:18}");
%>
<a href="/account/findAccount13">登录拦截器</a>

2.文件上传

2.1 添加依赖

<!--文件上传-->
<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version>
</dependency>

2.2 配置文件上传解析器

<!--配置文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="maxUploadSize" value="5242880" /><property name="defaultEncoding" value="UTF-8" />
</bean>

2.3 编写控制器

  • 编写controller
@Controller
@RequestMapping("/account")
public class AccountController {@RequestMapping(path="/upload")public String upload(HttpServletRequest request, MultipartFile upload,Model model) throws IOException {System.out.println("springmvc方式的文件上传");//获取要上传的文件目录String path = request.getSession().getServletContext().getRealPath("/uploads");System.out.println("path:"+path);//根据文件上传的目录创建File对象,如果不存在则创建1个File对象File file = new File(path);if(!file.exists()){//创建一个file对象file.mkdirs();}//获取文件上传名称String filename = upload.getOriginalFilename();//完成文件上传upload.transferTo(new File(path,filename));model.addAttribute("msg", "欢迎你 springmvc");return "success";}
}

2.4 编写jsp页面

    <form action="/account/upload" method="post" enctype="multipart/form-data">文件: <input type="file" name="upload"></input><input type="submit" value="提交"></form>

2.5 注意事项

  1. form表单必须加上enctype="multipart/form-data"
  2. method属性取值必须是Post
  3. 提供一个文件选择域<input type="file"/>

3.全局异常处理器

即使对大部分情况都做了预判和异常处理,但程序有时会因为莫名奇妙的原因发生错误,并且错误信息肯定会抛在浏览器页面上,这样用户观感特别不好,所以需要进行全局异常处理。

3.1 异常处理思路

系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:

异常处理

3.2 创建异常处理器

@Component
public class CustomExceptionResolver implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex) {ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("message", ex.getMessage());modelAndView.setViewName("error");return modelAndView;}
}

3.3 编写异常类

@Controller
@RequestMapping("/account")
public class AccountController {@RequestMapping("/findAccount14")public String findAccount14(Model model) {model.addAttribute("msg", "欢迎你 springmvc");//模拟异常信息int i = 10/0;return "success";}
}

3.4 配置异常处理器

<bean class="com.by.exception.CustomExceptionResolver "></bean>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/857896.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FlinkCDC sink paimon 暂不支持exactly-once写入,而通过 幂等写

幂等写入&#xff1a; 一个幂等操作无论执行多少次都会返回同样的结果。例如&#xff0c;重复的向hashmap中插入同样的key-value对就是幂等操作&#xff0c;因为头一次插入操作之后所有的插入操作都不会改变这个hashmap&#xff0c;因为hashmap已经包含这个key-value对了。另一…

vuejs3用gsap实现动画

效果 gsap官网地址&#xff1a; https://gsap.com/ 安装gsap npm i gsap 创建Gsap.vue文件 <script setup> import {reactive, watch} from "vue"; import gsap from "gsap"; const props defineProps({value:{type:Number,default:0} }) cons…

FFmpeg编译4

CPUx86-64 TOOLCHAIN N D K / t o o l c h a i n s / x 8 6 6 4 − 4.9 / p r e b u i l t / l i n u x − x 8 6 6 4 S Y S R O O T NDK/toolchains/x86_64-4.9/prebuilt/linux-x86_64 SYSROOT NDK/toolchains/x866​4−4.9/prebuilt/linux−x866​4SYSROOTNDK/platforms/and…

Java | Leetcode Java题解之第174题地下城游戏

题目&#xff1a; 题解&#xff1a; class Solution {public int calculateMinimumHP(int[][] dungeon) {int n dungeon.length, m dungeon[0].length;int[][] dp new int[n 1][m 1];for (int i 0; i < n; i) {Arrays.fill(dp[i], Integer.MAX_VALUE);}dp[n][m - 1] …

QML 实现上浮后消失的提示框

基本效果&#xff1a;上浮逐渐显示&#xff0c;短暂停留后上浮逐渐消失 为了能同时显示多个提示框&#xff0c;一是需要动态创建每个弹框 Item&#xff0c;二是弹出位置问题&#xff0c;如果是底部为基准位置就把已经弹出的往上移动。 效果展示&#xff1a; 主要实现代码&…

46、基于自组织映射神经网络的鸢尾花聚类(matlab)

1、自组织映射神经网络的鸢尾花聚类的原理及流程 自组织映射神经网络&#xff08;Self-Organizing Map, SOM&#xff09;是一种用于聚类和数据可视化的人工神经网络模型。在鸢尾花聚类中&#xff0c;SOM 可以用来将鸢尾花数据集分成不同的类别&#xff0c;同时保留数据间的拓扑…

动态规划——买卖股票的最佳时机含冷冻期

1、题目链接 leetcode 309. 买卖股票的最佳时机含冷冻期 2、题目分析 该题有我们可以定义三种状态&#xff0c;买入状态&#xff0c;可交易状态 &#xff0c;冷冻期状态 我们可以建立一个n*3的二维数组来表示这三种状态&#xff1a; 根据这个图可以看出&#xff0c; 可以从…

不到3毛钱的SOT23和SOT89封装18V耐压低功耗高PSRR高精度LDO稳压芯片ME6231电流0.5A电压3.3V和1.8V

前言 SOT23-5封装ME6231外观和丝印 一款国产LDO&#xff0c;某些场合&#xff0c;要把1117扔了吧&#xff0c;SOT23封装&#xff0c;虽然不是最小&#xff0c;但也是够小的了。 参考价格&#xff1a;约0.25元 概述 ME6231 系列是以 CMOS 工艺制造的 18V 耐压、低功耗、高 PSR…

2024-06-23 操作系统实验5——模拟页式存储管理

文章目录 一、实验目的二、实验内容三、实验过程四、结果测试五、实验总结和说明 补录与分享本科实验&#xff0c;以示纪念。 一、实验目的 通过编写和调试请求页式存储管理的模拟程序以加深对请求页式存储管理方案的理解。 二、实验内容 页面淘汰算法可采用FIFO置换算法&a…

从理论到实践掌握UML

统一建模语言&#xff08;UML&#xff09;是软件工程师用来设计软件系统的一种工具&#xff0c;就像是一套图形化的说明书。它让开发团队能够以图形化的方式来理解、设计和开发软件系统&#xff0c;比起用文字来描述&#xff0c;更加直观易懂。本文通过UML实例化的理论和实践相…

ROS | 常见故障排查

1.开启后发出一个WIFI WIFI名字&#xff1a;WHEELTEC接数字 安全密钥&#xff1a;dongguan 2.显示屏接口 USB接口接键鼠 3.远程登录命令 ssh -Y wheeltec192.168.0.100 是小车发出的WIFI的一个IP地址 4. 登录后确保IP地址 ip a 看一下 当前ip地址 倒数第四行-当前ip地址 1…

django学习入门系列之第三点《CSS基础样式介绍3》

文章目录 浮动什么是浮动浮动的特性清除浮动 往期回顾 浮动 什么是浮动 float属性用于创建浮动框&#xff0c;将其移动到一边&#xff0c;直到左边缘或右边缘触及包含块或另一个浮动框的边缘。 浮动的特性 浮动元素会脱离标准流(脱标) 浮动的元素会一行内显示并且元素顶部对…

51单片机STC89C52RC——6.3 定时器/计数器 实现计时功能(定时器+中断系统+LCD1602液晶显示器)

目录 目的/效果 一&#xff0c;STC单片机模块 二&#xff0c;定时器 中断系统LCD1602显示 三&#xff0c;创建Keil项目 四&#xff0c;代码 五&#xff0c;代码编译、下载到51单片机 ​ 目的/效果 用定时器实现系统中断&#xff0c;计时信息显示在LCD1602上。效果如下 …

springAI(一)

目录 一、spring AI 目的 二、spring AI 来源 三、sprig AI 是什么&#xff1f; 四、spring AI中的 概念 4.1、模型&#xff08;Models&#xff09; 4.2、提示&#xff08;Prompts&#xff09; 4.3、提示模板&#xff08;Prompt Templates&#xff09; 4.4、令 牌&#…

Axios-入门

介绍 Axios对原生Ajax进行了封装&#xff0c;简化书写&#xff0c;快速开发 官网&#xff1a;Axios中文文档 | Axios中文网 (axios-http.cn) 入门 1引入Axios的js文件 <script src"js/axios.js"></script> 2使用Axios发送请求&#xff0c;并获取响应…

系统架构师考点--嵌入式技术

​大家好。今天来总结一下嵌入式技术的考点。该考点分值3-5分&#xff0c;上午场选择题和下午场案例题都可能会考&#xff0c;但不是每年都考。 一、嵌入式微处理体系结构 冯诺依曼结构&#xff1a;传统计算机采用冯诺依曼(Von Neumann)结构&#xff0c;也称普林斯顿结构是一…

【代码随想录】【算法训练营】【第45天】 [198]打家劫舍 [213]打家劫舍II [337]打家劫舍III

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 45&#xff0c;周五&#xff0c;坚持不了一点~ 题目详情 [198] 打家劫舍 题目描述 198 打家劫舍 解题思路 前提&#xff1a; 思路&#xff1a; 重点&#xff1a; 代码实现 C语言 虚拟头…

中国科学院西北生态环境资源研究院联合多单位在《PNAS》发文:气候变暖对多年冻土区地上与地下生物量分布的影响

文章简介 论文名称&#xff1a;Changes in above-versus belowground biomass distribution in permafrost regions in response to climate warming&#xff08;气候变暖对多年冻土区地上与地下生物量分布的影响&#xff09; 第一作者及单位&#xff1a;贠汉伯&#xff08;研…

SCI一区TOP|双曲正弦余弦优化算法(SCHO)原理及实现【免费获取Matlab代码】

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2023年&#xff0c;J Bai受到双曲正弦余弦函数启发&#xff0c;提出了双曲正弦余弦优化算法&#xff08;Sinh Cosh optimizer, SCHO&#xff09;。 2.算法原理 2.1算法思想 SCHO灵感来源…

1panel + Pbootcms 设置伪静态规则

这里确保我们引用的样式路径是否是这样的&#xff0c;&#xff08;不然可能会设置了伪静态无法加载样式&#xff09; //这种格式在不开起伪静态是可以引入的&#xff0c;一旦开启就不行了,一定要在static 前面加上反斜杠 /<link rel"stylesheet" href"{pbo…