【Java框架】SpringMVC(三)——异常处理,拦截器,文件上传,SSM整合

目录

  • 异常处理
    • 解释
    • 局部异常处理
    • 全局异常
  • 拦截器
    • 拦截器介绍
    • 作用:
    • 拦截器和过滤器之间的区别
    • 拦截器执行流程
    • 代码实现
    • 补充
  • 文件上传
    • 依赖
    • 配置MultipartResolver
    • 编写文件上传表单页
    • API
      • MultipartFile
      • File.separator
      • 必须对上传文件进行重命名
      • 代码示例
    • SpringMVC文件上传流程
    • 多文件上传
  • 静态资源加载
    • 1.将静态资源统一放在一个路径下
    • 2.配置静态资源加载
  • SSM整合

异常处理

  • HandlerExceptionResolver
    • resolveException()
  • 局部异常处理
    • 仅能处理指定Controller中的异常
    • @ExceptionHandler

解释

  • Spring MVC 通过HandlerExceptionResolver 处理程序的异常,包括Handler 映射、数据绑定以及目标方法执行时发生的异常。
  • 主要处理Handler 中用@ExceptionHandler 注解定义的方法。
  • ExceptionHandlerMethodResolver 内部若找不到@ExceptionHandler 注解的话, 会找@ControllerAdvice 类的@ExceptionHandler 注解方法, 这样就相当于一个全局异常处理器。

局部异常处理

package cn.smbms.controller;import cn.smbms.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;/*** @author: zjl* @datetime: 2024/4/18* @desc:*/
@RestController
public class HelloController {@GetMapping(value = "/index")public String index(){System.out.println(5/0);//模拟异常return "index";}/*** 这里处理ArithmeticException.class,NullPointerException.class类型的异常* Exception ex: 生成的异常对象,会传递给ex, 通过ex可以得到相关的异常信息,这里程序员可以加入自己的业务逻辑* 这里采用ServletAPI入参,HttpServletRequest、HttpServletResponse、HttpSession...都可以直接用*/@ExceptionHandler({ArithmeticException.class,NullPointerException.class})public String localException(Exception ex, HttpServletRequest request){System.out.println("局部异常信息是-" + ex.getMessage());//如何将异常的信息带到下一个页面.request.setAttribute("errorInfo", ex.getMessage());return "error";}
}

全局异常

  • 对所有异常进行统一处理
  • 配置SimpleMappingExceptionResolver
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"><property name="exceptionMappings"><props><!--<prop key="java.lang.NullPointerException">null.jsp</prop><prop key="java.lang.ClassNotFoundException">class.jsp</prop><prop key="java.sql.SQLException">sql.jsp</prop><prop key="java.io.IOException">io.jsp</prop>--><prop key="java.lang.RuntimeException">error</prop></props></property></bean>

拦截器

在这里插入图片描述

  1. 浏览器发送一个请求会先到Tomcat的web服务器
  2. Tomcat服务器接收到请求以后,会去判断请求的是静态资源还是动态资源
  3. 如果是静态资源,会直接到Tomcat的项目部署目录下去直接访问
  4. 如果是动态资源,就需要交给项目的后台代码进行处理
  5. 在找到具体的方法之前,我们可以去配置过滤器(可以配置多个),按照顺序进行执行
  6. 然后进入到到中央处理器(SpringMVC中的内容),SpringMVC会根据配置的规则进行拦截
  7. 如果满足规则,则进行处理,找到其对应的controller类中的方法进行执行,完成后返回结果
  8. 如果不满足规则,则不进行处理

这个时候,如果我们需要在每个Controller方法执行的前后添加业务,具体该如何来实现?——拦截器

拦截器介绍

拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行

作用:

  • 在指定的方法调用前后执行预先设定的代码
  • 阻止原始方法的执行
  • 总结:拦截器就是用来做增强

拦截器和过滤器之间的区别

