2012-05-24 11 views
11

Próbowałem dokonać serializacji obiektów i Base64 zakodować wynik. Działa z biblioteką Sun:Jak zakodować obiekt Java w Javie przy użyciu org.apache.commons.codec.binary.base64?

Bean01 bean01 = new Bean01(); 
bean01.setDefaultValues(); 
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
new ObjectOutputStream(baos).writeObject(bean01); 
System.out.println(Base64.encode(baos.toByteArray())); 

To działa dobrze. Jednak chciałbym zrobić to samo przy użyciu org.apache.commons.codec.binary.base64, ale to nie zwróci ten sam ciąg:

System.out.println(org.apache.commons.codec.binary.Base64.encodeBase64(baos.toByteArray()));

Jaki byłby poprawny sposób, aby osiągnąć prawidłowe Kodowanie Base64 obiektu byteArray za pomocą kodera Apache?

+0

Która klasa 'Base64' w„lib słońca”Are You używając w swoim pierwszym przykładzie? – QuantumMechanic

+0

com.sun.org.apache.xerces.internal.impl.dv.util.Base64 –

Odpowiedz

22

faktycznie wersji commons-codec i specyficznej Sun wersji wewnętrznej używasz zrobić dają takie same wyniki. Chyba myśleli, że podając różne wersje, ponieważ są niejawnie wywołanie toString() na tablicy kiedy to zrobić:

System.out.println(org.apache.commons.codec.binary.Base64.encodeBase64(baos.toByteArray())); 

który jest zdecydowanie nie wydrukować zawartość tablicy. Zamiast tego wydrukuje tylko adres odwołania do tablicy.

Napisałem następujący program, aby przetestować kodery względem siebie. Zobaczysz z wyjścia poniżej, że dają takie same wyniki:

import java.util.Random; 

public class Base64Stuff 
{ 
    public static void main(String[] args) { 
     Random random = new Random(); 
     byte[] randomBytes = new byte[32]; 
     random.nextBytes(randomBytes); 

     String internalVersion = com.sun.org.apache.xerces.internal.impl.dv.util.Base64.encode(randomBytes); 
     byte[] apacheBytes = org.apache.commons.codec.binary.Base64.encodeBase64(randomBytes); 
     String fromApacheBytes = new String(apacheBytes); 

     System.out.println("Internal length = " + internalVersion.length()); 
     System.out.println("Apache bytes len= " + fromApacheBytes.length()); 
     System.out.println("Internal version = |" + internalVersion + "|"); 
     System.out.println("Apache bytes  = |" + fromApacheBytes + "|"); 
     System.out.println("internal equal apache bytes?: " + internalVersion.equals(fromApacheBytes)); 
    } 
} 

A oto wyjście z przebiegu go:

Internal length = 44 
Apache bytes len= 44 
Internal version = |Kf0JBpbxCfXutxjveYs8CXMsFpQYgkllcHHzJJsz9+g=| 
Apache bytes  = |Kf0JBpbxCfXutxjveYs8CXMsFpQYgkllcHHzJJsz9+g=| 
internal equal apache bytes?: true 
+0

dziękuję - głupi mnie, powinienem to zobaczyć :-D –

2

Od commons-codec home page:

Codec powstał jako próba skoncentrowania wysiłków na rzecz rozwoju na jednym ostatecznego wykonania kodera Base64. W czasie aplikacji Codec istniało około 34 różnych klas Java , które dotyczyły kodowania Base64 rozproszonego w repozytorium CVS Fundacji. Twórcy projektu Jakarta Tomcat zaimplementowali oryginalną wersję kodeka Base64, który został skopiowany przez podprojekt XML-RPC projektu HttpClient i Apache XML z projektu . Po prawie rok, dwie rozwidlone wersje Base64 miały znacząco oddzielone od siebie. XML-RPC zastosował liczne poprawki i łatki , które nie zostały zastosowane do Commons HttpClient Base64. Różne podprojekty nie różniące się implementacje na różnych poziomach zgodności z RFC 2045.

Myślę, że problem jest „różny poziom” zgodności.

Moja rada: wybrać jeden base64 koder/dekoder i trzymać się go

+0

Chciałbym, jestem zadowolony z opcji * słońca * z wyjątkiem jednego kryterium bez zmian: http://www.techiegyan.com/2009/01/11/warning-sunmiscbase64encoder-is-sun-zastrzeżony-api-and-may-be-removed-in-a-future-release/To dlatego muszę się przełączyć, chociaż nie chcę do –

+2

Potrzebują i często potrzebują rozbieżności, ale zawsze trzeba wygrać. –