【问题标题】:Send byte array and receive String through REST web service通过 REST Web 服务发送字节数组和接收字符串
【发布时间】:2015-11-24 15:07:35
【问题描述】:

在我的 Spring Rest web 服务中,我将一个文件(甚至很大)作为字节数组发送,但是当我收到信息时,该对象是一个字符串,所以当我从 Object 转换为 byte[] 时,我收到以下错误:

java.lang.ClassCastException: java.lang.String 无法转换为 [B

原文件通过转换

Files.readAllBytes(Paths.get(path))

并且这个byte[] 被填充到一个对象中,其中包含一个对象类型的字段result。 当客户端检索此对象并获得 result 类并转换为 byte[] 时,出现上述异常,这是客户端代码

Files.write(Paths.get("test.txt"),((byte[])response.getResult()));

如果我使用转换为字符串然后转换为字节,则文件的内容与原始文件不同。我不在乎文件类型,文件内容,我只需要从服务器复制到客户端目录 我该怎么办?谢谢

服务器类:

@Override
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public @ResponseBody Response getAcquisition(@RequestParam(value="path", defaultValue="/home") String path){
        try {
            byte[] file = matlabClientServices.getFile(path);
            if (file!=null){
                FileTransfer fileTransfer= new FileTransfer(file, Paths.get(path).getFileName().toString());
                return new Response(true, true, fileTransfer, null);
            }
            else 
                return new Response(false, false, "File doesn't exist!", null);         
        } catch (Exception e) {
            ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
            LOG.error("Threw exception in MatlabClientControllerImpl::getAcquisition :" + errorResponse.getStacktrace());
            return new Response(false, false, "Error during file retrieving!", errorResponse);
        }       
    }

而文件传输是:

    public class FileTransfer {

        private byte[] content;
        private String name;
..get and set

客户端类:

    @RequestMapping(value = "/", method = RequestMethod.GET)
public @ResponseBody Response getFile(@RequestParam(value="path", defaultValue="/home") String path){
    RestTemplate restTemplate = new RestTemplate();
    Response response = restTemplate.getForObject("http://localhost:8086/ATS/client/file/?path={path}", Response.class, path);
    if (response.isStatus() && response.isSuccess()){
        try {
            @SuppressWarnings("unchecked")
            LinkedHashMap<String,String> result= (LinkedHashMap<String,String>)response.getResult();
            //byte[] parseBase64Binary = DatatypeConverter.parseBase64Binary((String)fileTransfer.getContent());
            Files.write(Paths.get(result.get("name")), DatatypeConverter.parseBase64Binary(result.get("content"))); 
            return new Response(true, true, "Your file has been written!", null);
            } catch (IOException e) {
            return new Response(true, true, "Error writing your file!!", null);
        }
    }
    return response;
}

【问题讨论】:

  • 你能说明你是如何定义其余端点的吗?它接受什么内容类型?如果是 json,则 byte[] 将作为 Base64 编码字符串发送。给定正确的映射器,您可以将其作为 byte[].
  • 是的,我正在使用 json。我更新了上面的代码
  • 你的Response 班级是什么样子的?它不应该包含 Object 它应该是一个 byte[] 字段。
  • 它包含对象,因为响应用于所有 Web 服务
  • 如果您实际上并非一直都有相同的响应,我会考虑更改响应类。 "Q2lhbyBNb25kbw==" 否则只是反序列化器的字符串。如果你告诉它反序列化,例如一个 BinaryResponse 类,它有一个 byte[] 字段,它会为你做数据类型转换的东西。 Response&lt;GenericType&gt;(不确定这是否可行)或子类

标签: java spring file rest bytearray


【解决方案1】:

所以客户端应该是这样的

@RequestMapping(value = "/test/", method = RequestMethod.GET)
    public Response getFileTest(@RequestParam(value="path", defaultValue="/home") String path){
        RestTemplate restTemplate = new RestTemplate();
        Response response = restTemplate.getForObject("http://localhost:8086/ATS/client/file/?path={path}", Response.class, path);
        if (response.isStatus() && response.isSuccess()){
            try {
                byte[] parseBase64Binary = DatatypeConverter.parseBase64Binary((String)response.getResult());
                Files.write(Paths.get("test.txt"),parseBase64Binary );
            } catch (IOException e) {
            }
        }
        return response;
    }

【讨论】:

  • 它有效,很棒。有没有办法检索文件名和扩展名(否则我不知道原始文件)?或者我让你使用带有名称和文件的对象?
  • 你必须使用具有名称和文件的对象。字节数组只是文件的内容
  • 我更新了新的工作代码,你认为它是正确的吗?我不得不使用 LinkedHashMap 而不是 FileTrasfer 因为否则我收到异常
  • 有什么异常
  • 无法在 FileTrasfer 中转换 LinkedHashMap,getForObject 返回 Response 对象但使用 LinkedHashMap 而不是 FileTrasfer
【解决方案2】:

我相信这里的内容类型是text/plain,因此文件的内容是纯文本。只需从响应中生成字节数组:

 Files.write(Paths.get("test.txt"),((String)response.getResult()).getBytes());

【讨论】:

  • 正如我在主帖中所写,如果我转换为 String 并使用 getBytes,我收到的不是“Hello world”而是“Q2lhbyBNb25kbw=="。
  • @luca 是“Ciao Mondo”的 Base64 - 见 awsome。
  • 在将字符串编码为字节时可能需要明确指定字符集。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-04
  • 2010-11-13
  • 1970-01-01
  • 1970-01-01
  • 2011-04-13
  • 1970-01-01
相关资源
最近更新 更多