web-dev-qa-db-fra.com

Comment coder en Base64 un objet Java en utilisant org.Apache.commons.codec.binary.base64?

J'ai essayé de faire une sérialisation d'objet et Base64 encode le résultat. Cela fonctionne avec la bibliothèque de Sun:

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

Cela fonctionne bien. Cependant, je voudrais faire la même chose en utilisant org.Apache.commons.codec.binary.base64, mais cela ne renvoie pas la même chaîne:

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

Quelle serait la bonne façon d'obtenir le codage Base64 correct d'un tableau d'octets en utilisant le codeur d'Apache?

14
Ta Sas

En fait, la version commons-codec Et la version interne spécifique de Sun que vous utilisez do donnent les mêmes résultats. Je pense que vous pensiez qu'ils donnaient des versions différentes parce que vous appelez implicitement toString() sur un tableau lorsque vous le faites:

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

qui n'imprime certainement pas le contenu du tableau. Au lieu de cela, cela n'imprimera que l'adresse de la référence de tableau.

J'ai écrit le programme suivant pour tester les encodeurs les uns contre les autres. Vous verrez sur la sortie ci-dessous que les mêmes résultats:

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));
    }
}

Et voici la sortie d'une série de celui-ci:

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

De page d'accueil du commun-codec :

Le codec a été formé pour tenter de concentrer les efforts de développement sur une implémentation définitive de l'encodeur Base64. Au moment de la proposition de Codec, il y avait environ 34 classes Java Java traitant du codage Base64 réparties sur le référentiel CVS de la Fondation. Les développeurs du projet Jakarta Tomcat avaient implémenté une version originale du codec Base64 qui avait été copié par le sous-projet XML-RPC du projet Commons HttpClient et Apache XML. Après presque un an, les deux versions fourchues de Base64 avaient considérablement divergé l'une de l'autre. XML-RPC avait appliqué de nombreux correctifs et correctifs qui n'étaient pas appliqués au Commons HttpClient Base 64. Différents sous-projets avaient des implémentations différentes à différents niveaux de conformité avec la RFC 2045.

Je pense que votre problème est le "divers niveau" de conformité.

Mon conseil: choisissez un encodeur/décodeur base64 et respectez-le

2
user180100