原文: https://javatutorial.net/java-file-upload-rest-service

在本教程中,我将解释如何构建 Java REST Web 服务以通过 HTTP 从任何客户端上载文件。

将文件上传到 Web 应用程序是当今的一项常见任务。 许多服务都支持在其网站上上传图片或文档。 使用 Java Web 服务,这很容易实现。 除了 Java Web 容器(由 Tomcat,GlassFish 或 JBoss 等应用服务器提供)之外,我们还需要 Jersey 使它运行。 首先,我将向您展示如何实现 Web 服务,然后为您提供两个使用该服务的客户端示例。

Java 文件上传 REST 服务 - 图1

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 下找到整个项目

我将在此处发布整个 POM 文件,但您需要考虑的是 Jersey 依赖项

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3. <modelVersion>4.0.0</modelVersion>
  4. <groupId>net.javatutorial.tutorials</groupId>
  5. <artifactId>FileUploaderRESTService</artifactId>
  6. <version>1</version>
  7. <packaging>war</packaging>
  8. <name>File Uploader Rest Service</name>
  9. <url>https://javatutorial.net</url>
  10. <properties>
  11. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  12. </properties>
  13. <dependencies>
  14. <dependency>
  15. <groupId>com.sun.jersey</groupId>
  16. <artifactId>jersey-server</artifactId>
  17. <version>1.8</version>
  18. </dependency>
  19. <dependency>
  20. <groupId>com.sun.jersey</groupId>
  21. <artifactId>jersey-servlet</artifactId>
  22. <version>1.17.1</version>
  23. </dependency>
  24. <dependency>
  25. <groupId>com.sun.jersey</groupId>
  26. <artifactId>jersey-json</artifactId>
  27. <version>1.8</version>
  28. </dependency>
  29. <dependency>
  30. <groupId>com.sun.jersey.contribs</groupId>
  31. <artifactId>jersey-multipart</artifactId>
  32. <version>1.8</version>
  33. </dependency>
  34. </dependencies>
  35. <build>
  36. <plugins>
  37. <plugin>
  38. <groupId>org.apache.maven.plugins</groupId>
  39. <artifactId>maven-compiler-plugin</artifactId>
  40. <version>3.1</version>
  41. <inherited>true</inherited>
  42. <configuration>
  43. <source>1.7</source>
  44. <target>1.7</target>
  45. </configuration>
  46. </plugin>
  47. <plugin>
  48. <artifactId>maven-war-plugin</artifactId>
  49. <version>2.3</version>
  50. <configuration>
  51. <webXml>src/main/webapp/WEB-INF/web.xml</webXml>
  52. <webResources>
  53. <resource>
  54. <!-- this is relative to the pom.xml directory -->
  55. <directory>${project.basedir}/src/main/resources
  56. </directory>
  57. </resource>
  58. </webResources>
  59. </configuration>
  60. </plugin>
  61. </plugins>
  62. </build>
  63. </project>

现在拥有所有必需的库,让我们继续实现 REST 服务。 下面的代码中有几个地方我想提醒您注意。 首先请注意@Consumes(MediaType.MULTIPART_FORM_DATA)作为请求的编码类型的用法。 其次,如果愿意,您可能希望向该方法添加其他参数。 例如,您可能要在上传时传递一些描述或其他文本数据。 最后,如果您尝试将文件上传到不存在的目录中,Java 将抛出异常。 为了避免这个问题,我创建了方法createFolderIfNotExists(StringdirName)。

  1. package net.javatutorial.tutorials.services;
  2. import java.io.File;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.io.OutputStream;
  7. import javax.ws.rs.Consumes;
  8. import javax.ws.rs.POST;
  9. import javax.ws.rs.Path;
  10. import javax.ws.rs.core.Context;
  11. import javax.ws.rs.core.MediaType;
  12. import javax.ws.rs.core.Response;
  13. import javax.ws.rs.core.UriInfo;
  14. import com.sun.jersey.core.header.FormDataContentDisposition;
  15. import com.sun.jersey.multipart.FormDataParam;
  16. /**
  17. * This example shows how to build Java REST web-service to upload files
  18. * accepting POST requests with encoding type "multipart/form-data". For more
  19. * details please read the full tutorial on
  20. * https://javatutorial.net/java-file-upload-rest-service
  21. *
  22. * @author javatutorial.net
  23. */
  24. @Path("/upload")
  25. public class FileUploadService {
  26. /** The path to the folder where we want to store the uploaded files */
  27. private static final String UPLOAD_FOLDER = "c:/uploadedFiles/";
  28. public FileUploadService() {
  29. }
  30. @Context
  31. private UriInfo context;
  32. /**
  33. * Returns text response to caller containing uploaded file location
  34. *
  35. * @return error response in case of missing parameters an internal
  36. * exception or success response if file has been stored
  37. * successfully
  38. */
  39. @POST
  40. @Consumes(MediaType.MULTIPART_FORM_DATA)
  41. public Response uploadFile(
  42. @FormDataParam("file") InputStream uploadedInputStream,
  43. @FormDataParam("file") FormDataContentDisposition fileDetail) {
  44. // check if all form parameters are provided
  45. if (uploadedInputStream == null || fileDetail == null)
  46. return Response.status(400).entity("Invalid form data").build();
  47. // create our destination folder, if it not exists
  48. try {
  49. createFolderIfNotExists(UPLOAD_FOLDER);
  50. } catch (SecurityException se) {
  51. return Response.status(500)
  52. .entity("Can not create destination folder on server")
  53. .build();
  54. }
  55. String uploadedFileLocation = UPLOAD_FOLDER + fileDetail.getFileName();
  56. try {
  57. saveToFile(uploadedInputStream, uploadedFileLocation);
  58. } catch (IOException e) {
  59. return Response.status(500).entity("Can not save file").build();
  60. }
  61. return Response.status(200)
  62. .entity("File saved to " + uploadedFileLocation).build();
  63. }
  64. /**
  65. * Utility method to save InputStream data to target location/file
  66. *
  67. * @param inStream
  68. * - InputStream to be saved
  69. * @param target
  70. * - full path to destination file
  71. */
  72. private void saveToFile(InputStream inStream, String target)
  73. throws IOException {
  74. OutputStream out = null;
  75. int read = 0;
  76. byte[] bytes = new byte[1024];
  77. out = new FileOutputStream(new File(target));
  78. while ((read = inStream.read(bytes)) != -1) {
  79. out.write(bytes, 0, read);
  80. }
  81. out.flush();
  82. out.close();
  83. }
  84. /**
  85. * Creates a folder to desired location if it not already exists
  86. *
  87. * @param dirName
  88. * - full path to the folder
  89. * @throws SecurityException
  90. * - in case you don't have permission to create the folder
  91. */
  92. private void createFolderIfNotExists(String dirName)
  93. throws SecurityException {
  94. File theDir = new File(dirName);
  95. if (!theDir.exists()) {
  96. theDir.mkdir();
  97. }
  98. }
  99. }

