SpringMVC实现文件上传与下载、拦截器、异常处理器等功能

网友投稿 251 2022-12-11

SpringMVC实现文件上传与下载、拦截器、异常处理器等功能

目录文件下载文件上传拦截器拦截器的配置多个拦截器的执行顺序异常处理器基于配置的异常处理基于注解的异常处理总结

文件下载

使用ResponseEntity实现下载文件的功能

index.html

点击下载

控制器

@RequestMapping("/testDown")

public ResponseEntity testResponseEntity(HttpSession session) throws IOException {

//获取ServletContext对象

ServletContext servletContext = session.getServletContext();

//获取服务器中文件的真实路径

String realPath = servletContext.getRealPath("/static/img/1.jpg");

//创建输入流

InputStream is = new FileInputStream(realPath);

//创建字节数组

byte[] bytes = new byte[is.available()];

//将流读到字节数组中

is.read(bytes);

//创建HttpHeaders对象设置响应头信息

MultiValueMap headers = new HttpHeaders();

//设置要下载方式以及下载文件的名字

headers.add("Content-Disposition", "attachment;filename=1.jpg");

//设置响应状态码

HttpStatus statusCode = HttpStatus.OK;

//创建ResponseEntity对象

ResponseEntity responseEntity = new ResponseEntity<>(bytes, headers, statusCode);

//关闭输入流

is.close();

return responseEntity;

}

注意:如果报500错误,可能是项目中无法找到静态资源文件,需要对项目重新打包。

文件上传

文件上传要求form表单的请求方式必须为post,并且添加属性enctype="multipart/form-data"以二进制方式上传

SpringMVC中将上传的文件封装到MultipartFile对象中,通过此对象可以获取文件相关信息

上传步骤:

添加依赖

commons-fileupload

commons-fileupload

1.3.1

在SpringMVC的配置文件springMVC.xml中添加配置

index.html

控制器

@RequestMapping("/testUp")

//MultipartFile的形参名必须与index.html中的file标签的name一致

public String testUp(MultipartFile photo, HttpSession session) throws IOException {

//获取上传的文件的文件名

String fileName = photo.getOriginalFilename();

//处理文件重名问题

String hzName = fileName.substring(fileName.lastIndexOf("."));

fileName = UUID.randomUUID().toString() + hzName;

//获取服务器中photo目录的路径

ServletContext servletContext = session.getServletContext();

String photoPath = servletContext.getRealPath("photo");

File file = new File(photoPath);

if(!file.exists()){

file.mkdir();

}

String finalPath = photoPath + File.separator + fileName;

//实现上传功能

photo.transferTo(new File(finalPath));

return "success";

}

拦截器

拦截器的配置

SpringMVC中的拦截器用于拦截控制器方法的执行

SpringMVC中的拦截器需要实现HandlerInterceptor接口

HandlerInterceptor源码

public interface HandlerInterceptor {

default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

return true;

}

default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {

}

default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {

}

}

HandlerInterceptor接口有三个默认方法

preHandle:控制器方法执行之前执行preHandle(),其boolean类型的返回值表示是否拦截或放行,返回true为放行,即调用控制器方法;返回false表示拦截,即不调用控制器方法

postHandle:控制器方法执行之后执行postHandle()

afterCompletion:处理完视图和模型数据,渲染视图完毕之后执行afterCompletion()

控制器

FirstInterceptor.java

public class FirstInterceptor implements HandlerInterceptor {

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

System.out.println("FirstInterceptor-->preHandle");

return false;

}

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

System.out.println("FirstInterceptor-->postHandle");

}

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

System.out.println("FirstInterceptor-->afterCompletion");

}

}

SpringMVC的拦截器必须在SpringMVC的配置文件中进行配置:

方式一

输出:

FirstInterchttp://eptor-->preHandle

方式二

注意提前开启注解扫描,并把拦截器放入Ioc容器

输出:

FirstInterceptor-->preHandle