  • 归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术
  • 拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强
    在这里插入图片描述

拦截器执行流程

在这里插入图片描述

代码实现

自定义拦截器类

package cn.smbms.interceptor;import cn.smbms.tools.Constants;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** @author: zjl* @datetime: 2024/4/12* @desc:*/
public class SysInterceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {Object obj = request.getSession().getAttribute(Constants.USER_SESSION);if(obj == null){//未登录,重定向到401.jspresponse.sendRedirect(request.getContextPath() + "/401.jsp");return false;}return true;}
}

配置拦截规则

    <!-- 配置拦截器interceptors --><mvc:interceptors><mvc:interceptor><mvc:mapping path="/**"/><!-- 配置拦截规则 --><mvc:exclude-mapping path="/login.do"/><!-- 配置不拦截规则 --><mvc:exclude-mapping path="/logout"/><!-- 配置不拦截规则 --><bean class="cn.smbms.interceptor.SysInterceptor"/></mvc:interceptor></mvc:interceptors>

补充

  • 当配置多个拦截器时,形成拦截器链
  • 拦截器链的运行顺序参照拦截器添加顺序为准
  • 当拦截器中出现对原始处理器的拦截,后面的拦截器均终止运行
  • 当拦截器运行中断,仅运行配置在前面的拦截器的afterCompletion操作
    在这里插入图片描述

preHandle:与配置顺序相同,必定运行

postHandle:与配置顺序相反,可能不运行

afterCompletion:与配置顺序相反,可能不运行。

文件上传

  • MultipartResolver接口
    • 用于处理上传请求,将上传请求包装成可以直接获取文件的数据,方便操作
  • 两个实现类
    • StandardServletMultipartResolver
      • 使用了Servlet3.0标准的上传方式
    • CommonsMultipartResolver
      • 使用了Apache的commons-fileupload来完成具体的上传操作

依赖

	<!-- 文件上传 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.8.1</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version></dependency>

配置MultipartResolver

    <!-- 配置MultipartResolver,用于上传文件,使用spring的CommonsMultipartResolver --><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="maxUploadSize" value="5000000"/><!-- 上传文件大小上限,单位为字节-- ><property name="defaultEncoding" value="UTF-8"/><!-- 请求的编码格式,默认为ISO-8859-1,此处设置为UTF-8 --></bean>

编写文件上传表单页

  • method=“POST”
  • enctype=“multipart/form-data”
    • 指定表单内容类型,支持文件上传
  • <input type=“file” name=“a_idPicPath”/>
    • 用来上传文件的file组件

API

MultipartFile

  • Spring MVC会将上传文件绑定到MultipartFile对象中,并通过该对象完成文件的上传操作

File.separator

  • Windows、Linux自适应路径分隔符
  • 低入侵性的代码实现

必须对上传文件进行重命名

原因

  • 原文件名存在中文 乱码问题
  • 原文件名与服务器上已有文件重名 覆盖问题

重新定义上传文件名(保证不重名)

  • 当前系统时间+随机数+“_Personal.jpg”

文件上传成功后,须更新数据库字段(idPicPath),记录上传文件的存储路径

代码示例

