我可以在同一REST API响应中发送Excel文件和JSON正文以及文件说明吗 [英] Can I send an excel file and JSON body with a description of file in same REST API Response

查看:68
本文介绍了我可以在同一REST API响应中发送Excel文件和JSON正文以及文件说明吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个API,作为响应,该API返回APPLICATION_OCTET_STREAM作为媒体类型.我需要对其进行增强,以发送包含有关该文件的一些详细信息的JSON正文,例如文件中对和错记录的计数.因此,基本上我需要在同一API中提供两种响应.这可行吗?

I have an API which returns APPLICATION_OCTET_STREAM as Media Type in response. I need to enhance it to also send a JSON body with some details regarding the file, say counts of right and wrong records in the file. So basically I need two kinds of response in same API. Is this doable ?

推荐答案

可以,但是您需要使用Multipart响应.请记住,尽管某些客户端将无法处理这种类型的响应.通常,您会在上传文件时看到此数据类型,但很少将其用作响应数据类型.

It's possible, but you will need to use a Multipart response. Keep in mind though that some clients will not be able to handle this type of response. You'll normally see this data type using in uploading files, but is not very often used as a response data type.

话虽如此,下面是使用 Jersey测试框架的完整示例.在资源中,使用Jersey的FormDataMultiPart

That being said, below is a complete example using the Jersey Test Framework. In the resource, a file and some extra data are being sent in the response, with the use of Jersey's FormDataMultiPart

@Path("test")
public static class TestResource {
    @GET
    @Produces(MediaType.MULTIPART_FORM_DATA)
    public Response get() throws Exception {
        final MultiPart multiPart = new FormDataMultiPart()
                .field("json-data", new Model("Test Value"), MediaType.APPLICATION_JSON_TYPE)
                .bodyPart(new FileDataBodyPart("file-data", new File("test.txt")));
        return Response.ok(multiPart).build();
    }
}

要使测试成功,您应该在文件的第一行上有一个名为test.txt的文件,其内容为文件中有一些测试数据"(不带引号).这个多部分响应包括两个部分:json-data部分和file-data部分,其中json-data部分使用Model类对JSON进行建模,而file-data部分具有文件的内容.

To make the test succeed, you should have a file called test.txt with the content "Some Test Data in File" (without quotes) on the first line of that file. This multipart response has two parts, the json-data part, which uses a Model class to model the JSON, and the file-data part which has the contents of the file.

要使Multipart正常工作,我们需要在服务器和客户端上进行MultiPartFeature注册(用于客户端反序列化),并且需要在项目中具有multipart依赖项.

To make the Multipart work, we need to have the MultiPartFeature register on the server and the client (for client side deserialization) and we need to have the multipart dependency in our project.

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-multipart</artifactId>
    <version>${jersey2.version}</version>
</dependency>

在客户端上,要从响应中获取多部分,我们应将实体读取为FormDataMultiPart,然后我们可以按名称获取各个部分并按其数据类型提取它们.

On the client, to get the multipart out of the response, we should read the entity as FormDataMultiPart, then we can get individual parts by name and extract them by their data type.

Response res = target("test").request().get();
FormDataMultiPart multiPart = res.readEntity(FormDataMultiPart.class);
FormDataBodyPart jsonPart = multiPart.getField("json-data");
FormDataBodyPart filePart = multiPart.getField("file-data");

Model jsonData = jsonPart.getValueAs(Model.class);
InputStream file = filePart.getValueAs(InputStream.class);

下面是完整的测试.

import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
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 org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;

import static org.assertj.core.api.Assertions.assertThat;

public class MultipartResponseTest extends JerseyTest {

    public static class Model {
        private String value;
        public Model() {}
        public Model(String value) {
            this.value = value;
        }
        public String getValue() {
            return this.value;
        }
        public void setValue(String value) {
            this.value = value;
        }
    }

    @Path("test")
    public static class TestResource {
        @GET
        @Produces(MediaType.MULTIPART_FORM_DATA)
        public Response get() throws Exception {
            final MultiPart multiPart = new FormDataMultiPart()
                    .field("json-data", new Model("Test Value"), MediaType.APPLICATION_JSON_TYPE)
                    .bodyPart(new FileDataBodyPart("file-data", new File("test.txt")));
            return Response.ok(multiPart).build();
        }
    }

    @Override
    public ResourceConfig configure() {
        return new ResourceConfig()
                .register(TestResource.class)
                .register(MultiPartFeature.class);
    }

    @Override
    public void configureClient(ClientConfig config) {
        config.register(MultiPartFeature.class);
    }

    @Test
    public void testIt() throws Exception {
        final Response res = target("test")
                .request().get();
        FormDataMultiPart multiPart = res.readEntity(FormDataMultiPart.class);
        FormDataBodyPart jsonPart = multiPart.getField("json-data");
        FormDataBodyPart filePart = multiPart.getField("file-data");

        Model jsonData = jsonPart.getValueAs(Model.class);
        InputStream file = filePart.getValueAs(InputStream.class);

        BufferedReader fileReader = new BufferedReader(new InputStreamReader(file));
        String fileData = fileReader.readLine();

        file.close();
        fileReader.close();

        System.out.println(jsonData.getValue());
        System.out.println(fileData);

        assertThat(jsonData.getValue()).isEqualTo("Test Value");
        assertThat(fileData).isEqualTo("Some Test Data in File");
    }
}

要使用测试框架,您应该添加以下依赖项

To use the test framework, you should add the following dependency

<dependency>
    <groupId>org.glassfish.jersey.test-framework.providers</groupId>
    <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
    <version>${jersey2.version}</version>
</dependency>

这篇关于我可以在同一REST API响应中发送Excel文件和JSON正文以及文件说明吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