注意:以上两种配置方式都是对DispatcherServlet所处理的所有的请求进行拦截。

方式三

可以进入首页

发送任意请求都会被拦截

输出:

FirstInterceptor-->preHandle

以上配置方式可以通过ref或bean标签设置拦截器,通过mvc:mapping设置需要拦截的请求,通过mvc:exclude-mapping设置需要排除的请求,即不需要拦截的请求

/**:拦截所有请求

/*:拦截一级目录的请求

多个拦截器的执行顺序

第一个拦截器

@Component

public class FirstInterceptor implements HandlerInterceptor {

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

System.out.println("FirstInterceptor-->preHandle");

return true;

}

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

System.out.println("FirstInterceptor-->postHandle");

}

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

System.out.println("FirstInterceptor-->afterCompletion");

}

}

第二个拦截器

@Component

public class SecondInterceptor implements HandlerInterceptor {

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

System.out.println("SecondInterceptor-->preHandle");

return true;

}

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

System.out.println("SecondInterceptor-->postHandle");

}

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

System.out.println("SecondInterceptor-->afterCompletion");

}

}

两个拦截器都设置为对任意请求放行。

输出:

FirstInterceptor-->preHandle

SecondInterceptor-->preHandle

SecondInterceptor-->postHandle

FirstInterceptor-->postHandle

SecondInterceptor-->afterCompletion

FirstInterceptor-->afterCompletion

若每个拦截器的preHandle()都返回true

此时多个拦截器的执行顺序和拦截器在SpringMVC的配置文件的配置顺序有关:

preHandle()会按照配置的顺序执行,而postHandle()和afterCompletion()会按照配置的反序执行

如果设置第一个拦截器对所有请求放行,第二个拦截器对所有请求拦截。

第一个拦截器

@Component

public class FirstInterceptor implements HandlerInterceptor {

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

System.out.println("FirstInterceptor-->preHandle");

return true;

}

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

System.out.println("FirstInterceptor-->postHandle");

}

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

System.out.println("FirstInterceptor-->afterCompletion");

}

}

第二个拦截器

@Component

public class SecondInterceptor implements HandlerInterceptor {

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

System.out.println("SecondInterceptor-->preHandle");

return false;

}

public void postHandle(HttpServletRequest request, HttpServletResponse response, OzKhuPxbject handler, ModelAndView modelAndView) throws Exception {

System.out.println("SecondInterceptor-->postHandle");

}

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

System.out.println("SecondInterceptor-->afterCompletion");

}

}

输出:

FirstInterceptor-->preHandle

SecondInterceptor-->preHandle

FirstInterceptor-->afterCompletion

若某个拦截器的preHandle()返回了false

preHandle()返回false和它之前的拦截器的preHandle()都会执行,postHandle()都不执行,返回false的拦截器之前的拦截器的afterCompletion()会执行

异常处理器

基于配置的异常处理

SpringMVC提供了一个处理控制器方法执行过程中所出现的异常的接口:HandlerExceptionResolver

HandlerExceptionResolver接口的实现类有:DefaultHandlerExceptionResolver和SimpleMappingExceptionResolver

SpringMVC提供了自定义的异常处理器SimpleMappingExceptionResolver,使用方式:

error

error.html

出现错误

index.html

测试异常处理

基于注解的异常处理

//@ControllerAdvice将当前类标识为异常处理的组件

@ControllerAdvice

public class ExceptionController {

//@ExceptionHandler用于设置所标识方法处理的异常

@ExceptionHandler(value = {ArithmeticException.class,NullPointerException.class})

//ex表示当前请求处理中出现的异常对象

public String handleArithmeticException(Exception ex, Model model){

model.addAttribute("ex", ex);

return "error";

}

}

总结

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java C++实现相同MD5加密算法的方式
下一篇:老生常谈spring的事务传播机制
相关文章

 发表评论

暂时没有评论,来抢沙发吧~