下面将详细讲解Java文件上传与文件下载实现方法详解,分为以下几个方面:
- 文件上传
文件上传通常需要以下几个步骤:
- 创建一个表单,允许用户选择要上传的文件;
- 通过后端编写的处理程序处理上传的文件;
- 将文件保存到服务器的指定位置。
下面使用Spring Boot框架和Thymeleaf模板实现文件上传。
首先,在Spring Boot中,我们需要添加Multipart处理器,该处理器可以帮助我们处理上传的文件:
@Configuration
public class AppConfig {
@Bean
public MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
}
然后,创建一个表单,使用户能够选择要上传的文件:
<form method="post" action="#" th:action="@{/upload}"
enctype="multipart/form-data">
<div class="form-group">
<label for="file">选择要上传的文件:</label>
<input type="file" name="file" id="file">
</div>
<button type="submit" class="btn btn-primary">上传</button>
</form>
在上面的表单中,我们使用enctype="multipart/form-data"
属性来告诉浏览器上传的是文件,而不是普通的表单数据。
接下来,我们需要编写一个Controller来处理上传的文件:
@Controller
public class FileUploadController {
@PostMapping("/upload")
public String handleFileUpload(@RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
String filename = StringUtils.cleanPath(file.getOriginalFilename());
try {
Path fileStorageLocation = Paths.get("uploads")
.toAbsolutePath().normalize();
Files.createDirectories(fileStorageLocation);
Path targetLocation = fileStorageLocation.resolve(filename);
Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
redirectAttributes.addFlashAttribute("message",
"File " + filename + " uploaded successfully!");
} catch (Exception ex) {
redirectAttributes.addFlashAttribute("message", ex.getMessage());
}
return "redirect:/";
}
}
在上面的Controller中,我们使用@PostMapping
注解来指定POST请求的URL,也就是接收表单数据的URL。@RequestParam("file")
表示接收名为file
的文件数据。
在处理Controller中,首先通过StringUtils.cleanPath(file.getOriginalFilename())
获取上传的文件名,并清理掉所有不允许的路径字符,以防止路径遍历攻击。
然后,我们使用Paths.get("uploads").toAbsolutePath().normalize()
获取要保存文件的目录,并按照我们的要求创建它。最后,我们将上传的文件保存到该目录下,并返回一个消息,告诉用户文件已经上传成功。
另外一个示例中,我们可以使用HttpClient模拟上传文件:
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("http://localhost:8080/upload");
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("file", new File("path/to/file"), ContentType.APPLICATION_OCTET_STREAM, "filename");
HttpEntity entity = builder.build();
httpPost.setEntity(entity);
CloseableHttpResponse response = httpClient.execute(httpPost);
在上面的示例中,我们创建了一个HttpPost
对象,并将它们上传到指定的URL。我们使用MultipartEntityBuilder
类创建一个Multipart对象,并将要上传的文件添加到里面。然后我们将该对象传递给HttpPost
请求,HttpClient会负责转换为HTTP请求,并将其发送到服务器。
- 文件下载
文件下载通常需要以下几个步骤:
- 根据文件名从指定位置读取文件;
- 将文件转换为字节数组;
- 将字节数组写入到HTTP响应体中。
下面使用Spring Boot框架和Thymeleaf模板实现文件下载。
首先,在Spring Boot中,我们需要添加MIME类型映射,以便识别我们要下载的文件类型:
@Configuration
public class AppConfig {
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/uploads/**")
.addResourceLocations("file:/path/to/uploads/")
.setCachePeriod(0);
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_OCTET_STREAM);
}
};
}
}
然后,我们需要编写一个Controller来处理下载的请求:
@Controller
public class FileDownloadController {
@GetMapping("/download/{fileName:.+}")
public ResponseEntity<Resource> downloadFile(@PathVariable String fileName, HttpServletRequest request) {
Resource resource = new FileSystemResource("path/to/uploads/" + fileName);
String contentType = null;
try {
contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
} catch (IOException ex) {
ex.printStackTrace();
}
if(contentType == null) {
contentType = "application/octet-stream";
}
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
}
}
在上面的Controller中,我们使用@GetMapping
注解来指定GET请求的URL,也就是请求下载文件的URL。@PathVariable
表示文件名是一个路径变量,.+
表示路径变量可以匹配带有扩展名的文件名。
在处理Controller中,我们首先从指定位置读取文件,并将其转换为Resource对象,以便让Spring MVC处理并输出到响应体中。然后我们从请求中获取文件的MIME类型,并设置到响应头中。最后,我们使用ResponseEntity
对象将文件的字节数组转换为HTTP响应体,并告诉浏览器文件应该被下载(而不是在浏览器中打开)。
另外一个示例中,我们可以使用HttpClient模拟下载文件:
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("http://localhost:8080/download/filename");
CloseableHttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = entity.getContent();
OutputStream outputStream = new FileOutputStream(new File("path/to/save/file"));
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
outputStream.close();
inputStream.close();
}
在上面的示例中,我们创建了一个HttpGet
对象,并将它们下载到指定的URL。HttpClient会负责将服务器的响应转换为HttpEntity
对象,我们可以调用getContent()
方法获得该实体的内容。最后,通过输入流把实体内容保存到本地文件中。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java文件上传与文件下载实现方法详解 - Python技术站