最后,我们需要配置web.xml以将我们的类注册为 Web 服务并使其在启动时运行。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  4. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  5. id="WebApp_ID" version="2.5">
  6. <display-name>net.javatutorial.tutorials.services</display-name>
  7. <servlet>
  8. <servlet-name>Jersey REST Service</servlet-name>
  9. <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
  10. <init-param>
  11. <param-name>com.sun.jersey.config.property.packages</param-name>
  12. <param-value>net.javatutorial.tutorials.services</param-value>
  13. </init-param>
  14. <load-on-startup>1</load-on-startup>
  15. </servlet>
  16. <servlet-mapping>
  17. <servlet-name>Jersey REST Service</servlet-name>
  18. <url-pattern>/rest/*</url-pattern>
  19. </servlet-mapping>
  20. </web-app>

好的! 现在,您可以构建和部署 WAR 文件。 如果您使用上面代码中提供的完全相同的名称,则您的服务 URL(假设您在localhost上运行)将是:http://localhost:8080/FileUploaderRESTService-1/rest/upload

文件上传 HTML 表格

您可以使用非常简单的 HTML post 表单作为客户端将文件发送到服务器。

请注意multipart/form-data作为编码类型的用法。 您还需要添加文件类型为[file]的输入

  1. Choose file to upload<br>
  2. <form action="http://localhost:8080/FileUploaderRESTService-1/rest/upload" method="post" enctype="multipart/form-data">
  3. <input name="file" id="filename" type="file" /><br><br>
  4. <button name="submit" type="submit">Upload</button>
  5. </form>

如前所述,您可以向请求中添加其他数据。 在这种情况下,别忘了在网络服务中处理它🙂

Java 文件上传客户端

您可以为 Android 或 Java 中的独立程序创建文件上传客户端。 在下面的示例中,我将使用 Apache http 库,您将需要以下五个:

  • commonlog
  • httpclient
  • httpclient cache
  • httpcore
  • httpmime
  1. package net.javatutorial.tutorials.clienst;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.IOException;
  5. import org.apache.http.HttpEntity;
  6. import org.apache.http.HttpResponse;
  7. import org.apache.http.client.ClientProtocolException;
  8. import org.apache.http.client.methods.HttpPost;
  9. import org.apache.http.entity.mime.MultipartEntity;
  10. import org.apache.http.entity.mime.content.InputStreamBody;
  11. import org.apache.http.impl.client.DefaultHttpClient;
  12. import org.apache.http.params.BasicHttpParams;
  13. import org.apache.http.util.EntityUtils;
  14. /**
  15. * This example shows how to upload files using POST requests
  16. * with encoding type "multipart/form-data".
  17. * For more details please read the full tutorial
  18. * on https://javatutorial.net/java-file-upload-rest-service
  19. * @author javatutorial.net
  20. */
  21. public class FileUploaderClient {
  22. public static void main(String[] args) {
  23. // the file we want to upload
  24. File inFile = new File("C:\\Users\\admin\\Desktop\\Yana-make-up.jpg");
  25. FileInputStream fis = null;
  26. try {
  27. fis = new FileInputStream(inFile);
  28. DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
  29. // server back-end URL
  30. HttpPost httppost = new HttpPost("http://localhost:8080/FileUploaderRESTService-1/rest/upload");
  31. MultipartEntity entity = new MultipartEntity();
  32. // set the file input stream and file name as arguments
  33. entity.addPart("file", new InputStreamBody(fis, inFile.getName()));
  34. httppost.setEntity(entity);
  35. // execute the request
  36. HttpResponse response = httpclient.execute(httppost);
  37. int statusCode = response.getStatusLine().getStatusCode();
  38. HttpEntity responseEntity = response.getEntity();
  39. String responseString = EntityUtils.toString(responseEntity, "UTF-8");
  40. System.out.println("[" + statusCode + "] " + responseString);
  41. } catch (ClientProtocolException e) {
  42. System.err.println("Unable to make connection");
  43. e.printStackTrace();
  44. } catch (IOException e) {
  45. System.err.println("Unable to read file");
  46. e.printStackTrace();
  47. } finally {
  48. try {
  49. if (fis != null) fis.close();
  50. } catch (IOException e) {}
  51. }
  52. }
  53. }

您将在我们的 GitHub 存储库中找到项目文件 https://github.com/JavaTutorialNetwork/Tutorials/tree/master/FileUploaderJavaClient

谢谢阅读。 一如既往欢迎评论🙂