# Java 文件上传 REST 服务
> 原文: [https://javatutorial.net/java-file-upload-rest-service](https://javatutorial.net/java-file-upload-rest-service)
在本教程中,我将解释如何构建 Java REST Web 服务以通过 HTTP 从任何客户端上载文件。
将文件上传到 Web 应用程序是当今的一项常见任务。 许多服务都支持在其网站上上传图片或文档。 使用 Java Web 服务,这很容易实现。 除了 Java Web 容器(由 [Tomcat](http://tomcat.apache.org/),[GlassFish](http://www.oracle.com/us/products/middleware/cloud-app-foundation/glassfish-server/overview/index.html) 或 [JBoss](http://wildfly.org/) 等应用服务器提供)之外,我们还需要 [Jersey](https://github.com/jersey) 使它运行。 首先,我将向您展示如何实现 Web 服务,然后为您提供两个使用该服务的客户端示例。
![Java file upload form](https://img.kancloud.cn/1e/0d/1e0d6e2f821177a3c1ec080f42967809_547x221.jpg)
Java 文件上传表格
## 构建文件上传 REST 服务
该文件通过 HTTP POST 以编码类型`multipart/form-data`从客户端推送到我们的 Web 服务。 这样,除了文件之外,您还可以向 POST 请求添加多个参数。 让我们从需求开始。 您将需要 Web 应用程序服务器(例如 Tomcat,GlassFish 或 JBoss)来部署服务。 另外,我们将使用 jersey 框架来构建我们的服务端点。 请注意,GlassFish 4.x 版本需要 jersey 版本 2 库,因此如果使用 GlassFish 4,则**请在您的 POM 文件中使用 jersey 2.x 依赖项**。
为了快速参考,您可以在我们的 GitHub 存储库中的 [https://github.com/JavaTutorialNetwork/Tutorials/tree/master/FileUploaderRESTService](https://github.com/JavaTutorialNetwork/Tutorials/tree/master/FileUploaderRESTService) 下找到整个项目
我将在此处发布整个 POM 文件,但您需要考虑的是 Jersey 依赖项
```java
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.javatutorial.tutorials</groupId>
<artifactId>FileUploaderRESTService</artifactId>
<version>1</version>
<packaging>war</packaging>
<name>File Uploader Rest Service</name>
<url>https://javatutorial.net</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.8</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<inherited>true</inherited>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>${project.basedir}/src/main/resources
</directory>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
```
现在拥有所有必需的库,让我们继续实现 REST 服务。 下面的代码中有几个地方我想提醒您注意。 首先请注意`@Consumes(MediaType.MULTIPART_FORM_DATA)`作为请求的编码类型的用法。 其次,如果愿意,您可能希望向该方法添加其他参数。 例如,您可能要在上传时传递一些描述或其他文本数据。 最后,如果您尝试将文件上传到不存在的目录中,Java 将抛出异常。 为了避免这个问题,我创建了方法`createFolderIfNotExists(StringdirName)`。
```java
package net.javatutorial.tutorials.services;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;
/**
* This example shows how to build Java REST web-service to upload files
* accepting POST requests with encoding type "multipart/form-data". For more
* details please read the full tutorial on
* https://javatutorial.net/java-file-upload-rest-service
*
* @author javatutorial.net
*/
@Path("/upload")
public class FileUploadService {
/** The path to the folder where we want to store the uploaded files */
private static final String UPLOAD_FOLDER = "c:/uploadedFiles/";
public FileUploadService() {
}
@Context
private UriInfo context;
/**
* Returns text response to caller containing uploaded file location
*
* @return error response in case of missing parameters an internal
* exception or success response if file has been stored
* successfully
*/
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(
@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail) {
// check if all form parameters are provided
if (uploadedInputStream == null || fileDetail == null)
return Response.status(400).entity("Invalid form data").build();
// create our destination folder, if it not exists
try {
createFolderIfNotExists(UPLOAD_FOLDER);
} catch (SecurityException se) {
return Response.status(500)
.entity("Can not create destination folder on server")
.build();
}
String uploadedFileLocation = UPLOAD_FOLDER + fileDetail.getFileName();
try {
saveToFile(uploadedInputStream, uploadedFileLocation);
} catch (IOException e) {
return Response.status(500).entity("Can not save file").build();
}
return Response.status(200)
.entity("File saved to " + uploadedFileLocation).build();
}
/**
* Utility method to save InputStream data to target location/file
*
* @param inStream
* - InputStream to be saved
* @param target
* - full path to destination file
*/
private void saveToFile(InputStream inStream, String target)
throws IOException {
OutputStream out = null;
int read = 0;
byte[] bytes = new byte[1024];
out = new FileOutputStream(new File(target));
while ((read = inStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
}
/**
* Creates a folder to desired location if it not already exists
*
* @param dirName
* - full path to the folder
* @throws SecurityException
* - in case you don't have permission to create the folder
*/
private void createFolderIfNotExists(String dirName)
throws SecurityException {
File theDir = new File(dirName);
if (!theDir.exists()) {
theDir.mkdir();
}
}
}
```
最后,我们需要配置`web.xml`以将我们的类注册为 Web 服务并使其在启动时运行。
```java
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>net.javatutorial.tutorials.services</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>net.javatutorial.tutorials.services</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
```
好的! 现在,您可以构建和部署 WAR 文件。 如果您使用上面代码中提供的完全相同的名称,则您的服务 URL(假设您在`localhost`上运行)将是:`http://localhost:8080/FileUploaderRESTService-1/rest/upload`
## 文件上传 HTML 表格
您可以使用非常简单的 HTML post 表单作为客户端将文件发送到服务器。
请注意`multipart/form-data`作为编码类型的用法。 您还需要添加文件类型为`[file]`的输入
```java
Choose file to upload<br>
<form action="http://localhost:8080/FileUploaderRESTService-1/rest/upload" method="post" enctype="multipart/form-data">
<input name="file" id="filename" type="file" /><br><br>
<button name="submit" type="submit">Upload</button>
</form>
```
如前所述,您可以向请求中添加其他数据。 在这种情况下,别忘了在网络服务中处理它🙂
## Java 文件上传客户端
您可以为 Android 或 Java 中的独立程序创建文件上传客户端。 在下面的示例中,我将使用 Apache http 库,您将需要以下五个:
* commonlog
* httpclient
* httpclient cache
* httpcore
* httpmime
```java
package net.javatutorial.tutorials.clienst;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.InputStreamBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.util.EntityUtils;
/**
* This example shows how to upload files using POST requests
* with encoding type "multipart/form-data".
* For more details please read the full tutorial
* on https://javatutorial.net/java-file-upload-rest-service
* @author javatutorial.net
*/
public class FileUploaderClient {
public static void main(String[] args) {
// the file we want to upload
File inFile = new File("C:\\Users\\admin\\Desktop\\Yana-make-up.jpg");
FileInputStream fis = null;
try {
fis = new FileInputStream(inFile);
DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
// server back-end URL
HttpPost httppost = new HttpPost("http://localhost:8080/FileUploaderRESTService-1/rest/upload");
MultipartEntity entity = new MultipartEntity();
// set the file input stream and file name as arguments
entity.addPart("file", new InputStreamBody(fis, inFile.getName()));
httppost.setEntity(entity);
// execute the request
HttpResponse response = httpclient.execute(httppost);
int statusCode = response.getStatusLine().getStatusCode();
HttpEntity responseEntity = response.getEntity();
String responseString = EntityUtils.toString(responseEntity, "UTF-8");
System.out.println("[" + statusCode + "] " + responseString);
} catch (ClientProtocolException e) {
System.err.println("Unable to make connection");
e.printStackTrace();
} catch (IOException e) {
System.err.println("Unable to read file");
e.printStackTrace();
} finally {
try {
if (fis != null) fis.close();
} catch (IOException e) {}
}
}
}
```
您将在我们的 GitHub 存储库中找到项目文件 [https://github.com/JavaTutorialNetwork/Tutorials/tree/master/FileUploaderJavaClient](https://github.com/JavaTutorialNetwork/Tutorials/tree/master/FileUploaderJavaClient)
谢谢阅读。 一如既往欢迎评论🙂
- JavaTutorialNetwork 中文系列教程
- Java 基础
- Java 概述
- 在 Ubuntu 上安装 Java 8 JDK
- Java Eclipse 教程
- Eclipse 快捷方式
- 简单的 Java 示例
- Java 基本类型
- Java 循环
- Java 数组
- Java 读取文件示例
- Java 对象和类教程
- 什么是面向对象编程(OOP)
- Java 封装示例
- Java 接口示例
- Java 继承示例
- Java 抽象示例
- Java 多态示例
- Java 中的方法重载与方法覆盖
- Java 控制流语句
- Java 核心
- 如何在 Windows,Linux 和 Mac 上安装 Maven
- 如何使用 Maven 配置文件
- 如何将自定义库包含到 Maven 本地存储库中
- 如何使用 JUnit 进行单元测试
- 如何使用 Maven 运行 JUnit 测试
- 如何在 Java 中使用 Maven 创建子模块
- 如何使用 Maven 创建 Java JAR 文件
- 如何使用 Maven 创建 Java WAR 文件
- JVM 解释
- Java 内存模型解释示例
- 捕获 Java 堆转储的前 3 种方法
- Java 垃圾收集
- Java 互斥量示例
- Java 信号量示例
- Java 并行流示例
- Java 线程同步
- Java 线程池示例
- Java ThreadLocal示例
- Java 中的活锁和死锁
- Java Future示例
- Java equals()方法示例
- Java Lambda 表达式教程
- Java Optional示例
- Java 11 HTTP 客户端示例
- Java 类加载器介绍
- Java 枚举示例
- Java hashCode()方法示例
- 如何测试独立的 Java 应用程序
- SWING JFrame基础知识,如何创建JFrame
- Java SWING JFrame布局示例
- 在JFrame上显示文本和图形
- 与JFrame交互 – 按钮,监听器和文本区域
- 如何使用 Maven 创建 Java JAR 文件
- Java Collection新手指南
- 选择合适的 Java 集合
- Java ArrayList示例
- Java LinkedList示例
- Java HashSet示例
- Java TreeSet示例
- Java LinkedHashSet示例
- Java EnumSet示例
- Java ConcurrentHashSet示例
- Java HashMap示例
- Java LinkedHashMap示例
- Java TreeMap示例
- Java EnumMap示例
- Java WeakHashMap示例
- Java IdentityHashMap示例
- Java SortedMap示例
- Java ConcurrentMap示例
- Java Hashtable示例
- Java 中ArrayList和LinkedList之间的区别
- Java HashMap迭代示例
- Java HashMap内联初始化
- Java 中HashMap和TreeMap之间的区别
- Java 图示例
- Java 深度优先搜索示例
- Java 广度优先搜索示例
- 不同的算法时间复杂度
- Java 序列化示例
- Java 反射示例
- Java 中的弱引用
- Java 8 日期时间 API
- Java 基本正则表达式
- 使用 Java 检索可用磁盘空间
- Java 生成 MD5 哈希和
- Java 增加内存
- Java 属性文件示例
- 如何在 Eclipse 上安装 Java 9 Beta
- Java 9 JShell 示例
- Java 9 不可变列表示例
- Java 9 不可变集示例
- Java 9 不可变映射示例
- Java 单例设计模式示例
- Java 代理设计模式示例
- Java 观察者设计模式示例
- Java 工厂设计模式
- Java 构建器设计模式
- Java 比较器示例
- Java 发送电子邮件示例
- Java volatile示例
- Java Docker 和 Docker 容器简介
- 安装和配置 MySQL 数据库和服务器以供 Spring 使用
- 如何在 Java 中使用 MySQL 连接器
- 如何使用 Eclipse 调试 Java
- Java EE
- 如何在 Windows 10 中设置JAVA_HOME
- JavaBeans 及其组件简介
- 如何安装和配置 Tomcat 8
- 如何在 Tomcat 中部署和取消部署应用程序
- 从 Eclipse 运行 Tomcat
- Java Servlet 示例
- Java Servlet POST 示例
- Servlet 请求信息示例
- Servlet 注解示例
- 使用初始化参数配置 Java Web 应用程序
- Java Servlet 文件上传
- Java JSP 示例
- Glassfish 启用安全管理
- 如何使用 MySQL 配置 Glassfish 4
- Java 文件上传 REST 服务
- Glassfish 和 Jetty 的 Java WebSockets 教程
- 基于 Glassfish 表单的身份验证示例
- 如何使用 Java EE 和 Angular 构建单页应用程序
- Spring
- 在 Eclipse 中安装 Spring STS
- 使用 STS 创建简单的 Spring Web App
- Spring Web Framework 简介
- Java Docker 和 Docker 容器简介
- 在 Spring 中实现控制器
- Spring 中的PathVariable注解
- Spring 中的RequestBody注解
- Spring 中的RequestParam注解
- Spring 拦截器
- Spring IOC
- Java Spring IoC 容器示例
- Spring 中的DispatcherServlet
- Spring 示例中的依赖注入
- 实现 Spring MVC 控制器
- Spring ORM 简介
- 什么是 DAO 以及如何使用它
- 如何对 DAO 组件进行单元测试
- 如何对控制器和服务执行单元测试
- 安装和配置 MySQL 数据库和服务器以供 Spring 使用
- 如何在 Spring 中处理登录身份验证
- Spring Security 简介及其设置
- 如何使用 Spring 创建 RESTful Web 服务
- Spring CSRF 保护
- Spring 中基于 OAuth2 的身份验证和授权
- Spring Boot 简介
- Spring MVC 框架介绍
- Spring JDBC 简介
- 如何 docker 化 Spring 应用程序
- Spring 的@Autowired注解
- Spring AOP 中的核心概念和建议类型
- Sping Bean 简介
- 如何在 Java 中使用 MySQL 连接器
- 安卓
- 安装和配置 Android Studio
- 将 Android 设备连接到 Android Studio
- Android 简介,活动,意图,服务,布局
- 创建一个简单的 Android 应用
- 运行和调试 Android 应用程序
- 在虚拟设备上运行 Android 应用程序
- Android 活动示例
- Android 意图示例
- Android 服务示例
- Android 线性布局示例
- Android 相对布局示例
- Android Web 视图示例
- Android 列表视图示例
- Android 网格视图示例
- 带有ListAdapter的 Android ListView示例
- Android SQLite 数据库介绍
- Android SQLite 数据库示例
- Android 动画教程
- Android 中的通知
- Android 中的事件处理
- 如何在 Android 中发送带有附件的电子邮件
- 杂项
- 选择您的 JAVA IDE:Eclipse,NetBeans 和 IntelliJ IDEA
- Java S3 示例
- 如何在 Ubuntu 上为多个站点配置 Apache
- 如何在 Liferay DXP 中替代现成的(OOTB)模块
- 简单的 Git 教程
- 使用 Java 捕获网络数据包
- Selenium Java 教程
- 使用特定工作区运行 Eclipse
- 在 Eclipse 中安装 SVN
- 如何运行 NodeJS 服务器
- SQL 内连接示例
- SQL 左连接示例
- SQL 右连接示例
- SQL 外连接示例
- 树莓派
- Raspberry Pi 3 规格
- 将 Raspbian 安装到 SD 卡
- Raspberry Pi 首次启动
- 远程连接到 Raspberry Pi
- 建立 Raspberry Pi 远程桌面连接
- Raspberry Pi Java 教程
- 使用 PWM 的 Raspberry Pi LED 亮度调节
- Raspberry Pi 控制电机速度
- Raspberry Pi 用 Java 控制直流电机的速度和方向