2017-03-02 101 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

相關問題