前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringMvc(四)- 下载,上传,拦截器

SpringMvc(四)- 下载,上传,拦截器

作者头像
化羽羽
发布2022-10-28 15:10:22
2910
发布2022-10-28 15:10:22
举报
文章被收录于专栏:化羽学Java

1、图片下载

图片下载:将服务器端的文件以流的形式写到客户端,通过浏览器保存到本地,实现下载;

1.1 图片下载步骤

1.通过session获取上下文对象(session.getServletContext())

​ session.getServletContext()

2.获取 服务器上的图片文件(输入流)

​ InputStream inputStream = servlet.getResourceAsStream("pic/dsgl.jpg");

3.定义缓存数组

​ byte[] bytes = new byte[inputStream.available()];

4.将目标文件读取到缓存数组

​ inputStream.read(bytes);

5.将目标图片文件封装到响应对象 ResponseEntity 中,响应给浏览器

​ 响应头数据:HttpHeaders httpHeaders = new HttpHeaders();

​ 响应码:HttpStatus httpStatus = HttpStatus.OK;

​ 响应的图片数据:return new ResponseEntity<byte[]>(bytes,httpHeaders,httpStatus);

1.2 请求方法

代码语言:javascript
复制
// 图片下载:将服务器端的文件以流的形式写到客户端,通过浏览器保存到本地,实现下载
@RequestMapping("/downloadPic")
public ResponseEntity<byte[]> testDownloadPic(HttpSession session) throws IOException {
    //读取服务器器上的图片文件,读取流对象,必须要借助session获取上下文对象
    InputStream inputStream = session.getServletContext().getResourceAsStream("pic/dsgl.jpg");

    //定义缓存数组,数组大小根据文件大小来定义
    byte[] bytes = new byte[inputStream.available()];

    //将目标文件读取到缓存数组
    inputStream.read(bytes);

    //将目标图片文件封装到响应对象 ResponseEntity 中,响应给浏览器
    //ResponseEntity 响应对象,必须包含三个内容:响应头数据, 响应码(响应状态), 响应的图片数据

    HttpHeaders httpHeaders = new HttpHeaders();

    //响应头数据 attachment 代表附件(才可以下载)
    httpHeaders.add("Content-Disposition","attachment;filename=" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) +
                    ".jpg"); //UUID.randomUUID().toString().substring(0,8)+

    //响应码
    HttpStatus httpStatus = HttpStatus.OK;

    //响应的图片数据
    return new ResponseEntity<byte[]>(bytes,httpHeaders,httpStatus);

}

1.3 jsp

代码语言:javascript
复制
<h2>从服务器下载图片到本地</h2>
<hr/>
<h3>
    <a href="${pageContext.request.contextPath}/downloadPic" >点击下载图片</a>
</h3>

2、图片上传

2.1 图片上传步骤

1.获取上传的头像名称

​ String targetFilename = multipartFile.getOriginalFilename();

2.重新定义新的文件名

​ targetFilename = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + targetFilename.substring(targetFilename.indexOf("."));

3.获取真实上传路径

​ String realFilePath = session.getServletContext().getRealPath("upload");

4.创建文件目录(如果不存在)

​ targetFilePath.mkdirs()

5.创建目标文件对象(用于存放要上传的图片)

​ File targetFile = new File(targetFilePath+"/"+targetFilename);

6.文件上传到服务器,组件自动支持功能

​ multipartFile.transferTo(targetFile);

7.设置回显头像

​ map.put("targetHeadImage",targetFilename);

2.2 jsp

代码语言:javascript
复制
<h2>本地图片上传到服务器</h2>
<hr/>
<!-- 图片上传,必须使用form表单,而且石post方式 -->
<form action="${pageContext.request.contextPath}/uploadPic" method="post" enctype="multipart/form-data">
	<h3>
		选择个人头像:<br/>
		<input type="file" name="uploadHeadImage">
		<input type="submit" value="上传">
	</h3>
</form>
<p>
	上传个人头像:
	<img src="${targetHeadImage}" width="100px">
</p>

2.3 请求方法

代码语言:javascript
复制
//图片上传
//将本地图片上传到服务器
@RequestMapping(value = "/uploadPic",method = RequestMethod.POST)
public String testUploadPic(HttpSession session, @RequestParam("uploadHeadImage") MultipartFile multipartFile, Map<String, String> map) throws IOException {

    //获取上传的头像名称
    String targetFilename = multipartFile.getOriginalFilename();
    System.out.println("------ 上传文件名"+targetFilename+" ------");

    //重新定义新的文件名,要保留上传文件的类型
    targetFilename = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + targetFilename.substring(targetFilename.indexOf("."));

    System.out.println("------ 新的文件名"+targetFilename+" ------");

    //上传文件,要保存服务器上的真实路径中,idea项目发布,默认不会放到目标tomcat中,
    String realFilePath = session.getServletContext().getRealPath("upload");

    System.out.println("------ 服务器真实路径"+realFilePath+" ------");

    //文件目录可能不存在,也不能人为干预,必须程序主动处理
    File targetFilePath = new File(realFilePath);

    if(!targetFilePath.exists()){
        //目标不存在,主动创建
        if(targetFilePath.mkdirs()){
            System.out.println("上传目录创建成功");
        }
    }

    //**创建目标文件对象
    File targetFile = new File(targetFilePath+"/"+targetFilename);

    //文件上传到服务器,只需要一步,组件自动支持功能
    multipartFile.transferTo(targetFile);

    //设置回显头像
    map.put("targetHeadImage",targetFilename);

    return "forward:hellopic.jsp";
}