	//文件上传@RequestMapping(value="/useraddsave.html",method=RequestMethod.POST)public String addUserSave(User user,HttpSession session,HttpServletRequest request,@RequestParam(value ="a_idPicPath", required = false) MultipartFile attach){String idPicPath = null;//判断文件是否为空if(!attach.isEmpty()){String path = request.getSession().getServletContext().getRealPath("statics"+File.separator+"uploadfiles"); logger.info("uploadFile path ============== > "+path);String oldFileName = attach.getOriginalFilename();//原文件名logger.info("uploadFile oldFileName ============== > "+oldFileName);String prefix=FilenameUtils.getExtension(oldFileName);//原文件后缀     logger.debug("uploadFile prefix============> " + prefix);int filesize = 500000;logger.debug("uploadFile size============> " + attach.getSize());if(attach.getSize() >  filesize){//上传大小不得超过 500krequest.setAttribute("uploadFileError", " * 上传大小不得超过 500k");return "useradd";}else if(prefix.equalsIgnoreCase("jpg") || prefix.equalsIgnoreCase("png") || prefix.equalsIgnoreCase("jpeg") || prefix.equalsIgnoreCase("pneg")){//上传图片格式不正确String fileName = System.currentTimeMillis()+RandomUtils.nextInt(1000000)+"_Personal.jpg";  logger.debug("new fileName======== " + attach.getName());File targetFile = new File(path, fileName);  if(!targetFile.exists()){  targetFile.mkdirs();  }  //保存  try {  attach.transferTo(targetFile);  } catch (Exception e) {  e.printStackTrace();  request.setAttribute("uploadFileError", " * 上传失败!");return "useradd";}  idPicPath = path+File.separator+fileName;}else{request.setAttribute("uploadFileError", " * 上传图片格式不正确");return "useradd";}}user.setCreatedBy(((User)session.getAttribute(Constants.USER_SESSION)).getId());user.setCreationDate(new Date());user.setIdPicPath(idPicPath);if(userService.add(user)){return "redirect:/user/userlist.html";}return "useradd";}

省略service、mapper、sql代码

SpringMVC文件上传流程

在这里插入图片描述

多文件上传

<label for="a_idPicPath">证件照:</label>
<input type="file" name="attachs" id="a_idPicPath"/>
<label for="a_workPicPath">工作证照片:</label>
<input type="file" name="attachs" id="a_workPicPath"/>
  • 控制器-处理方法addUserSave()
    • 修改入参MultipartFile为数组
      • MultipartFile[] attachs
  • MultipartFile[] 数组内存放文件对象顺序
    • 按照form表单的file标签的顺序进行存储
  • 分别更新字段:idPicPath、workPicPath
  • 若入参对象MultipartFile为数组时,该参数前面必须要加上@RequestParam注解,否则会报错
@RequestParam(value="a_idPicPath",required=false) 		    							MultipartFile idPicFile,
@RequestParam(value="a_workPicPath",required=false)MultipartFile workPicFile)

静态资源加载

1.将静态资源统一放在一个路径下

在这里插入图片描述

2.配置静态资源加载

    <mvc:resources location="/statics/" mapping="/statics/**"></mvc:resources>

SSM整合

