3. SpringBoot中文件下载

将可以被下载资源放在磁盘的 D:\springbootcodes\springboot_day6\download 路径

这里我们使用jsp开发

引入依赖使tomcat可以解析jsp,设置SpringBoot可以访问jsp资源

<!--使tomcat可以解析jsp-->
<dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId>
</dependency>

用到的包结构

开发jsp下载页面

<%@ page pageEncoding="UTF-8" contentType="text/html; UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><h1>测试文件下载</h1><a href="${pageContext.request.contextPath}/file/download?fileName=HELP.md">HELP.md</a><a href="${pageContext.request.contextPath}/file/download?fileName=readme.txt">readme.txt</a><a href="${pageContext.request.contextPath}/file/download?fileName=项目介绍.md">项目介绍.md</a>
</body>
</html>

application.yml配置文件

server:port: 8989servlet:context-path: /springboot_day6jsp:init-parameters:development: true # 打开jsp开发模式# 配置jsp模板视图
spring:mvc:view:prefix: /suffix: .jspfile:download:dir: D:\springbootcodes\springboot_day6\download  # 指定下载目录,测试环境# dir: /home/download  生产环境# 调整日志的级别
logging:level:root: infocom.baizhi: debug

开发Controller中的下载方法

一个请求对应一个响应,响应文件对应一个响应,如果最后跳转的话跳转也对应一个响应,因为我们必须响应文件,所以后端的下载方法不跳转,即没有返回值,返回为void。

