Java实现文件上传服务器和客户端

下面从服务器和客户端两个角度,分别讲解Java实现文件上传的完整攻略。

一、服务器方案

1.1 前置准备

首先,我们需要引入Java的文件上传相关依赖包:commons-fileupload和commons-io。这两个包的作用是支持多种文件上传方式,并且后者还提供了一些方便的工具类来处理文件操作。

引入依赖参考pom.xml文件配置:

<dependencies>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>
</dependencies>

1.2 服务器端代码实现

服务器端代码实现大致分成以下四个步骤:

  1. 创建Servlet,配置上传文件的相关参数:
@WebServlet("/upload")
@MultipartConfig(
    location = "/tmp", // 指定上传文件的目录
    maxFileSize = 1024 * 1024 * 10, // 最大文件上传大小
    maxRequestSize = 1024 * 1024 * 50, // 最大请求体大小
    fileSizeThreshold = 1024 * 1024, // 文件大小临界值(当文件大小超过这个值时,会写入磁盘)
)
public class UploadServlet extends HttpServlet {
    // ...
}
  1. 调用request.getPart()方法获取上传文件的part对象,然后使用InputStream获取文件流和part.getSubmittedFileName()获取文件名:
Part partFile = request.getPart("file");
String fileName = partFile.getSubmittedFileName();
InputStream inputStream = partFile.getInputStream();
  1. 使用Apache commons-io的FileUtils.copyInputStreamToFile()方法将inputStream中的文件流写入到目标文件:
File targetFile = new File(uploadPath, fileName);
FileUtils.copyInputStreamToFile(inputStream, targetFile);
  1. 处理上传过程中出现的异常或者错误,并返回上传结果:
response.setContentType("application/json;charset=UTF-8");
String json = "{\"message\":\"ok\"}";
response.getWriter().write(json);

1.3 示例

下面是一个基于SpringBoot的上传文件服务器的示例代码:

@RestController
public class FileController {
    @PostMapping(value="/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<Object> upload(@RequestParam("file") MultipartFile file) throws IOException {
        File targetFile = new File("/tmp/" + file.getOriginalFilename());
        file.transferTo(targetFile);
        return ResponseEntity.ok().build();
    }
}

二、客户端方案

2.1 前置准备

在客户端实现文件上传的过程中,我们需要使用Java的HttpURLConnection和BufferedReader类。具体来说,我们先构造HttpURLConnection对象,并设置相关的属性,比如请求的方式和请求头参数。然后,将要上传的文件读入内存中,然后构造一个OutputStream对象并将文件写入请求中。最后,处理服务器端的返回结果。

2.2 客户端代码实现

客户端上传文件通常分成以下三个步骤:

  1. 配置请求参数:
URL url = new URL("http://localhost:8080/upload");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
connection.setDoOutput(true);
  1. 构造表单数据:
OutputStream outputStream = connection.getOutputStream();
String formdataTemplate = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s";
outputStream.write(String.format(formdataTemplate, "name", "testname").getBytes("utf-8"));
outputStream.write(String.format(formdataTemplate, "email", "testemail").getBytes("utf-8"));
outputStream.write(String.format(formdataTemplate, "file", file.getName()).getBytes("utf-8"));
  1. 上传文件并处理结果:
FileInputStream inputStream = new FileInputStream(file);
int bytesRead = -1;
byte[] buffer = new byte[4096];
while ((bytesRead = inputStream.read(buffer)) != -1) {
    outputStream.write(buffer, 0, bytesRead);
}
outputStream.write("\r\n--".getBytes("utf-8"));
outputStream.write(boundary.getBytes("utf-8"));
outputStream.write("--\r\n".getBytes("utf-8"));

BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
String line = "";
while ((line = in.readLine()) != null) {
    System.out.println(line);
}

inputStream.close();
outputStream.flush();
outputStream.close();

2.3 示例

下面是一个基于Java URL的上传文件的客户端示例代码:

public class FileUploadTest {
    public static void main(String[] args) throws Exception {
        String boundary = UUID.randomUUID().toString();
        File file = new File("test.jpg");
        URL url = new URL("http://localhost:8080/upload");

        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
        connection.setDoOutput(true);

        OutputStream outputStream = connection.getOutputStream();

        String formdataTemplate = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s";
        outputStream.write(String.format(formdataTemplate, "name", "testname").getBytes("utf-8"));
        outputStream.write(String.format(formdataTemplate, "email", "testemail").getBytes("utf-8"));
        outputStream.write(String.format(formdataTemplate, "file", file.getName()).getBytes("utf-8"));

        FileInputStream inputStream = new FileInputStream(file);
        int bytesRead = -1;
        byte[] buffer = new byte[4096];
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        outputStream.write("\r\n--".getBytes("utf-8"));
        outputStream.write(boundary.getBytes("utf-8"));
        outputStream.write("--\r\n".getBytes("utf-8"));
        inputStream.close();

        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
        String line = "";
        while ((line = in.readLine()) != null) {
            System.out.println(line);
        }

        outputStream.flush();
        outputStream.close();
    }
}