  • 1.使用IDEA创建SSM的Maven工程
  • 2.在main目录中创建出来java和resources目录
  • 3.修改pom.xml
    • 3.1导入SSM使用的依赖
    • 3.2导入resources配置
    • 3.3对maven工程重新构建(reload project)
  • 4.创建package目录结构,基本目录命名规则:com.项目名简称
    实体类:entity或pojo
    请求层:controller
    业务层:service
    数据访问层:mapper
    工具类包:utils或tools
    配置类包:config
    过滤器包:filter
    拦截器包:interceptor
  1. 导入SSM使用的配置文件,放在resources目录下
  • 5.1spring配置文件:applicationContext.xml【修改扫描的包路径】
  • 5.2springMvc配置文件:springm-servlet.xml【修改扫描的包路径,去掉没用的配置】
  • 5.3创建mybatis目录,导入mybatis配置文件:mybatis-config.xml【修改实体类别名的包名】
  • 5.4在mybatis目录下创建mapper目录
  • 5.5将写SQL的mapper.xml导入进来,修改为对应实体类的mapper.xml【修改namespace的路径】
  • 5.6数据库配置文件:database.properties【修改数据库连接信息】
  • 5.7日志配置文件:log4j.properties
  • 5.8web.xml配置文件:修改启动页“welcome-file”、引入spring、springmvc、过滤器的配置
  • 5.9注意:修改配置文件中的自定义配置(包名、路径名等)
  • 6.编写java代码
    pojo——controller——service——mapper——mapper.xml
  • 7.编写前端页面
    • 将前端页面统一放在一个目录下(jsp),以便配置视图解析器,在请求层可以直接使用逻辑视图名。
  • 8.编写/导入静态资源
    • 图片、音频、视频、样式、js、插件等等
    • 注意:将静态资源统一放在webapp/statics下
    • 若没有statics目录需要手动创建。
  • 9.在springm-servlet.xml中配置静态资源访问,否则无法使用静态资源
  • 10.在编写完请求层、业务逻辑层、以及SQL后,可以进行功能测试

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

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

相关文章

AWS制作WordPress在国内外的利弊?

AWS作为全球领先的云计算服务供应商&#xff0c;为WordPress提供了强大且灵活的托管环境&#xff0c;使用AWS来搭建和运行WordPress无疑是个不错的选择。即便如此使用AWS制作还是会有些许利弊&#xff0c;九河云作为AWS的合作伙伴来为读者们仔细探讨AWS在WordPress的利弊。 利&…

学python的第十九天

网络通信和访问数据库 1.1 基本的网络知识 TCP/IP IP是低级的路由协议&#xff0c;它将数据拆分在许多小的数据包中&#xff0c;并通过网络将他们发送到某一特定地址&#xff0c;但无法保证所有包都抵达目的地&#xff0c;也不能保证包按顺序抵达 TCP&#xff08;传输控制协议…

深度学习系列65:数字人openHeygen详解

1. 主流程分析 从inference.py函数进入&#xff0c;主要流程包括&#xff1a; 1&#xff09; 使用cv2获取视频中所有帧的列表&#xff0c;如下&#xff1a; 2&#xff09;定义Croper。核心代码为69行&#xff1a;full_frames_RGB, crop, quad croper.crop(full_frames_RGB)。…

Android MVVM架构 + Retrofit完成网络请求

关于Retrofit&#xff0c;这个应该不是一个很新颖的东西了&#xff0c;简单过一下吧 1.由Square公司开发&#xff0c;基于Type-safe的REST客户端。 2.使用注解来定义API接口&#xff0c;使得HTTP请求变得简洁且易于维护。 3.支持同步和异步请求&#xff0c;可与RxJava、Corouti…

【安卓13】解决带GMS编译报super分区空间不足错误

1、错误信息 2、解决方案 不同供应商修改分区大小的文件路径不一样&#xff0c;但是万变不离其宗&#xff0c;根据报错信息全局搜索关键词BOARD_SUPER_PARTITION_SIZE 这里以RK供应商和AML供应商修改为例&#xff1a; &#xff08;1&#xff09;RK改法&#xff1a; 根目录下…

全光谱灯对人体的危害?谨记全光谱灯选购要避开的四大套路

全光谱灯对人体的危害有多大&#xff1f;近年来网上关于护眼台灯对视力有害的言论有很多&#xff0c;引发了很多人空前的关注&#xff0c;事实上这未必是一件坏事&#xff0c;因为随着护眼台灯的热度持续上涨&#xff0c;市面上浑水摸鱼的行为增多了不少&#xff0c;有着不少劣…

STM32H7使用FileX库BUG,SD卡挂载失败

问题描述&#xff1a; 使用STM32H7ThreadXFileX&#xff0c;之前使用swissbit牌的存储卡可正常使用&#xff0c;最近项目用了金士顿的存储卡&#xff0c;发现无法挂载文件系统。 原因分析&#xff1a; 调试过程发现&#xff0c;关闭D-Cache可以挂载使用exfat文件系统。 File…

一文看够,植物线粒体基因组分析套路

线粒体堪称生命活动的“能量供给站”&#xff0c;植物线粒体是线粒体基因组研究中难度最高的&#xff0c;其基因组大小差异较大&#xff0c;100kb-10Mb&#xff0c;大部分由非编码DNA序列组成&#xff0c;且有许多同源序列&#xff0c;占基因组总长的2%-60%&#xff0c;基因间区…

制作github.io学术个人主页

制作如图的学术个人主页。About me - Xianwen Ling’s Blog 学术个人主页是一个学者展示个人学术成果和研究方向的重要工具。个人主页可以集中展示学者的研究论文、出版物、演讲和发布的项目等学术成果&#xff0c;这样其他人可以更方便地了解和评估学者的研究贡献。个人主页可…

Maven 安装及配置教程(Windows)【安装】

文章目录 一、 下载1. 官网下载2. 其它渠道 二、 安装三、 配置四、 验证五、 本地仓储配置六、 配置镜像七、 配置JDK八、完整配置九、常用命令十、IDEA 中配置 Maven1. 配置当前项目2. 配置新建 / 新打开 项目 软件 / 环境安装及配置目录 一、 下载 1. 官网下载 安装地址&a…

书生·浦语大模型第二期实战营第七节-OpenCompass 大模型评测实战 笔记和作业

来源&#xff1a; 视频教程&#xff1a;https://www.bilibili.com/video/BV1Pm41127jU/?spm_id_from333.788&vd_sourcef4a51f7f5a63e756f73ad0dff318c1a3 文字教程&#xff1a;https://github.com/InternLM/Tutorial/blob/camp2/opencompass/readme.md 作业来源&#x…

【Hadoop】- MapReduce YARN 初体验[9]

目录 提交MapReduce程序至YARN运行 1、提交wordcount示例程序 1.1、先准备words.txt文件上传到hdfs&#xff0c;文件内容如下&#xff1a; 1.2、在hdfs中创建两个文件夹&#xff0c;分别为/input、/output 1.3、将创建好的words.txt文件上传到hdfs中/input 1.4、提交MapR…

HotSpot JVM 中的应用程序/动态类数据共享

0.前言 本文的目的是详细讨论 HotSpot JVM 自 JDK 1.5 以来提供的一项功能&#xff0c;该功能可以减少启动时间&#xff0c;但如果在多个 JVM 之间共享相同的类数据共享 (CDS) 存档&#xff0c;则还可以减少内存占用。 1.类数据共享 (CDS) CDS 的想法是使用特定格式将预处理…

状态模式和策略模式对比

状态模式和策略模式都是行为型设计模式&#xff0c;它们的主要目标都是将变化的行为封装起来&#xff0c;使得程序更加灵活和可维护。之所以将状态模式和策略模式进行比较&#xff0c;主要是因为两个设计模式的类图相似度较高。但是&#xff0c;从状态模式和策略模式的应用场景…

Pulsar Meetup 深圳 2024 会务介绍

“ Hi&#xff0c;各位热爱 Pulsar 的小伙伴们&#xff0c;Pulsar Meetup 深圳 2024 报名倒计时啦&#xff0c;快来报名。这里汇集了腾讯、华为和谙流科技等大量 Pulsar 大咖&#xff0c;干货多多&#xff0c;礼品多多&#xff0c;不容错过啊。 ” 活动介绍 由 AscentStream 谙…

Python 0基础_变现_38岁_day 16(文件操作)

在python&#xff0c;使用内置函数open()进行文件的一些读写操作 文件操作格式&#xff1a;open(文件路径&#xff0c;访问模式&#xff0c;字符编码) 前面两个参数是必备参数&#xff0c;后面的字符编码为选填&#xff0c;但是大多数情况下都会协商字符编码 访问模式 r 只读 w…

数码摄影色彩构成,数码相机色彩管理

一、资料描述 本套摄影色彩资料&#xff0c;大小58.54M&#xff0c;共有6个文件。 二、资料目录 《抽象彩色摄影集》.阿瑟.pdf 《色彩构成》.pdf 《色彩学》.星云.扫描版.pdf 《摄影色彩构成》.pdf 《数码相机色彩管理》.pdf 数码摄影进阶之4《色彩篇》.pdf 三、资料下…

解决IDEA中Tomcat控制台乱码问题(包括sout输出乱码)

文章目录 前言一、控制台直接输出乱码二、sout输出内容在控制台显示乱码 前言 今天在使用Tomcat的时候发现控制台输入出现了乱码问题&#xff0c;其实之前就出现过一次&#xff0c;解决了&#xff0c;但是新创建一个项目后又会出现sout的内容在控制台输出的乱码问题&#xff0…

Windows下Git的使用

目录 一、克隆远程仓库到本地二、git的三板斧2.1 add-将代码添加到本地仓库2.2 commit-提交代码到本地仓库2.3 push-推送本次添加操作到远程仓库2.4 gitee只有三板斧吗&#xff1f; 三、推送后没有出现绿点四、push到远程时报错五、git图形化界面下载链接 一、克隆远程仓库到本…

sql题目练习

cookie注入 解题思路和之前的整数型注入一样&#xff0c;只是比整数型注入多了一步&#xff0c;题目没有给输入框&#xff0c;提示“尝试找找cookie吧”cookie的中文翻译是曲奇&#xff0c;小甜饼的意思。cookie其实就是一些数据信息&#xff0c;类型为“小型文本文件”&#…