• 先创建根应用上下文配置,WebDemo/src/main/java/com/seliote/webdemo/config/RootContextConfig.java
package com.seliote.webdemo.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller; // 配置类必须标注 @Configuration 注解
@Configuration
// 设置注解扫描,默认扫描所有标注了 @Component 的类(@Component 标注的标注也算),都将变为 Spring 管理的 bean(自动实例化与注入依赖)
@ComponentScan(
// 注解扫描的起始包
basePackages = "com.seliote.webdemo",
// 排除对标注了 @Configuration 与 @Controller 类的实例化
excludeFilters = @ComponentScan.Filter({Configuration.class, Controller.class})
)
public class RootContextConfig {
}
  • 创建 Servlet 上下文配置,注意其中注册了一个 MultipartResolver 用于 Servlet 3.0- 的文件下载,WebDemo/src/main/java/com/seliote/webdemo/config/ServletContextConfig.java
package com.seliote.webdemo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc; @Configuration
// 激活注解驱动的控制器请求映射
@EnableWebMvc
@ComponentScan(
basePackages = "com.seliote.webdemo",
// 忽略默认扫描模式
useDefaultFilters = false,
// 仅对标注了 @Controller 的类进行扫描
includeFilters = @ComponentScan.Filter(Controller.class)
)
public class ServletContextConfig { // 启用文件上传,如果不是 Servlet 3.0+ 就使用第三方工具
@Bean
public MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
}
  • 编写启动项,注意其中注册 DispatcherServlet 时所调用的 dynamic.setMultipartConfig(new MultipartConfigElement(...)) 方法用于开启文件上传,WebDemo/src/main/java/com/seliote/webdemo/config/Bootstrap.java
package com.seliote.webdemo.config;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet; import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration; // ServletContainerInitializer 接口的实现将在应用程序启动时(所有监听器启动之前)调用 onStartup() 方法(应用可用的最早时间点),
// 但是直接实现 ServletContainerInitializer 过于麻烦,所以提供了一个 SpringServletContainerInitializer 桥接口,
// 它会在应用程序启动时扫描应用中所有 WebApplicationInitializer 接口的实现并调用其 onStartup() 方法
public class Bootstrap implements WebApplicationInitializer {
public void onStartup(ServletContext aServletContext) throws ServletException {
// 允许 Servlet 容器提供静态文件
aServletContext.getServletRegistration("default").addMapping("/resource/*"); // 配置根应用上下文
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(RootContextConfig.class);
// 通过监听器启动根上下文(ContextLoaderListener 将在 Web 应用程序启动时初始化
aServletContext.addListener(new ContextLoaderListener(rootContext)); // 配置 Servlet 上下文
AnnotationConfigWebApplicationContext servletContext = new AnnotationConfigWebApplicationContext();
servletContext.register(ServletContextConfig.class);
// 动态注册一个 DispatcherServlet,注意是 new DispatcherServlet(ApplicationContext)
// 并传入上文创建的 AnnotationConfigWebApplicationContext,而非传入 DispatcherServlet.class
ServletRegistration.Dynamic dynamic = aServletContext.addServlet("dispatcherServlet", new DispatcherServlet(servletContext));
// 启用文件上传
dynamic.setMultipartConfig(new MultipartConfigElement("/tmp", 20_971_520L, 41_943_040L, 512_000));
// 设置 DispatcherServlet 的映射
dynamic.addMapping("/");
// 设置应用程序部署后即启动
dynamic.setLoadOnStartup(1);
}
}
  • 两个 JSP 用于上传和下载

    WebDemo/web/upload.jsp
<%@ page contentType="text/html" pageEncoding="UTF-8" language="java" %>
<html>
<head>
<title>Upload</title>
</head>
<body>
<h2>Select a file:</h2><br /><br />
<form method="post" action="/upload" enctype="multipart/form-data">
<input type="file" name="userFile" /><br />
<input type="submit" value="Submit" />
</form>
</body>
</html>

WebDemo/web/download.jsp

<%@ page contentType="text/html" pageEncoding="UTF-8" language="java" %>
<html>
<head>
<title>Download</title>
</head>
<body>
<a href="/download">
<button type="button">Download</button>
</a>
</body>
</html>
  • 最后编写控制器即可,WebDemo/src/main/java/com/seliote/webdemo/controller/FileController.java
package com.seliote.webdemo.controller;

import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus; import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream; @Controller
public class FileController { @ResponseBody
@ResponseStatus(HttpStatus.OK)
@RequestMapping("/upload")
public String upload(@RequestPart("userFile") Part aPart) throws IOException {
if (aPart == null) {
return "Part is null";
}
InputStream inputStream = aPart.getInputStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int readLength = -1;
while ((readLength = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, readLength);
}
int length = byteArrayOutputStream.size();
byteArrayOutputStream.close();
return "Success!" + length;
} @ResponseBody
@ResponseStatus(HttpStatus.OK)
@RequestMapping("/download")
public void download(HttpServletRequest aHttpServletRequest, HttpServletResponse aHttpServletResponse) throws IOException {
File file = new File("/home/seliote/Temp/grub.cfg"); // 设置响应头,说明是文件下载
aHttpServletResponse.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
aHttpServletResponse.setContentType("application/octet-stream"); // 为响应手动写入文件
InputStream inputStream = new FileInputStream(file);
ServletOutputStream servletOutputStream = aHttpServletResponse.getOutputStream();
byte[] buffer = new byte[1024];
int readLength = -1;
while ((readLength = inputStream.read(buffer)) != -1) {
servletOutputStream.write(buffer, 0, readLength);
}
inputStream.close();
}
}

