简体   繁体   English

如何在RESTEasy响应中获得混合的多重影响?

[英]How do I get a mixed multipart in a RESTEasy response?

I am trying to use resteasy. 我正在尝试使用resteasy。 While I am able to do send a mixed multipart as a request to a webservice, I am unable to do get a mixed multipart in the response. 虽然我可以将混合的多部分作为请求发送到Web服务,但是我无法在响应中得到混合的多部分。 For eg: Requesting for a file (byte[] or stream) and the file name in a single Response. 例如:在单个Response中请求文件(字节[]或流)和文件名。 Following is what I have tested: 以下是我测试的内容:

Service code: 服务代码:

@Path("/myfiles")
public class MyMultiPartWebService {

@POST
@Path("/filedetail")
@Consumes("multipart/form-data")
@Produces("multipart/mixed")
public MultipartOutput fileDetail(MultipartFormDataInput input) throws IOException {
       MultipartOutput multipartOutput = new MultipartOutput();
       //some logic based on input to locate a file(s)
       File myFile = new File("samplefile.pdf");
       multipartOutput.addPart("fileName:"+ myFile.getName(), MediaType.TEXT_PLAIN_TYPE);
       multipartOutput.addPart(file, MediaType.APPLICATION_OCTET_STREAM_TYPE);
       return multipartOutput;
 }
}

Client code: 客户代码:

public void getFileDetails(/*input params*/){
    HttpClient client = new DefaultHttpClient();
    HttpPost postRequest = new HttpPost("urlString");
    MultipartEntity multiPartEntity = new MultipartEntity();
    //prepare the request details        
    postRequest.setEntity(multiPartEntity);

    HttpResponse response = client.execute(postRequest);
    HttpEntity returnEntity = response.getEntity();

    //extracting data from the response
    Header header = returnEntity.getContentType();
    InputStream is = returnEntity.getContent();
    if (is != null) {
        byte[] bytes = IOUtils.toByteArray(is);
        //Can we see the 2 parts that were added?
        //Able to get a single InputStream only, and hence unable to differentiate two objects in the response
        //Trying to see the contents - printing as string
        System.out.println("Output from Response :: " + new String(bytes));
     }
 }

The output is as follows - able to see 2 different objects with different content types, but unable to extract them separately. 输出如下-能够看到2个具有不同内容类型的不同对象,但是无法分别提取它们。

Output from Response :: 
--af481055-4e4f-4860-9c0b-bb636d86d639
Content-Type: text/plain

fileName: samplefile.pdf
--af481055-4e4f-4860-9c0b-bb636d86d639
Content-Length: 1928
Content-Type: application/octet-stream

%PDF-1.4
<<pdf content printed as junk chars>>

How can I extract the 2 objects from the response? 如何从响应中提取2个对象?

UPDATE: 更新:

Tried the following approach to extract the different parts - use the 'boundary' to break the MultipartStream; 尝试了以下方法来提取不同部分-使用“边界”打破MultipartStream; use the content type string to extract approp object. 使用内容类型字符串提取适当的对象。

    private void getResponeObject(HttpResponse response) throws IllegalStateException, IOException {
        HttpEntity returnEntity = response.getEntity();
        Header header = returnEntity.getContentType();
        String boundary = header.getValue();
        boundary = boundary.substring("multipart/mixed; boundary=".length(), boundary.length());
        System.out.println("Boundary" + boundary); // --af481055-4e4f-4860-9c0b-bb636d86d639
        InputStream is = returnEntity.getContent();
        splitter(is, boundary);
    }

    //extract subsets from the input stream based on content type
    private void splitter(InputStream is, String boundary) throws IOException {
        ByteArrayOutputStream boas = null;
        FileOutputStream fos = null;

        MultipartStream multipartStream = new MultipartStream(is, boundary.getBytes());
        boolean nextPart = multipartStream.skipPreamble();
        System.out.println("NEXT PART :: " + nextPart);
        while (nextPart) {
            String header = multipartStream.readHeaders();
            if (header.contains("Content-Type: "+MediaType.APPLICATION_OCTET_STREAM_TYPE)) {
                fos = new FileOutputStream(new File("myfilename.pdf"));
                multipartStream.readBodyData(fos);
            } else if (header.contains("Content-Type: "+MediaType.TEXT_PLAIN_TYPE)) {
                boas = new ByteArrayOutputStream();
                multipartStream.readBodyData(boas);
                String newString = new String( boas.toByteArray());
            } else if (header.contains("Content-Type: "+ MediaType.APPLICATION_JSON_TYPE)) {
                //extract string and create JSONObject from it
            } else if (header.contains("Content-Type: "+MediaType.APPLICATION_XML_TYPE)) {
                //extract string and create XML object from it
            }
            nextPart = multipartStream.readBoundary();
        }
    }

Is this the right approach? 这是正确的方法吗?

UPDATE 2: The logic above seems to work. 更新2:上面的逻辑似乎起作用。 But got another block, when receiving the RESPONSE from the webservice. 但是,当从网络服务接收到响应时,又遇到了另一个障碍。 I could not find any references to handle such issues in the Response. 我在响应中找不到任何处理此类问题的参考。 The logic assumes that there is ONE part for a part type. 该逻辑假定零件类型只有一个零件。 If there are, say, 2 JSON parts in the response, it would be difficult to identify which part is what. 例如,如果响应中有2个JSON部分,则很难确定哪个部分是什么。 In other words, though we can add the part with a key name while creating the response, we are unable to extract the key names int he client side. 换句话说,尽管我们可以在创建响应时添加带有键名的零件,但是我们无法在客户端提取键名。 Any clues? 有什么线索吗?

You can try the following approach... 您可以尝试以下方法...

At the server side... 在服务器端...

  1. Create a wrapper object that can encapsulate all types. 创建一个可以封装所有类型的包装对象。 For eg., it could have a Map for TEXT and another Map for Binary data. 例如,它可能有一个TEXT映射和另一个Map二进制数据。
  2. Convert the TEXT content to bytes (octet stream). 将TEXT内容转换为字节(八位字节流)。
  3. Create a MetaData which contains references to the Key names and their type. 创建一个元数据,其中包含对键名称及其类型的引用。 Eg., STR_MYKEY1, BYTES_MYKEY2. 例如STR_MYKEY1,BYTES_MYKEY2。 This metadata can also be converted into octet stream. 此元数据也可以转换为八位位组流。
  4. Add the metadata and the wrapped entity as parts to the multipart response. 将元数据和包装的实体作为部分添加到多部分响应中。

At the Client side... 在客户端...

  1. Read the MetaData to get the key names. 阅读元数据以获取键名称。

  2. Use the key name to interpret each part. 使用键名来解释每个部分。 Since the Keyname from the metadata tells if the original data is a TEXT or BINARY, you should be able to extract the actual content with appropriate logic. 由于元数据中的键名会告诉您原始数据是TEXT还是BINARY,因此您应该能够使用适当的逻辑提取实际内容。

The same approach can be used for upstream, from client to service. 相同的方法可用于从客户端到服务的上游。 On top of this, you can compress the TEXT data which will help in reducing the content size... 最重要的是,您可以压缩TEXT数据,这将有助于减小内容大小...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM