La conversion d'objets Java en tableaux d'octets est très courant dans les scénarios où la transmission du protocole de communication est utilisée à l'aide de Netty. Par exemple, le protocole a des en-têtes de protocole établis, des classides, des messages et d'autres informations, et un autre contenu clé est la charge utile. Différents contenus de protocole seront placés dans la charge utile, et cette charge utile est souvent un réseau d'octets.
Alors, comment construire commodément un objet Java dans un tableau d'octets?
1 bytebuf remplissage
Donnons un exemple de l'objet suivant:
classe publique UGVDATA implémente Serialisible {private statique final long SerialVersionUID = -219988432063763456l; // État du code d'octet Statut; // Current GPS Longitude Float Longitude; // Current GPS Latitude Float Latitude; // L'unité de vitesse de conduite est M / S, avec une vitesse de flottement point décimal; // Pourcentage de batterie actuel à percussion à batterie courte; // Numéro de tâche Long Quest; octet public [] tobyTearray () {bytebuf buf = nonoled.buffer (32); buf.writeByte (this.getStatus ()); buf.writefloat (getLongitude ()); buf.writeFloat (getLatitude ()); buf.writeFloat (getSpeed ()); buf.writeShort (getbatterypercentage ()); buf.writelong (getQuest ()); return buf.array (); } // omettez être défini}Ensuite, il vous suffit de nouveau de l'objet ci-dessus et d'appeler sa méthode TobyTearray pour convertir cet objet en un tableau d'octets.
2. Utilisez JSON habilement
Nous savons tous que les cordes peuvent être converties en tableaux d'octets. Il est également facile de convertir un objet en une chaîne JSON, utilisez simplement FastJson directement. Si vous avez des problèmes d'utilisation de Fastjson, vous pouvez consulter un autre blog de mon json.parseobject et json.tojSontring instance
JSON.TojSontring (UgvData) .getBytes ()
3 méthode de réflexion
L'inconvénient de la première méthode est que chaque classe doit écrire une méthode Tobytearray comme celle-ci. S'il y a trop de cours, c'est très gênant. Y a-t-il un moyen pratique? Bien sûr, il y en a un, qui utilise la réflexion (il ne reflétera que la première fois, et le cache local sera effectué plus tard, donc les frais généraux de performance ne sont pas grands). Vous devez ajouter les cinq classes suivantes dans un dossier
1. codécable
Importer com.fasterxml.jackson.annotation.jsonignore; import com.google.common.collect.lists; importer lombok.data; import java.lang.reflect.field; import java.util.collections Liste <FieldWrapper> ResololFileLdWrapperList (class Clazz) {field [] fields = cllazz.getDeclaredFields (); List <FieldWrapper> fieldWrapperList = lists.newArrayList (); pour (champ de champ: champs) {CodeCProprety CodeCproprety = field.getAnnotation (CodeCProprety.class); if (codecproprety == null) {continuant; } Fieldwrapper fw = new fieldwrapper (champ, codecproprety); fieldwrapperList.add (FW); } Collection.Sort (FieldWrapperList, nouveau comparateur <FieldWrapper> () {@Override public int compare (fieldwrapper o1, fieldwrapper o2) {return o1.getCodecproprety (). Order () - o2.GetCodeCProprety (). Order ();}}); return fieldWrapperList; } @Jsonignore Liste abstraite publique <FieldWrapper> getFieldWrapperList ();}2.Codecproprety
Importer java.lang.annotation.elementType; import java.lang.annotation.retention; import java.lang.annotation.retentionPolicy; import java.lang.annotation.target; @retention (rétentionpolicy.runtime) @target ({{elementType.field}) public @interfacecpropriy {** * ATTRAT @return * / int order (); / ** * longueur de données. Utilisé pendant le décodage, il ne fonctionne que pour un type de données simple (tel que la chaîne). * @return * / int length () par défaut 0;}3. Fieldwrapper
Importer Lombok.AllargSstructoror; Importer Lombok.Data; Importer Java.lang.reflect.field; @ data @ allargSconstructorPublic Class FieldWrapper {/ ** * Attributs de données de haut en bas * / champ de champ privé; / ** * Annotations sur les attributs de données de haut en bas * / codecproprety privé Codecproprety;}4.Eloaddecoder
Importer io.netty.buffer.bytebuf; import io.netty.buffer.unpooled; importer java.lang.reflect.field; import java.lang.reflect.method; import java.nio.charset.chart; src, class <T> Clazz) {t instance = null; essayez {instance = Clazz.newinstance (); } catch (exception e) {lancer un nouveau runtimeException ("la classe d'instanciation a échoué", e); } List <FieldWrapper> fieldWrapperList = instance.getFieldWrapperList (); ByteBuf Buffer = UNTOOLED.BUFFER (). WriteBytes (SRC); pour (FieldWrapper FieldWrapper: FieldWrapperList) {FillData (FieldWrapper, instance, tampon); } return instance; } private static void fillData (fieldwrapper fieldwrapper, instance d'objet, tampon bytebuf) {field field = fieldwrapper.getField (); field.setAccessible (true); String typename = field.getType (). GetName (); essayez {switch (typename) {case "java.lang.boolean": case "boolean": boolean b = buffer.readboolean (); field.set (instance, b); casser; Case "java.lang.character": cas "char": charasence chardens issue = buffer.readcharsequence (fieldwrapper.getCodecproprety (). length (), charset.forname ("utf-8")); field.set (instance, chardequence); casser; Case "java.lang.byte": cas "octet": octet ": byte b1 = buffer.readbyte (); field.set (instance, b1); casse; case" java.lang.short ": cas" short ": court-lecture = buffer.readshort (); field.seger": case "inserent; case" = Buffer. "java.lang.double": case "Double": Double ReadDouble = Buffer.ReadDouble (); Field.set (instance, readString); Break;5. Téléchargement utile
import io.netty.buffer.bytebuf; import io.netty.buffer.unpooled; import java.lang.reflect.field; import java.lang.reflect.method; import java.nio.charset.chart; {List <FieldWrapper> fieldWrapperList = Command.getFieldWrapperList (); ByteBuf Buffer = UNTOOLED.BUFFER (); fieldwrapperList.ForEach (fieldwrapper -> write2bytebuf (fieldwrapper, commande, tampon)); retour tamper.array (); } / ** * Les données sont écrites à ByteBuf * * @param fieldwrapper * @param instance * @param buffer * / private static void write2bytebuf (fieldwrapper fieldwrapper, objet instance, bytebuf buffer) {field field = fieldwrapper.getField (); String typename = field.getType (). GetName (); field.setAccessible (true); Valeur d'objet = null; try {value = field.get (instance); } catch (illégalaccessException e) {new RuntimeException ("Réflexion n'a pas obtenu de valeur, déposée:" + field.getName (), e); } switch (typename) {case "java.lang.boolean": case "boolean": tampon.writeboolean ((booléen) valeur); casser; cas "java.lang.character": cas "char": tamper.writecharSequence ((chardequence) valeur, charset.forname ("utf-8")); casser; case "java.lang.byte": cas "byte": buffer.writeByte ((byte) value); casser; case "java.lang.short": cas "short": buffer.writeShort (((courte) valeur); casser; case "java.lang.integer": cas "int": buffer.writeInt ((int) value); casser; cas "java.lang.long": cas "long": buffer.writelong ((longue) valeur); casser; case "java.lang.float": case "float": buffer.writefloat ((float) value); casser; case "java.lang.double": cas "double": tampon.writedouble (((double) valeur); casser; Case "java.lang.string": tamper.writecharsequence ((charonsence) value, charset.forname ("utf-8")); casser; Par défaut: lancez un nouveau RuntimeException (typename + "non pris en charge, bug"); }}}Après avoir ajouté les cinq classes ci-dessus, il est également très facile à utiliser. Il vous suffit de convertir DrivestartData en un tableau d'octets comme indiqué ci-dessous.
PayloadEncoder.getPayload (DrivestartData)
4 Résumé
Certaines personnes peuvent demander, les trois types ci-dessus sont évidemment le deuxième type pour convertir JSON est le plus simple, alors pourquoi avez-vous besoin d'utiliser les deux autres?
En fait, les premier et troisième types peuvent être classés dans la même catégorie, tous deux convertissant l'objet directement en un tableau d'octets. Si la couche suivante est analysée, elle peut être prise un par une;
Le deuxième cas consiste à convertir la chaîne JSON de l'objet en un tableau d'octets. Le problème est que le début de la chaîne JSON est "{", c'est-à-dire que le premier chiffre du tableau d'octet converti est "{" correspondant à la valeur de "{"
En usage, il doit être basé sur la situation. Si la couche suivante analyse directement les éléments, utilisez le premier s'il y a moins d'objets; Utilisez le troisième s'il existe de nombreux objets;
Si la couche suivante analyse certains formats de JSON, utilisez le second.
Tout ce qui précède est le contenu complet de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.