Spring 中的文件上传与下载控制的更多相关文章

  1. Java Web 学习(8) —— Spring MVC 之文件上传与下载

    Spring MVC 之文件上传与下载 上传文件 表单: <form action="upload" enctype="multipart/form-data&qu ...

  2. javaWeb中,文件上传和下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  3. JavaWeb中的文件上传和下载功能的实现

    导入相关支持jar包:commons-fileupload.jar,commons-io.jar 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上 ...

  4. Spring MVC的文件上传和下载

    简介: Spring MVC为文件上传提供了直接的支持,这种支持使用即插即用的MultipartResolver实现的.Spring MVC 使用Apache Commons FileUpload技术 ...

  5. 0062 Spring MVC的文件上传与下载--MultipartFile--ResponseEntity

    文件上传功能在网页中见的太多了,比如上传照片作为头像.上传Excel文档导入数据等 先写个上传文件的html <!DOCTYPE html> <html> <head&g ...

  6. Spring MVC-学习笔记(5)spring MVC的文件上传、下载、拦截器

    1.文件上传.      spring MVC为文件上传提供了直接的支持,这种支持是即插即用的MultipartResolver(多部分解析器)实现的.spring MVC使用Apache Commo ...

  7. 使用Spring MVC实现文件上传与下载

    前段时间做毕业设计的时候,想要完成一个上传文件的功能,后来,虽然在自己本地搭建了一个ftp服务器,然后使用公司的工具完成了一个文档管理系统:但是还是没有找到自己想要的文件上传与下载的方式. 今天看到一 ...

  8. Spring Boot入门——文件上传与下载

    1.在pom.xml文件中添加依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="ht ...

  9. Java中的文件上传和下载

    文件上传原理: 早期的文件上传机制: 在TCP/IP中.最早出现的文件上传机制是FTP.他是将文件由客户端发送到服务器的标准机制. jsp中的文件上传机制: 在jsp编程中不能使用FTP的方法来上传文 ...

随机推荐

  1. March 2 2017 Week 9 Thursday

    The first duty of love is to listen. 爱的首要责任是倾听. Yesterday, I read an article that says a successful ...

  2. BZOJ4415:[SHOI2013]发牌(线段树)

    Description 假设一开始,荷官拿出了一副新牌,这副牌有N张不同的牌,编号依次为1到N.由于是新牌,所以牌是按照顺序排好的,从牌库顶开始,依次为1, 2,……直到N,N号牌在牌库底.为了发完所 ...

  3. POJ 最小球覆盖 模拟退火

    最小球覆盖:用半径最小的球去覆盖所有点. 纯粹的退火算法,是搞不定的,精度不够,不然就会TLE,根本跑不出答案来. 任取一点为球心,然后一点点靠近最远点.其实这才是最主要的. 因为:4个点确定一个球, ...

  4. Bokeh 学习

    这段时间由于在做K-means对文本进行处理,需要进行绘图,实验室编程大哥向我介绍了Bokeh来进行绘图,一直是根据自己的需求来进行对其探索,今儿个看到一篇博文,对Bokeh进行了详细的解说,做个笔记 ...

  5. 2018.10.14 MyBatis配置实现对用户的增删改查

    记得导入对应的Jar包 ant-1.9.6.jar ant-launcher-1.9.6.jar asm-5.2.jar cglib-3.2.5.jar commons-logging-1.2.jar ...

  6. Linux云主机 监控方案浅析

    1.为何需要监控 监控是运维工程师的眼睛,它可帮助运维工程师第一时间发现系统的问题. 对于服务器的整个生命周期,都要和监控打交道: 当有服务器上架,都需要加入比如CPU负载.内存.网络.磁盘等基础监控 ...

  7. canvas基本图形

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. qbxt Day1 测试犯傻祭祀

    今天是2018/7/15 然后又是我最不喜乱的测试,期末考试爆炸仍在眼前. T1 van♂游戏 题意 小喵喵喜欢玩RPG游戏.在这款游戏中,玩家有两个属性,攻击和防御,现在小喵喵的攻击和防御都是1,接 ...

  9. onInterceptTouchEvent和onTouchEvent调用关系详解 ...

    http://blog.csdn.net/lvxiangan/article/details/9309927 老实说,这两个小东东实在是太麻烦了,很不好懂,我自己那api文档都头晕,在网上找到很多资料 ...

  10. 由inline-block小例子引申出的一些问题,及IE6、IE7兼容性解决方案

    使用场景分析: 常见的对块与块之间的横向排列处理 对同级所有元素使用display:inline-block; , 之后块与块直接会产生间隙问题 解决办法: 给父级设 font-size:0; 别高兴 ...