2017-03-02 98 views
1

在我目前的春天的项目,我有一些input[type=file]场这就需要通过这个PropertyEditorSupport类进行处理的一种形式:转换Base64编码字符串到字节数组

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代码添加到其他PARAMS:

$('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)。

有人可以看到这里有什么问题吗?

+0

这里的缓冲区ByteArrayInputStream的新(缓冲)相同这里的缓冲区的字节[]缓冲区? – reos

+0

是的,它是相同的变量。 –

+0

嗯我建议你使用编码,基本的东西base64。您在客户端编码图像,然后在解码的服务器中编码。 – reos

回答

3

我试图举出一个很简单的例子,只用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); 
       } 

      } 
     }; 
    } 
} 
-1

BASE64Decoder可以解码base64byte[],一样:

import sun.misc.BASE64Decoder; 
BASE64Decoder decoder = new BASE64Decoder(); 
byte[] decoded = decoder.decodeBuffer(imageData); 

同时有Base64编解码器(验证进口)的几个版本:

import org.apache.commons.codec.binary.Base64; 
byte[] decoded = Base64.decodeBase64(str); 

也许下一次请发布可重复码,因为引用类(类似于Base64)只留下机会来推测,而不知道你实际上在谈论什么。

+0

你应该尽量避免使用'sun。*'类。 – glee8e

+0

@ glee8e我实际上提供了两个选择 - 虽然被低估了正确的答案 - 带着一些荒谬的理由,这只不过是一种个人的偏好 - 虽然甚至不能说出为什么......这真是一个笑话。我又在SO的“奇怪的部分”,就像他们在YouTube上一样? –

+0

您确实提供了两个选项,但不应该提及内部类 - 任何看这个答案的新手都可能会使用它,因为它不会引起外部依赖关系,如果他们开始使用Java 9,一定会感到惊讶。这是正是我为什么低调。 “太阳班”应该始终保密,我们应该像巫师把Voldemort称为神秘人一样来提及它。 – glee8e

相关问题