REST Web service: Upload và Download file với Jersey 2.x

1350

Bài viết được sự cho phép của tác giả Giang Phan

Trong các bài viết trước, chúng ta đã cùng tìm hiểu cách xây dựng ứng dụng CRUD với RESTful Web service. Trong bài này, chúng ta cùng tìm hiểu cách upload/ download file với RESTful sử dụng Jersey version 2.x như thế nào.

Xem thêm tuyển dụng Web Developer Jobs hấp dẫn trên TopDev

Tạo Jersey project

Chúng ta sẽ sử dụng lại project Jersey 2.x ở bài trước.

Để có thể upload/ download file với Jersey, chúng ta khai báo thêm thư viện sau trong file pom.xml.

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-multipart -->
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-multipart</artifactId>
    <version>${jersey.version}</version>
</dependency>

Đăng ký sử dụng MultiPartFeature: chúng ta có thể sử dụng một trong 2 cách sau:

  • Thêm cấu hình trong file JerseyServletContainerConfig.java
  • Thêm cấu hình trong file web.xml

JerseyServletContainerConfig.java

package com.gpcoder.config;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.logging.LoggingFeature;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
//Deployment of a JAX-RS application using @ApplicationPath with Servlet 3.0
//Descriptor-less deployment
import org.glassfish.jersey.server.ResourceConfig;

public class JerseyServletContainerConfig extends ResourceConfig {
public JerseyServletContainerConfig() {
// if there are more than two packages then separate them with semicolon
packages("com.gpcoder.api");
register(new LoggingFeature(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME), Level.INFO,
LoggingFeature.Verbosity.PAYLOAD_TEXT, 10000));
register(JacksonFeature.class);
register(MultiPartFeature.class);
}
}

web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
    <display-name>RESTful CRUD Example by gpcoder</display-name>
    <servlet>
        <servlet-name>jersey2-serlvet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.gpcoder.config.JerseyServletContainerConfig</param-value>
        </init-param>
        <init-param>
                    <param-name>jersey.config.server.provider.classnames</param-name>
                    <param-value>org.glassfish.jersey.filter.LoggingFilter;
                        org.glassfish.jersey.jackson.JacksonFeature;
                        org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
            </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>jersey2-serlvet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>

Tạo Java REST Web service cho phép upload/ download file với Jersey2

FileService.java

Tạo file FileUploadResponse.java, file này chứa thông tin trả về cho Client sau khi đã upload thành công:

package com.gpcoder.model;

import java.util.Date;

import lombok.Data;

@Data
public class FileUploadResponse {

private String fileName;
private Date createdDate;
private long fileSizeInByte;
}

Tạo REST web service cho phép upload/ download file:

package com.gpcoder.api;

import java.io.File;
import java.io.InputStream;
import java.util.Date;

import javax.activation.MimetypesFileTypeMap;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;

import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;

import com.gpcoder.model.FileUploadResponse;
import com.gpcoder.utils.FileUtils;

//URI:
//http(s)://:(port)/// //http://localhost:8080/RestfulWebServiceExample/rest/files
@Path("/files")
public class FileService {

public static final String BASE_FOLDER = "D:/WorkSpace/GPCoder/Java-Tutorial/Jersey2RestfulWebServiceExample/data/";

@GET
@Path("/download/{type}")
public Response downloadFile(@PathParam("type") String fileType) {

String fileName = "test." + fileType;
File file = new File(BASE_FOLDER + "download/" + fileName);

/* Finding MIME type for explicitly setting MIME */
String mimeType = new MimetypesFileTypeMap().getContentType(file);

ResponseBuilder responseBuilder = Response.ok(file, mimeType);
responseBuilder.header("Content-Disposition", "attachment; filename="" + fileName + """);
return responseBuilder.build();
}

@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response uploadFile( //
@FormDataParam("uploadFile") InputStream fileInputStream,
@FormDataParam("uploadFile") FormDataContentDisposition fileFormDataContentDisposition) {

String fileName = fileFormDataContentDisposition.getFileName();
File uploadedFile = FileUtils.storeFile(fileInputStream, BASE_FOLDER, fileName);

FileUploadResponse entity = new FileUploadResponse();
entity.setFileName(uploadedFile.getName());
entity.setFileSizeInByte(uploadedFile.length());
entity.setCreatedDate(new Date());
System.out.println("entity: " + entity);

return Response.ok("File uploaded successfully at " + uploadedFile.getPath()).entity(entity).build();
}
}

Lớp hỗ trợ lưu file trên server từ một InputStream:

FileUtils.java

package com.gpcoder.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Paths;

