J'aime encoder une carte Java de chaînes comme une seule chaîne codée de base 64. La chaîne codée sera transmise à un point d'extrémité distant et peut-être manipulé par une personne non agréable. Donc, la pire chose qui devrait arriver est la clé de l'invadio, des tuples de valeur, mais ne devrait pas apporter d'autres risques de sécurité de côté.
Exemple: p> oui, doit être base64. Pas comme ça ou que ou tout autre ces . Existe-t-il une solution légère existante (classe Utils simples préférée) là-bas? Ou dois-je créer le mien? P> rien de mieux que cela? P> // marshalling
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(map);
oos.close();
String encoded = new String(Base64.encodeBase64(baos.toByteArray()));
// unmarshalling
byte[] decoded = Base64.decodeBase64(encoded.getBytes());
ByteArrayInputStream bais = new ByteArrayInputStream(decoded);
ObjectInputStream ois = new ObjectInputStream(bais);
map = (Map<String,String>) ois.readObject();
ois.close();
3 Réponses :
Votre solution fonctionne. La seule autre approche serait de sérialiser vous-même la carte (itérer sur les clés et les valeurs). Cela signifierait que vous devriez vous assurer de gérer toutes les cas correctement (par exemple, si vous transmettez les valeurs comme clé Dans l'ensemble, il est difficile de bien avoir raison, facile de se tromper et de prendre beaucoup plus de code et de mal de tête. De plus, n'oubliez pas que vous devriez écrire beaucoup de code de manutention d'erreur dans l'analyseur (côté récepteur). P> = valeur code>, vous devez trouver un moyen d'autoriser
= Code> Dans la clé / valeur et vous devez séparer les paires, ce qui signifie que vous devez également permettre ce caractère de séparation dans le nom, etc.). P>
Une autre manière possible utiliserait JSON qui est une LIGTHWeight LIG.
Le codage ressemblerait alors à ceci:
Mes exigences principales sont les suivantes: la chaîne codée doit être aussi courte que possible et contenir uniquement des caractères latins ou des caractères de l'alphabet de base64 (pas mon appel). Il n'y a pas d'autre requête. em> p>
Utilisez Google gson pour convertir la carte
code> à JSON . Utilisez
gzipoutputtream code> A> Pour compresser la chaîne JSON. Utilisez CODEC Apache Commons CODEC
BASE64 CODE >
oubase64OutputStream
Pour encoder les octets compressés à une chaîne de base64. p>Exemple de coup d'envoi: P>
public static void main(String[] args) throws IOException { Map<String, String> map = new HashMap<String, String>(); map.put("key1", "value1"); map.put("key2", "value2"); map.put("key3", "value3"); String serialized = serialize(map); Map<String, String> deserialized = deserialize(serialized, new TypeToken<Map<String, String>>() {}.getType()); System.out.println(deserialized); } public static String serialize(Object object) throws IOException { ByteArrayOutputStream byteaOut = new ByteArrayOutputStream(); GZIPOutputStream gzipOut = null; try { gzipOut = new GZIPOutputStream(new Base64OutputStream(byteaOut)); gzipOut.write(new Gson().toJson(object).getBytes("UTF-8")); } finally { if (gzipOut != null) try { gzipOut.close(); } catch (IOException logOrIgnore) {} } return new String(byteaOut.toByteArray()); } public static <T> T deserialize(String string, Type type) throws IOException { ByteArrayOutputStream byteaOut = new ByteArrayOutputStream(); GZIPInputStream gzipIn = null; try { gzipIn = new GZIPInputStream(new Base64InputStream(new ByteArrayInputStream(string.getBytes("UTF-8")))); for (int data; (data = gzipIn.read()) > -1;) { byteaOut.write(data); } } finally { if (gzipIn != null) try { gzipIn.close(); } catch (IOException logOrIgnore) {} } return new Gson().fromJson(new String(byteaOut.toByteArray()), type); }
J'aime votre solution parce que son court, travaillant, efficace, sécurisé et final, mais surtout la chaîne codée est également comprise par des applications non Java.
JSON, GZIP et BASE64 sont des normes globales et appuyées dans pratiquement toutes les langues (Java, C #, PHP, etc.). Java Serialization Comme vous l'avez montré (ObjectInput / OutputStream) n'est prise en charge que dans Java.
Ouais, je sais, c'est pourquoi j'ai dit "aussi comprise par des applications non-Java" ;-) Bon travail!
Oh je vois, j'ai mal interprété votre commentaire. Désolé pour ça :) content que cela vous ait aidé.
Je sais que c'est un peu tard, mais j'utilise ces deux méthodes depuis quelque temps maintenant, ils fonctionnent bien jusqu'à ce que je rencontre des personnages japonais: / Je pensais que UTF-8 fera le travail mais je ne sais pas maintenant comment réparer cette. La désérialisation va en douceur, sauf que les personnages japonais deviennent des ordures. S'il vous plaît aider.
Quelle est l'exigence fonctionnelle? C'est à dire. De quoi avez-vous besoin pour cela? Ce n'est qu'alors que nous pouvons juger de la meilleure approche.
Mes principales exigences sont les suivantes: la chaîne codée doit être aussi courte que possible et ne contenir que des caractères latins ou des caractères de l'alphabet de base64 (pas mon appel). Il n'y a pas d'autre requête.