JAVAEE框架技术之6-springMVC拦截器和文件上传功能

简介: JAVAEE框架技术之6-springMVC拦截器和文件上传功能

文件上传下载

文件上传

文件上传是项目开发中最常见的功能之一 ,springMVC 可以很好的支持文件上传,但是SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用Spring的文件上传功能,则需要在上下文中配置MultipartResolver。

文件上传三要素

  • 表单的提交方式 method=“POST”
  • 表单的enctype属性是多部分表单形式 enctype=“multipart/form-data"
  • 表单项(元素)type=“file”

页面准备

<h2>上传页面</h2>
<form action="/upload" enctype="multipart/form-data" method="post">  
    用户:<input type="text" name="username"> <br/>  
    上传:<input type="file" name="file"/><br/>  
    <input type="submit" value="上传">
</form>

添加依赖

Spring MVC使用Apache Commons FileUpload技术实现了一个MultipartResolver实现类,因此,SpringMVC的文件上传还需要依赖Apache Commons FileUpload的组件。

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

文件上传解析器

springmvc-config.xml的配置文件中

<!-- 定义文件上传解析器 -->
    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 设定默认编码 -->
        <property name="defaultEncoding" value="UTF-8"/>
        <!-- 设定文件上传的最大值5MB,5*1024*1024 ,指的是所有文件的总和 -->
        <property name="maxUploadSize" value="5242880"/>
    </bean>

controller实现

@Controller
@RequestMapping("test")
public class TestController {
    @RequestMapping("show8")
    public String upload(@RequestParam("file") MultipartFile multipartFile,HttpServletRequest request) throws IOException {
        String fileName = multipartFile.getOriginalFilename(); // 获取文件的名称
        String path = request.getServletContext().getRealPath("/upload"); // 获取真实路径
        File file = new File(path); // 将path封装为File对象
        if (!file.exists()) {
            file.mkdir();
        }
        multipartFile.transferTo(new File(file,fileName));//上传
        System.out.println(path);
        return "forward:/success.html";
    }
}

文件下载

工具类

package cn.yanqi.utils;
import java.io.*;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletResponse;
public class DownLoadUtils {
  public static void downLoadMyFile(File file, HttpServletResponse response) {
    try {
      if (file.exists()) {
        // 获取下载文件名
        String filename = file.getName();
        // 1: 设置下载的响应头
        response.setHeader("Content-Disposition",
            "attachment;fileName="+ URLEncoder.encode(filename, "UTF-8"));
        //2、 读取文件--输入流
        InputStream input=new FileInputStream(file);
        //3、 写出文件--输出流
        OutputStream out = response.getOutputStream();
        byte[] buff =new byte[1024];
        int index=0;
        //4、执行 写出操作
        while((index= input.read(buff))!= -1){
          out.write(buff, 0, index);
          out.flush();
        }
        out.close();
        input.close();
      } else {
        throw new RuntimeException("文件不存在....");
      }
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

代码实现

@Controller
@RequestMapping("test")
public class TestController {
    @RequestMapping("dowloadFile")
    @ResponseStatus(HttpStatus.OK)
    public void dowload(HttpServletRequest request, HttpServletResponse response){
        //获取文件的真实路径
        String realPath =  request.getServletContext().getRealPath("/upload/一燕.jpg");
        File file = new File(realPath);//下载文件路径
        // 工具类
        DownLoadUtils.downLoadMyFile(file,response);
    }
 }   

SpringMVC拦截器

概述

SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。

preHandle 执行目标方法之前进行拦截; true 放行 false 拦截不放行
postHandle 在目标方法执行之后,进行增强
afterCompletion 在视图渲染完毕后,进行资源释放

拦截器实现

自定义拦截器

使用自定义拦截器,SpringMVC提供了 HandlerInterceptor 接口。我们重写 preHandlepostHandleafterCompletion 这三个方法!

/**
 * @Auther: yanqi
 * @Desc 自定义拦截器
 */
public class MyInterceptor implements HandlerInterceptor {
    //执行目标方法之前进行拦截  true 放行  false 拦截不放行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("执行目标方法之前进行拦截");
        //放行
        return true;
    }
  //目标方法执行之后,进行增强
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("目标方法执行之后,进行增强");
    }
  //在视图渲染完毕后,进行资源释放
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("在视图渲染完毕后,进行资源释放");
    }
}

配置拦截器

  • springmvc-servlet.xml