2.4 配置文件 和 jars

2.4.1 配置文件
代码语言:javascript
复制
<!-- 配置支持文件上传的组件,可插拔,配置才可使用 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 指定文件上传的字符集,要跟jsp页面字符集一致 -->
    <property name="defaultEncoding" value="utf-8"></property>
    <property name="maxInMemorySize" value="10485678"></property>
</bean>

<!-- 配置服务器的静态资源的映射目录,自动根据指定的目录(真实文件路径),按照文件名查找文件 -->
<mvc:resources mapping="/*.jpg" location="file:///D:/KEGONGCHANG/DaiMa/IDEA/KH96/SpringMVC/SpringMVC/springmvc-04/target/springmvc-04/upload/"></mvc:resources>
2.4.2 jars
代码语言:javascript
复制
 <!-- 文件上传 -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

3、拦截器

拦截器,必须实现 HandlerInterceptor 接口

3.1 实现三个方法

3.1.1 preHandle
  • 执行时机:调用目标请求处理器中的目标请求处理方法前,执行此方法;
  • 调用处:在前端核心控制器的962行,不同spring版本不一样;
  • 执行次序:从第一个拦截器,依次往后执行所有拦截器的此方法,只要有一个拦截器返回false,一组请求就都过不去;
  • 返回值:
    • false:代表不可以调用请求目标处理方法,即需要拦截请求;
    • true:代表可以调用请求目标处理方法,即不需要拦截请求;
3.1.2 postHandle
  • 执行时机:在调用目标请求处理器中的目标请求处理方法后,在模型数据渲染之前,执行此方法;
  • 调用处:在前端核心控制器的974行,不同spring版本不一样;
  • 执行次序:从最后一个拦截器,依次往前执行所有拦截器的此方法;
3.1.3 afterCompletion
  • 执行时机:
    • 正常情况:
      • 没有拦截请求,也没有发生异常,在调用目标请求处理器中的目标请求处理方法后,在模型数据渲染之后(获取,渲染,转发或者重定向等),执行此方法;
      • 调用处:在前端核心控制器的1059行,不同spring版本不一样,
      • 执行次序:从最后一个拦截器,依次往前执行所有拦截器的此方法
    • 异常情况:
      • 多个拦截器中,其中一个拦截了请求(preHandle方法返回了false),此方法被调用,且是从当前拦截器前一个拦截器开始倒序执行(第一个拦截器拦截除外);
      • 在前端核心处理器,处理请求过程中发生了异常,此方法也会被调用,原理和上面类似;
  • 小结:所有通过的拦截器,都会执行此方法,释放资源,拦截请求的当前拦截器是不会执行此方法(包括其后的所有拦截器);

3.2 测试 (一个拦截器)

代码语言:javascript
复制
@Controller //将拦截器作为普通组件,不可以直接生效,必须将容器,加入到拦截器组中
public class FirstInterceptor implements HandlerInterceptor  {

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        
        System.out.println(" ------ FirstInterceptor  preHandle ------");
        
        return false; //返回false
		//return true; //返回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 ------");

    }
}

配置文件

代码语言:javascript
复制
<!-- 添加自定义拦截器 到 拦截器组 -->
<mvc:interceptors>
    <ref bean="firstInterceptor"></ref>
</mvc:interceptors>

请求方法

代码语言:javascript
复制
@RequestMapping("/testFirstInterceptor")
public String testSpringMvcInterceptor(){
    System.out.println(" ------ 测试SprigMvc的拦截器的目标处理方法1------ ");
    return "forward:index.jsp";
}
3.2.1 返回 false

只执行 perHandle方法,不执行 目标请求处理器中的目标请求处理方法

3.2.2 返回 true

执行 preHandle -> 执行目标请求处理器中的目标请求处理方法 -> postHandle -> afterCompletion

3.3 测试(两个拦截器)

3.3.1 都返回true

第二个拦截器

代码语言:javascript
复制
@Controller 
public class SecondInterceptor implements HandlerInterceptor
{

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println(" ------ SecondInterceptor  preHandle ------");

       // return false;
        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 ------");

    }
}

配置文件

代码语言:javascript
复制
<!-- 添加自定义拦截器 到 拦截器组 -->
<mvc:interceptors>
    <ref bean="firstInterceptor"></ref>
    <ref bean="secondInterceptor"></ref>
</mvc:interceptors>

请求方法

代码语言:javascript
复制
@RequestMapping("/testSecondInterceptor")
public String testSecondInterceptor(){
    System.out.println(" ------ 测试SprigMvc的拦截器的目标处理方法2------ ");
    return "forward:index.jsp";
}
3.3.1 两个都返回true
3.3.2 第一个 返回true,第二个返回false
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-09-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、图片下载
    • 1.1 图片下载步骤
      • 1.2 请求方法
        • 1.3 jsp
        • 2、图片上传
          • 2.1 图片上传步骤
            • 2.2 jsp
              • 2.3 请求方法
                • 2.4 配置文件 和 jars
                  • 2.4.1 配置文件
                  • 2.4.2 jars
              • 3、拦截器
                • 3.1 实现三个方法
                  • 3.1.1 preHandle
                  • 3.1.2 postHandle
                  • 3.1.3 afterCompletion
                • 3.2 测试 (一个拦截器)
                  • 3.2.1 返回 false
                  • 3.2.2 返回 true
                • 3.3 测试(两个拦截器)
                  • 3.3.1 都返回true
                  • 3.3.1 两个都返回true
                  • 3.3.2 第一个 返回true,第二个返回false
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档