【问题标题】:Conversion of Base64 String to byte arrayBase64字符串到字节数组的转换
【发布时间】:2017-07-22 17:31:34
【问题描述】:

在我当前的 spring 项目中,我有一个包含一些 input[type=file] 字段的表单,需要由这个 PropertyEditorSupport 类处理:

public class ImagemEditor extends PropertyEditorSupport {
  private String file_path = System.getProperty("user.home")+File.separator+".store"+File.separator+"Pictures";

  @Override
  public void setAsText(String text) {
    ...
  }
  ...
}

图像作为 Base64 字符串发送到服务器,并通过此 javascript 代码添加到其他参数:

  $('input[type=file]').on("change", function(){
    var id = $(this).attr("id");
    var name = $(this).attr("name");
    if(typeof id !== "undefined") {
      if(this.files.length > 0) {
        reader = new FileReader();
        reader.onloadend = function () {
          str += "&" + name + "=" + this.result;
        }
        reader.readAsDataURL(this.files[0]);
      }
    }
  });

在 PropertyEditorSupport 类中,我读取带有 Base64 编码图像的字符串并转换为byte[],只是为了将这些字节存储到文件中:

  byte[] buffer = Base64.decodeBase64(text.split(",")[1]);

  File arquivo;
  try {
    arquivo = new File(file_path+File.separator+file_name()+".jpeg");
  } catch (Exception e) {
    e.printStackTrace();
    arquivo = null;
  }

  File dir = new File(file_path);
  if(!dir.exists())
    dir.mkdirs();
  if(!arquivo.exists())
    try {
      arquivo.createNewFile();
    } catch (Exception e) {
      e.printStackTrace();
    }

  FileOutputStream fileOut;
  try {
    fileOut = new FileOutputStream(arquivo);
  } catch (Exception e) {
    e.printStackTrace();
    fileOut = null;
  }

  try {
    fileOut.write(buffer);
  } catch (Exception e) {
    e.printStackTrace();
  }

  try {
    fileOut.close();
  } catch (Exception e) {
    e.printStackTrace();
  }

但是当我尝试打开生成的图像时,它与我上传的图像不同(我使用命令行工具vbindiff 进行验证,并且图像的标题始终相同)。甚至无法打开生成的图像(我在 Linux/Kubuntu 上使用 Gwenview)。

有人能看出这里有什么问题吗?

【问题讨论】:

  • 这里的缓冲区 new ByteArrayInputStream(buffer) 和这里的缓冲区 byte[] buffer 一样吗?
  • 是的,它是同一个变量。
  • 可以搜索javascript base64 encoding和java base64解码。
  • 虽然添加赏金可能会对您有所帮助,但我认为您可能已经有了答案,如果您只是费心提出一个可重现的问题。告诉您输入已损坏的随机代码和错误消息并没有太大帮助,除非您实际提供导致这些错误的 输入...
  • 要添加另一个选项,只需使用 multipart/form-data 进行文件上传。

标签: java spring spring-mvc filereader propertyeditor


【解决方案1】:

我尝试仅使用 jre 提供一个非常简短的示例。

你只需要将html放在工作目录index.html中,运行服务器并上传示例图片。

这只是示例代码,因此您的应用程序将在某种 servlet 容器上运行,您必须使代码适应您拥有的实际请求和响应对象。

索引页

<html>
<head>
<title>Test file</title>
<script type="text/javascript">
    function sendFile() {
        var file = document.querySelector('input[type=file]').files[0];
        var reader = new FileReader();

        reader.addEventListener("load", function() {
            var http = new XMLHttpRequest();
            var url = "save_file";

            http.open("POST", url, true);
            http.setRequestHeader("Content-type",
                    "application/x-www-form-urlencoded");
            http.onreadystatechange = function() {//Call a function when the state changes.
                if (http.readyState == 4 && http.status == 200) {
                    console.info(http.responseText);
                }
            }
            var header = "base64,";
            var pos=reader.result.indexOf(header);
            var data = reader.result.substring(pos+header.length);
            http.send(data);
        }, false);

        if (file) {
            reader.readAsDataURL(file);
        }
    }
</script>
</head>
<body>
    <input type="file" onchange="sendFile()">
    <br>
</body>
</html>

HTTP 服务器

package so;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.Base64;
import java.util.Scanner;


import com.sun.net.httpserver.*;

public class LoadImage {

    public static void main(String[] args) throws IOException {
         HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
         server.createContext("/save_file",FileSaveHandler());
         server.createContext("/", indexHandler());
         server.start();
         System.out.println("Server started");
         Scanner scanner = new Scanner(System.in);
         scanner.nextLine();
         System.out.println("Server stopped");
         server.stop(0);
    }

    private static HttpHandler indexHandler() {
        return new HttpHandler() {
            @Override
            public void handle(HttpExchange exchange) throws IOException {
                File f = new File("index.html");
                try(OutputStream responseBody = exchange.getResponseBody();InputStream in =  new FileInputStream(f);){
                    byte[] buffer = new byte[(int)f.length()];
                    in.read(buffer);
                    exchange.sendResponseHeaders(200, buffer.length);
                    responseBody.write(buffer);
                }
            }
        };
    }

    private static HttpHandler FileSaveHandler() {
        return new HttpHandler() {

            @Override
            public void handle(HttpExchange exchange) throws IOException {

                try(InputStream in = exchange.getRequestBody();
                    OutputStream out = new FileOutputStream("out.jpg")){

                    byte [] buffer = new byte[3*1024];
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    int l = 0;
                    while((l=in.read(buffer))>=0){
                        bos.write(buffer, 0, l);
                    }
                    byte[] data = Base64.getDecoder().decode(bos.toByteArray());
                    out.write(data);
                }

            }
        };
    }
}

【讨论】:

    猜你喜欢
    • 2012-07-21
    • 1970-01-01
    • 2016-10-21
    • 2017-07-10
    • 1970-01-01
    • 2017-05-21
    • 1970-01-01
    • 1970-01-01
    • 2017-03-15
    相关资源
    最近更新 更多