<!--拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--/** 所有controller请求都会进入拦截器-->
            <mvc:mapping path="/**"/>
            <!--指定拦截器-->
            <bean class="cn.yanqi.controller.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

指定和排除拦截

<!--指定拦截-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--指定拦截,写什么路径拦截什么路径-->
            <mvc:mapping path="/UserController/show1.do"/>
            <!--指定拦截器-->
            <bean class="cn.yanqi.controller.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
<!--排除拦截-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--所有controller请求都会进入拦截器-->
            <mvc:mapping path="/**"/>
            <!--拦截所有,排除拦截-->
            <mvc:exclude-mapping path="/hello2/show1.do"/>
            <mvc:exclude-mapping path="/hello2/show2.do"/>
            <!--指定拦截器-->
            <bean class="cn.yanqi.controller.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
  • 访问测试

注意事项

只拦截controller请求

在拦截器链实现过程中,如果第一个拦截器中的preHandle的返回值是false,第二个拦截器将不会执行!

拦截器链

什么是拦截器链

多个拦截器,拦截同一个目标资源,形成一个链条,就是拦截器链!

拦截器链执行顺序

  • 拦截方法的执行顺序

先进后出

  • 拦截器的执行顺序

跟springmvc配置文件中的配置顺序有关系

mvc:interceptor 谁先配置谁先执行!

拦截器链实现

<!--配置拦截-->
    <mvc:interceptors>
        <!--第一个拦截器-->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="cn.yanqi.Interceptor.MyInterceptor1"/>
        </mvc:interceptor>
        <!--第二个拦截器-->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="cn.yanqi.Interceptor.MyInterceptor2"/>
        </mvc:interceptor>
    </mvc:interceptors>

过滤器与拦截器的区别

/**
 * @Desc  Filter过滤器:
 *              1、实现Filter接口
 *              2、通过web.xml或注解方式完成配置
 *              3、重写的方法 init  doFilter   destroy
 *              4、过滤器过滤的是所有请求,不分controller和页面
 */
public class MyFilter implements Filter {}
/**
 * @Desc Interceptor拦截器
 *                  1、实现HandlerInterceptor接口
 *                  2、需要在springmvc核心配置文件中配置
 *                  3、重写的方法
 *                          preHandle  调用handler方法之前执行,true表示放行,false表示不放行
 *                          postHandle  调用handler方法之后执行
 *                          afterCompletion  视图渲染之后执行
 *                  4、只拦截controller请求        
 */
public class MyInterceptor implements HandlerInterceptor {}

RestFul

什么是RESTfull

REST(英文:Representational State Transfer,简称REST,意思:表述性状态转换,描述了一个架构样式的网络系统,比如web应用)。

Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

  • 应用场景

应用场景:前后端分离开发的架构中

RESTfull与传统URL对比

传统URL

前端 后台 描述
http://localhost:8080/user/findAllUsers @RequestMapping(/user/findAllUsers)
public List findAllUsers()
查询所有用户
http://localhost:8080/user/findUserById?id=1 @RequestMapping(/user/findUserById)
public User findUserById(int id)
查询指定用户
http://localhost:8080/user/addUser @RequestMapping(/user/addUser)
public void addUser(User user)
添加用户
http://localhost:8080/user/updateUser @RequestMapping(/user/updateUser)
public void updateUser(User user)
修改用户
http://localhost:8080/user/deleteUserById?id=1 @RequestMapping(/user/deleteUserById)
public User deleteUserById(int id)
删除用户

RESTfull风格

Restful风格的请求是使用==“url+请求方式”(名饲+动词)==表示一次请求目的的,HTTP 协议里面四个表示操作方式的动词如下:

请求方式 描述
GET 用于获取资源
POST 用于新建资源
PUT 用于更新资源
DELETE 用于删除资源
  • RESTfull风格请求的格式
前端 后台 描述
http://localhost:8080/user/ @RequestMapping(/user,method=GET)
public List findAllUsers()
GET查询所有用户
http://localhost:8080/user/1 @RequestMapping(/user/{id},method=GET)
public User findUserById(@PathVariable int id)
GET查询id为1用户
http://localhost:8080/user/ @RequestMapping(/user,method=POST)
public void addUser(User user)
POST添加用户
http://localhost:8080/user/1 @RequestMapping(/user/{id},method=PUT)
public void updateUser(@PathVariable int id)
PUT修改id为1用户
http://localhost:8080/user/1 @RequestMapping(/user/{id},method=DELETE)
public User deleteUserById(@PathVariable int id)
DELETE删除id为1的用户