public class FileUtils {

private FileUtils() {
super();
}

public static File storeFile(InputStream inputStream, String baseFolder, String fileName) {
String extension = fileName.substring(fileName.lastIndexOf('.'));
String name = fileName.substring(0, fileName.lastIndexOf('.'));
String uploadedFilePath = baseFolder + "upload/" + name + "-" + System.currentTimeMillis() + extension;

File uploadedFile = new File(Paths.get(uploadedFilePath).toAbsolutePath().toString());
try (OutputStream outputStream = new FileOutputStream(uploadedFile)) {
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
outputStream.flush();
} catch (IOException ex) {
ex.printStackTrace();
}
return uploadedFile;
}
}

Test Upload/ Download file với RESTful web service sử dụng Postman

Test Upload/ Download file với RESTful web service sử dụng Postman

Test Upload/ Download file với RESTful web service sử dụng Postman

  • (1) : Chọn phương thức POST upload file mà REST service support.
  • (2) : Nhập địa chỉ resource.
  • (3) : Chọn tab Header.
  • (4) : Thêm header để chỉ định kết quả trả về là XML (Accept: application/xml). Nếu muốn kết quả trả về là json thì thay đổi giá trị Acccept: application/json.
  • (5) : Chọn tab Body.
  • (6) : Chọn enctype là multipart/form-data.
  • (7) : Nhập key uploadFile, key này tương ứng với đối số mà web service nhận dữ liệu.
  • (8) : Chọn loại control là Upload.
  • (9) : Chọn file để test.
  • (10) : Gửi request.
  • (11) : Kết quả trả về.
  Làm thế nào để Test Jersey Rest API với JUnit?
  Sử dụng Swagger UI trong jersey REST WS project

Tạo Java REST Client truy cập web servcie với Jersey2 Client

Tạo Jersey Client upload file

UploadFileWithJerseyRestClientExample.java

package com.gpcoder.client;

import java.io.File;
import java.io.IOException;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.glassfish.jersey.media.multipart.FormDataMultiPart;
import org.glassfish.jersey.media.multipart.MultiPart;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.media.multipart.file.FileDataBodyPart;

import com.gpcoder.model.FileUploadResponse;

public class UploadFileWithJerseyRestClientExample {

public static final String API_URL = "http://localhost:8080/RestfulWebServiceExample/rest/files/upload";

public static final String BASE_FOLDER = "D:/WorkSpace/GPCoder/Java-Tutorial/Jersey2RestfulWebServiceExample/data/";

public static void main(String[] args) throws IOException {

File testFile = new File(BASE_FOLDER + "test.jpg");
FileDataBodyPart filePart = new FileDataBodyPart("uploadFile", testFile);

try (FormDataMultiPart formDataMultiPart = new FormDataMultiPart();
MultiPart multipart = formDataMultiPart.bodyPart(filePart);) {

Client client = ClientBuilder.newBuilder().register(MultiPartFeature.class).build();
WebTarget target = client.target(API_URL);
Response response = target.request(MediaType.APPLICATION_JSON_TYPE).post(Entity.entity(multipart, multipart.getMediaType()));

FileUploadResponse result = response.readEntity(FileUploadResponse.class);
System.out.println("result: " + result);
}
}
}

Tạo Jersey Client download file

DownloadFileWithJerseyRestClientExample.java

package com.gpcoder.client;

import java.io.File;
import java.io.InputStream;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

import org.glassfish.jersey.media.multipart.MultiPartFeature;

import com.gpcoder.utils.FileUtils;

public class DownloadFileWithJerseyRestClientExample {

public static final String API_URL = "http://localhost:8080/RestfulWebServiceExample/rest/files/download/";

public static final String BASE_FOLDER = "D:/WorkSpace/GPCoder/Java-Tutorial/Jersey2RestfulWebServiceExample/data/";

public static void main(String[] args) {

Client client = ClientBuilder.newBuilder().register(MultiPartFeature.class).build();
WebTarget target = client.target(API_URL + "docx");
Response resp = target.request().get();

if (resp.getStatus() == Response.Status.OK.getStatusCode()) {
InputStream is = resp.readEntity(InputStream.class);
File uploadedFile = FileUtils.storeFile(is, BASE_FOLDER, "test-download.docx");
System.out.println("uploadedFile: " + uploadedFile.getAbsolutePath());
} else {
System.out.println("Http Call failed. The response code is" + resp.getStatus() + //
". Error reported is" + resp.getStatusInfo());
}
}
}

Bài viết gốc được đăng tải tại gpcoder.com

Có thể bạn quan tâm:

Xem thêm công việc IT ngành CNTT hấp dẫn trên TopDev