这篇文章介绍了常见的文件上传操作。在实际开发中,我们可以根据业务需求进行修改和扩展。在此基础上,还可以加入安全认证和限流等措施加强上传文件的安全性和稳定性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现文件上传服务器和客户端 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • 关于JDK8中的字符串拼接示例详解

    关于JDK8中的字符串拼接示例详解攻略,可以分为以下几个部分。 一、背景介绍 在现代开发中,字符串的处理是开发中非常重要,且经常需要用到的一项技术。在JDK8中,Java提供了许多新的字符串拼接方式,包括 String.join()方法、String.format()方法、StringBuilder等。这些方法虽然实现的目的是一样的,但是使用的方式以及处理的…

    Java 2023年5月27日
    00
  • Java实现的两种常见简单查找算法示例【快速查找与二分查找】

    下面我就来详细讲解一下Java实现的快速查找和二分查找算法。 一、快速查找 快速查找,也称为顺序查找,是一种最简单的查找算法。这种算法就是在待查找的一组数据中,顺序地遍历每一个数据,直到找到待查找的目标数据为止,或者遍历完数组都没有找到目标数据。 Java实现快速查找的代码如下: public class QuickFind { // 查找函数 public…

    Java 2023年5月19日
    00
  • CSS变量实现主题切换的方法

    下面我将详细讲解CSS变量实现主题切换的方法的完整攻略。 什么是CSS变量? CSS变量也称为自定义属性,是一种定义在CSS规则中的、可重复使用的值。与常规的CSS属性不同,CSS变量以双减号(–)开头,并可以在整个样式表的范围内使用。 实现简介 利用CSS变量实现主题切换的方法主要包括以下几个步骤: 定义多套主题色进行切换; 使用CSS变量将主题色应用到…

    Java 2023年6月15日
    00
  • 详解Java 中的函数式接口

    详解Java 中的函数式接口 函数式编程作为现代编程语言的一种编程范式,使用的越来越广泛。而Java 8以后,也开始支持函数式编程。函数式编程有一个非常重要的概念——函数式接口。本文将通过以下几个方面详细讲解Java中的函数式接口。 什么是函数式接口? 函数式接口是指仅有一个抽象方法的接口。函数式接口是函数式编程的核心。 Java 的Lambda 表达式、方…

    Java 2023年5月26日
    00
  • Spring Mvc中传递参数方法之url/requestMapping详解

    Spring MVC中传递参数方法之URL/RequestMapping详解 在Spring MVC中,我们可以通过URL和RequestMapping来传递参数。本文将详细介绍Spring MVC中传递参数的方法,并提供两个示例说明。 URL传递参数 在Spring MVC中,我们可以通过URL来传递参数。以下是一个简单的URL传递参数示例,它将参数id传…

    Java 2023年5月17日
    00
  • Hibernate通用数据库操作代码

    下面是Hibernate通用数据库操作代码的完整攻略。 什么是Hibernate通用数据库操作代码? Hibernate通用数据库操作代码是指能够适用于多种不同数据模型和表结构的重复使用的数据库操作代码块。 如何写Hibernate通用数据库操作代码? 以下是写Hibernate通用数据库操作代码的步骤: 配置Hibernate 要使用Hibernate,需…

    Java 2023年5月20日
    00
  • 对ArrayList和LinkedList底层实现原理详解

    对ArrayList和LinkedList底层实现原理详解 ArrayList 简介 ArrayList是基于动态数组实现的,其最大的特点就是可以随机访问,这也是数组的一个最大优点。另外,ArrayList支持在尾部快速添加元素的操作,当然,如果要在中间插入、删除元素,这是需要移动数组元素,所以操作速度会相对比较慢,并且,在ArrayList中,如果进行了大…

    Java 2023年5月26日
    00
  • Java中使用LocalDate根据日期来计算年龄的实现方法

    以下是详细的“Java中使用LocalDate根据日期来计算年龄的实现方法”的攻略: 1. 概述 Java 8中的java.time包提供了一个强大的日期和时间API。在Java 8中,可以使用LocalDate类来表示一个日期,该类提供了许多方法来计算年龄。可以使用LocalDate的静态方法来计算年龄。在本攻略中,我们将提供两个示例,来演示如何使用Loc…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部