上述url地址/user/1中的1就是要获得的请求参数,在SpringMVC中可以使用占位符进行参数绑定。RequestMapping中/user/1可以写成/user/{id},占位符{id}对应的就是1的值。在业务方法中我们可以使用@PathVariable注解进行占位符的匹配获取工作。

@Controller
@ResponseBody
public class RestfullController {
    @GetMapping("/users")
    public String findAll() {
        return "findAll";
    }
    @GetMapping("/users/{id}")
    public String findUserById(@PathVariable Integer id) {
        return "findUserById:"+id;
    }
    @PostMapping("/users")
    public String addUser() {
        return "addUser";
    }
    // @RequestMapping(value = "/users/{id}",method = RequestMethod.PUT)
    @PutMapping("/users/{id}")
    public String updateUser(@PathVariable Integer id) {
        return "updateUser:" + id;
    }
    // @RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
    @DeleteMapping("/users/{id}")
    public String deleteUser(@PathVariable Integer id) {
        return "deleteUser:" + id;
    }
}

测试Restfull请求

浏览器默认只能发送:get、post请求,put delete请求是没办法测试的。我们需要借助于一个工具postman来模拟发送 GET POST PUT DELETE请求。

postman接口测试


目录
相关文章
|
3月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
2月前
|
前端开发 安全 Java
技术进阶:使用Spring MVC构建适应未来的响应式Web应用
【9月更文挑战第2天】随着移动设备的普及,响应式设计至关重要。Spring MVC作为强大的Java Web框架,助力开发者创建适应多屏的应用。本文推荐使用Thymeleaf整合视图,通过简洁的HTML代码提高前端灵活性;采用`@ResponseBody`与`Callable`实现异步处理,优化应用响应速度;运用`@ControllerAdvice`统一异常管理,保持代码整洁;借助Jackson简化JSON处理;利用Spring Security增强安全性;并强调测试的重要性。遵循这些实践,将大幅提升开发效率和应用质量。
66 7
|
4月前
|
XML 前端开发 Java
深入理解SpringMVC工作原理,像大牛一样手写SpringMVC框架
对于SpringMVC相信诸位并不陌生,这是Java开发过程中使用最频繁的框架,在你的项目中可能不一定用MyBatis,但绝对会使用SpringMVC,因为操作数据库还有Hibernate、JPA等其他ORM框架选择,但SpringMVC这个框架在其领域中,可谓是独领风骚
|
5月前
|
前端开发 Java 应用服务中间件
Spring框架第六章(SpringMVC概括及基于JDK21与Tomcat10创建SpringMVC程序)
Spring框架第六章(SpringMVC概括及基于JDK21与Tomcat10创建SpringMVC程序)
|
5月前
|
缓存 NoSQL Java
在 SSM 架构(Spring + SpringMVC + MyBatis)中,可以通过 Spring 的注解式缓存来实现 Redis 缓存功能
【6月更文挑战第18天】在SSM(Spring+SpringMVC+MyBatis)中集成Redis缓存,涉及以下步骤:添加Spring Boot的`spring-boot-starter-data-redis`依赖;配置Redis连接池(如JedisPoolConfig)和连接工厂;在Service层使用`@Cacheable`注解标记缓存方法,指定缓存名和键生成策略;最后,在主配置类启用缓存注解。通过这些步骤,可以利用Spring的注解实现Redis缓存。
79 2
序-Servlet和SpringMVC的联系和区别-配置路径先想好使用的使用的方法,然后匹配的需要的技术
序-Servlet和SpringMVC的联系和区别-配置路径先想好使用的使用的方法,然后匹配的需要的技术
|
5月前
|
JSON Java 数据库
技术笔记:SpringMVC常用注解
技术笔记:SpringMVC常用注解
|
5月前
|
XML 前端开发 Java
SpringMVC的架构有什么优势?——异常处理与文件上传(五)
SpringMVC的架构有什么优势?——异常处理与文件上传(五)
|
6月前
SpringMVC拦截器的介绍,拦截器的基本实现,拦截器链配置
SpringMVC拦截器的介绍,拦截器的基本实现,拦截器链配置
60 2
|
5月前
|
前端开发 Java Maven
如何在Spring MVC中实现图片的上传和下载功能
如何在Spring MVC中实现图片的上传和下载功能