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

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

将文件上传到 Web 应用程序是当今的一项常见任务。 许多服务都支持在其网站上上传图片或文档。 使用 Java Web 服务,这很容易实现。 除了 Java Web 容器(由 TomcatGlassFishJBoss 等应用服务器提供)之外,我们还需要 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

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