package com.baizhi.controller;import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URLEncoder;@Controller
@RequestMapping("file")
public class FileController {private static final Logger log = LoggerFactory.getLogger(FileController.class);@Value("${file.download.dir}")private String realName;/*** 测试文件下载* @param fileName*/@RequestMapping("download")public void download(String fileName, HttpServletResponse response) throws IOException {log.debug("当前下载文件名为: " + fileName);log.debug("当前下载文件目录: " + realName);// 1. 去指定目录中读取文件File file = new File(realName, fileName);// 2. 将文件读取为文件输入流FileInputStream is = new FileInputStream(file);// 2.5 获取响应流之前,一定要设置以附件形式下载 attachment 附件 inline 在线打开(默认值),在之后加上设置的文件名字// 这里fileName大小写无所谓,因为文件名可能有中文,所以我们要进行编码response.setHeader("content-disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));// 3. 获取响应输出流ServletOutputStream os = response.getOutputStream();// 4. 输入流复制给输出流IOUtils.copy(is, os);// 5. 释放资源IOUtils.closeQuietly(is);IOUtils.closeQuietly(os);// 最后补充:FileCopyUtils.copy(is, os)既可以将输入流复制给输出流,还可以在复制之后关闭资源,可以替代上面的4,5步}
}

4. SpringBoot中拦截器

SpringBoot集成了了Spring和SpringMVC的优势,SpringBoot沿用了SpringMVC中的拦截器,几乎没有做什么修改,只是在配置拦截器不同。自定义拦截器需要实现系统定义的HandlerInterceptor接口,在SpringMVC中实现HandlerInterceptor接口需要重写preHandle、postHandle、afterCompletion三个方法,而SpringBoot对于HandlerInterceptor默认实现,不是所有的项目三个方法都需要用到,基于自己的业务去选择,这三个方法都是用户可选实现,我们甚至可以不实现里面的任何一种方法,因为它们在接口里都有默认实现,默认什么都不做。

关于自定义拦截器中三个方法的参数细节以及三个方法和controller方法的执行顺序建议阅读我之前总结的SpringMVC中的拦截器,和SpringBoot中拦截器的定义几乎是一样的,只是在配置时不同。

接下来我们来开发一个拦截器

这次我们仍然需要使用jsp,所以我们需要导入相关依赖并设置SpringBoot可以访问jsp资源

引入依赖使tomcat可以解析jsp,设置SpringBoot可以访问jsp资源

<!--使tomcat可以解析jsp-->
<dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId>
</dependency>

需要用到的包结构

开发拦截器

自定义拦截器需要实现HandlerInterceptor接口,实现里面的preHandle、postHandle、afterCompletion方法,不过SpringBoot已经帮我们默认实现了,默认实现为空,我们可以根据我们的需要去实现我们需要的方法,甚至三个方法都不实现。三个方法和controller中方法执行顺序为:

preHandle --> controller中方法 --> postHandle --> afterCompletion方法

只有preHandle 方法返回true放行才会去执行之后的controller中的方法,当访问失败postHandle 不会执行,但是无论如何afterCompletion方法一定会执行,它相当于finally{}代码块

拦截器需要专门放在interceptors包里,这个包是专门用来存放拦截器的

/*** 自定义拦截器1*/
public class MyInterceptor1 implements HandlerInterceptor {private static final Logger log = LoggerFactory.getLogger(MyInterceptor1.class);//preHanle 最先执行//参数3: handler 当前请求的控制器方法对象@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.debug("============1==============");//response.sendRedirect(request.getContextPath() + "/403.jsp");return true; // 放行  false  中断}//参数3: handler 当前请求的控制器方法对象//参数4: modelAndView 模型和视图 当前请求访问方法的modeandview对象//正确的时候才会执行这个方法,错误的时候不会执行@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.debug("============2==============");//log.debug("view: {}", modelAndView.getViewName());}//参数3: handler 当前请求的控制器方法对象//参数4: ex 如果控制器出现异常时的异常对象//这个方法: 相当于finally{}代码块  总是执行  无论请求正确,出现异常@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {log.debug("============3==============");}
}

开发controller

@Controller
@RequestMapping("demo")
public class DemoController {private static final Logger log = LoggerFactory.getLogger(DemoController.class);@RequestMapping("demo")public String demo(){log.debug("demo ok!!!");return "demo";  // 底层会封装成ModelAndView}
}

配置拦截器

配置拦截器的类需要专门放在config包里,config包是专门用来存放配置类的

@Configuration
public class MvcConfig implements WebMvcConfigurer {/*** 配置拦截器相关方法* @param registry*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 配置拦截器1registry.addInterceptor(new MyInterceptor1())   // 指定拦截器.addPathPatterns("/**") //拦截所有controller请求 // .addPathPatterns("/login", "/user")只拦截login和user.excludePathPatterns("/file/**")  // 排除哪些路径.order(1); //指定拦截器的执行顺序,int 类型.默认按照自然排序(从小到大)的顺序执行,数字相同按照从上往下执行}
}

测试

最后补充的是如果有多个拦截器那么多个拦截器之间的执行顺序是什么?

多个拦截器的执行顺序

我们创建两个拦截器MyInteceptor1、MyInterceptor2,

在配置类里面配置一下拦截器

测试

5. SpringBoot中war包部署

SpringBoot部署方式有两种,一种是war,一种是jar,我们先来学习如何部署war

  1. 指定部署方式为war
  2. 去除SpringBoot内嵌的tomcat
  3. 在插件中指定入口类
  4. 配置入口类
  5. 打包
  6. 测试

  1. 指定部署方式为war

SpringBoot在部署的时候默认部署为jar包部署,所以我们需要设置部署方式为war,怎么设置呢,在配置文件加上下面这句话,这个方法写在项目名的下面

<packaging>war</packaging>

  1. 去除SpringBoot内嵌的tomcat

项目内嵌服务器,外部又有一个服务器,就会有问题,所以要把内嵌的tomcat依赖删除掉,这样就没有内嵌的tomcat了,只有外部一个容器,就能正常运行了。在删除依赖时,我们不仅要删除内嵌的tomcat依赖,如果我们还引入了解析jsp的依赖,我们也要删除掉,因为外部的tomcat默认可以解析jsp

虽然spring-boot-starter-web已经引入了tomcat依赖,但是我们还引入tomcat依赖并设置scope为provide表示只有当前环境可用,打包时内嵌的tomcat不参与打包

<!---使得内嵌的tomcat-不参与打包-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><!--provided当前idea环境可用,打包不参与打包--><scope>provided</scope>
</dependency>

如果我们还引入了解析jsp的依赖我们也要去除,因为外部的tomcat默认可以解析jsp,我们只需要在jsp依赖里加上provided就可以使解析jsp的依赖在打包时不参与打包

注意:一旦我们不使用内部的tomcat,则application.yml中的项目名端口号会失效,使用外部tomcat默认项目名为war包的名字(无.war后缀),端口号默认为8080

  1. 在插件中指定入口类

把内嵌的tomcat排除,用外部的tomcat 启动,外部的tomcat和SpringBoot没有一点关系,所以需要明确告诉外部的tomcat在启动的时候要执行项目中的哪个入口类去启动,在插件中配置入口类,修改插件,在pom.xml依赖中的插件中加入下面这句话就可以指定入口类

<!--配置springboot的入口类-->
<configuration><fork>true</fork><!--增加jvm参数--><jvmArguments>-Dfile.encoding=UTF-8</jvmArguments><!--指定入口类--><!--根据自己项目情况设定--><mainClass>com.baizhi.SpringbootDay6Application</mainClass>
</configuration>

  1. 配置入口类

我们需要让外部服务器找到入口类的时候明确的在入口类里面告诉它现在用的不是内嵌的服务器了,用的是外部的服务器,让入口类继承SpringBootServletInitializer,SpringBootServletInitializer的作用就是指定不再使用内嵌的服务器,而是使用外部tomcat容器启动,还需要覆盖SpringBootServletInitializer中的configure方法。

// SpringBootServletInitializer: 不再使用内嵌的服务器启动,而是使用外部的tomcat容器(服务器)启动
@SpringBootApplication
public class SpringbootDay6Application extends SpringBootServletInitializer {public static void main(String[] args) {SpringApplication.run(SpringbootDay6Application.class, args);}// 明确再配置一遍当前的入口类是谁@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {return builder.sources(SpringbootDay6Application.class); // 把入口类的class传进去}
}

  1. 打包

注:打包时打包的是springboot_day6,而不是springboot_day5,下图演示错了

我们将打包成的war包名字修改为springboot

  1. 测试

将war包复制到tomcat里的webapps包里

双击tomcat中bin包下的start.bat运行Tomcat

访问

6. SpringBoot中Jar包部署

  1. 设置打包方式为jar

在pom.xml中设置打包方式为jar,不过不设置也可以,默认就是jar包方式部署

<!--指定jar包部署-->
<packaging>jar</packaging>
  1. 执行打包

  1. 启动jar包

  1. 注意事项

在使用jar包部署时如果访问的是jsp,需要设置插件为1.4.2版本

<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><!--打包jsp模板时,必须使用1.4.2插件--><version>1.4.2.RELEASE</version>
</plugin>

还需要指定jsp文件打包位置,把项目中的哪个jsp打到jar包的哪个目录

<!--指定jsp文件打包位置-->
<resources><!-- 打包时将jsp文件拷贝到META-INF目录下--><resource><!-- 指定resources插件处理哪个目录下的资源文件 --><directory>src/main/webapp</directory><!--指定必须要放在此目录下才能被访问到--><targetPath>META-INF/resources</targetPath><includes><include>**/**</include></includes></resource><resource><directory>src/main/resources</directory><includes><include>**/**</include></includes><filtering>false</filtering></resource>
</resources>

SpringBoot中文件下载、拦截器、war包部署、jar包部署相关推荐

  1. SpringBoot中配置拦截器时,跨域失效

    SpringBoot中配置拦截器时,跨域失效 前后段分离的项目,配置了跨域后,访问正常,但是配置了拦截器以后,有的访问正常,有的出现跨域问题,发现出现跨域问题的都是拦截器里面没有放行的请求. @Con ...

  2. SpringBoot中自定义拦截器

    场景 自定义拦截器,通过继承WebMvcConfigureAdapter然后重写父类中的方法进行扩展. 项目搭建专栏: https://blog.csdn.net/BADAO_LIUMANG_QIZH ...

  3. springboot中的拦截器interceptor和过滤器filter,多次获取request参数

    大家好,我是烤鸭:     这是一篇关于springboot的拦截器(interceptor)和过滤器(Filter). 先说一下过滤器和拦截器. 区别: 1. servlet请求,顺序:Filter ...

  4. SpringBoot中使用拦截器、servlet、过滤器Filter

    Spring Boot 使用拦截器步骤: 1. 创建类实现 HandlerInterceptor 接口 package com.dongmu.interceptor;import org.spring ...

  5. 【springboot中使用拦截器】

    1.拦截器原理 1.定义拦截器: 2.配置拦截器 3.解决静态资源被拦截 2.拦截器使用实例 2.1判断用户有没有登录 2.2取消拦截操作 1.拦截器原理 拦截器的原理很简单,是AOP 的一种实现,专 ...

  6. 如何快速在 Springboot 中集成拦截器? | 原力计划

    作者 | 才疏学浅 责编 | 夕颜 出品 | CSDN(ID:CSDNnews) 话不多说,直接上货! 拦截器的作用 拦截器提供了一种机制,在访问action前后进行一些操作,因为拦截器的这个特性,那 ...

  7. spring mvc中的拦截器

    本文说下spring MVC中的拦截器 文章目录 拦截器介绍 拦截器注入适配器 自定义拦截器 controller测试 测试结果 本文小结 拦截器介绍 拦截器是在servlet执行之前执行的程序(这里 ...

  8. SpringBoot之Interceptor拦截器注入使用

    相关文章: SpringBoot 之AOP切面的使用 SpringBoot之Listener注册到Spring容器中的多种方法 SpringBoot之Filter过滤器的实现及排序问题 SpringB ...

  9. Linux中把文件夹打成war包,SpringBoot中maven项目打成war包部署在liunx服务器上的方法...

    说明:Spring Boot由于内嵌了如Tomcat,Jetty和Undertow这样的容器,也就是说可以直接跑起来,用不着再像Spring项目还需要外置的Tomcat等容器来进行部署工作了,通过启动 ...

最新文章

  1. HarmonyOS UI开发 DirectionalLayout(定向布局) 的使用
  2. 开源 免费 java CMS - FreeCMS1.5 标签 guestbookPage
  3. 超全 Python IDE 武器库大总结,优缺点一目了然!
  4. 数据集标注工具_如何提高数据标注质量,提供精细化标注数据集?丨曼孚科技...
  5. 2018-2019-1 20165203 《信息安全系统设计基础》第六周学习总结
  6. 发票管理软件_企业为什么需要ERP企业管理软件?
  7. C++编程技术常见问题有哪些?
  8. 使用Crash工具查看一个TCP listen sock内存布局实例
  9. 重置物体的position, rotation, scale,复制物体的组件
  10. 一、应广单片机的Mini-C语言基础
  11. IIS express 配置和500.22错误解决详解
  12. C语言源程序作业完成系统,C语言源程序的自动评判系统
  13. MSRA院长周礼栋升任微软全球资深副总裁,20年前加入微软,毕业于复旦
  14. 楼道扶手智能清洁装置的制作分享
  15. jquery.qrcode 批量打印
  16. CodeLab:Android fundamentals 04.2:Input controls
  17. Leetcode 704.二分查找 27.移除元素 代码随想录day1
  18. 测试液晶显示器的软件,tLCDtest(液晶屏幕测试软件)
  19. halocn标定找旋转中心_一种利用旋转中心进行手眼标定的原理性介绍
  20. 陌生人社交的一路羁绊——垃圾用户

热门文章

  1. 我们来了解下ModelAndViewContainer组件---------------【springmvc源码】
  2. c语言八字节,C语言相关
  3. Mike 2014 安装驱动错误
  4. r96950hs和r76850hs哪个好
  5. c# 计算空格宽度像素_黄聪:C#如何通过MeasureString、Graphics获取字符串的像素长度...
  6. linux jq 遍历数组,jquery 遍历数组 each 方法详解
  7. Ubuntu一些实用软件安装
  8. html编辑器自定义脚本,ckeditor自定义插件使用方法详解
  9. 从浅到深使用pm2来彻底掌握微服务运维精髓
  10. 【设计杂志的软件】名编辑电子杂志大师教程 | 添加本地视频