La conversión de objetos Java en matrices de bytes es muy común en escenarios en los que se usa la transmisión del protocolo de comunicación usando Netty. Por ejemplo, el protocolo tiene algunos encabezados de protocolo establecidos, classids, mensajes y otra información, y otro contenido clave es la carga útil. Se colocarán diferentes contenidos de protocolo en la carga útil, y esta carga útil es a menudo una matriz de bytes.
Entonces, ¿cómo construir convenientemente un objeto Java en una matriz de bytes?
1 bytebuf relleno
Demos un ejemplo del siguiente objeto:
La clase pública UGVDATA implementa serialisible {privado estático final Long SerialVersionUid = -219988432063763456l; // Estado de byte de código de estado; // Longitud de flotación de longitud GPS actual; // Latitud flotante de latitud GPS actual; // La unidad de velocidad de conducción es m/s, con una velocidad de flotación de punto decimal; // porcentaje de batería actual de batería de porcentaje de batería; // Número de tarea Long Quest; public byte [] tobytearray () {bytebuf buf = nopoled.buffer (32); buf.writyte (this.getStatus ()); buf.writefloat (getLongitude ()); buf.writefloat (getLatitude ()); buf.writefloat (getSpeed ()); buf.Writeshort (getBatteryParcentage ()); buf.writelong (getQuest ()); return buf.array (); } // omitir Get Set}Entonces solo necesita nuevo el objeto anterior y llamar a su método TobyTearray para convertir este objeto en una matriz de bytes.
2. Usa JSON Hábilmente
Todos sabemos que las cadenas se pueden convertir en matrices de bytes. También es fácil convertir un objeto en una cadena JSON, solo use FastJson directamente. Si tiene problemas para usar FastJson, puede ver otro blog de mi instancia de Json.ParseObject y Json.tojSonstring
Json.tojsonstring (ugvdata) .getBytes ()
3 Método de reflexión
La desventaja del primer método es que cada clase debe escribir un método TobyTearray como este. Si hay demasiadas clases, es muy problemático. ¿Hay alguna manera conveniente? Por supuesto, hay uno, que usa la reflexión (solo reflejará la primera vez, y el caché local se realizará más adelante, por lo que la sobrecarga de rendimiento no es grande). Necesita agregar las siguientes cinco clases en una carpeta
1.Codecible
import com.fasterxml.jackson.annotation.jsonignore; import com.google.common.collect.lists; import lombok.data; import java.lang.reflect.field; import java.util.collections; import java.util.comparator; import java.util.list; @DataPublics Abstract ClassCableable {CodeCable de clase pública {Field.comparator; resolveFilelDwraPperList (class Clazz) {Field [] Fields = Clazz.GetDeclaredFields (); List <fieldwrapper> fieldwrapperlist = lists.newarrayList (); for (campo campo: campos) {CodeCproprety CodeCproprety = Field.getAnnotation (CodeCproprety.class); if (codeCproprety == null) {continuar; } Fieldwrapper fw = new FieldWrapper (Field, CodeCproprety); FieldWrapperList.Add (FW); } Colección.sort (FieldWrapperList, New Comparator <fieldWrapper> () {@Override public int Compare (FieldWrapper O1, FieldWrapper O2) {return o1.getCodeCproprety (). Order () - O2.getCodeCpropety (). Order ();}); return FieldWrapperList; } @Jsonignore Public Abstract List <FieldWrapper> GetFieldWrapperList ();}2.Codecroprety
import java.lang.annotation.ElementType; import java.lang.annotation.retention; import java.lang.annotation.retentionPolicy; import java.lang.annotation.target; @Retention (retentionPolicy.runtime) @Target ({elementType.field}) public @interfaceface CodePRety Codey* @return */ int orden (); /*** Longitud de datos. Utilizado durante la decodificación, solo funciona, excepto por un tipo de datos simple (como la cadena). * @return */ int long () predeterminado 0;}3. FieldWrapper
import lombok.alLargSconstructor; import lombok.data; import java.lang.reflect.field;@data@AllargSconstructorPublic FieldWrapper { / *** Atributos de datos up andraen* / campo de campo privado; / *** Anotaciones en los atributos de datos hacia arriba y hacia abajo*/ Private CodeCproprety CodeCpropety;}4. PayloadDecoder
import io.netty.buffer.bytebuf; import io.netty.buffer.unpooled; import java.lang.reflect.field; import java.lang.reflect.method; import java.nio.charset.charset; import java.util.list; public class PayloadDeCoder {Public Static <T Extends Codends; src, class <t> clazz) {t instance = null; intente {instancia = clazz.newinstance (); } catch (Exception e) {Throw New RuntimeException ("Falló la clase de instanciación", e); } List <fieldwrapper> fieldwrapperlist = instancia.getfieldwrapperlist (); Bytebuf buffer = Unpooled.Buffer (). WriteBytes (SRC); for (FieldWrapper FieldWrapper: FieldWrapperSist) {FillData (FieldWrapper, instancia, buffer); } instancia de retorno; } private static void fillData (FieldWrapper FieldWrapper, instancia de objeto, ByteBuf Buffer) {Field Field = FieldWrapper.GetField (); campo.setAccessible (verdadero); Cadena typename = field.gettype (). GetName (); intente {switch (typename) {case "java.lang.boolean": case "boolean": boolean b = buffer.readBoolean (); campo.set (instancia, b); romper; Caso "java.lang.character": caso "char": charsequence charsequence = buffer.readCharSequence (fieldwrapper.getCodeCproprety (). longitud (), charset.forname ("utf-8")); campo.set (instancia, charsecuencia); romper; case "java.lang.Byte": case "byte": byte": byte b1 = buffer.readByte(); field.set(instance, b1); break; case "java.lang.Short": case "short": short readShort = buffer.readShort(); field.set(instance, readShort); break; case "java.lang.Integer": case "int": int readInt = buffer.read (); "Java.lang.Double": Case "Double": Double ReadDouble = Buffer.readDouble (); Field.set (instancia, lectura);5. PayloadEncoder
import io.netty.buffer.bytebuf; import io.netty.buffer.unpooled; import java.lang.reflect.field; import java.lang.reflect.method; import java.nio.charset.charset; import java.util.list.lists de clase pública {public static <T Extends BodeSable; comando) {list <fieldwrapper> fieldwrapperlist = command.getFieldWrapperSist (); Bytebuf buffer = Unpooled.Buffer (); FieldWrapperList.ForEach (FieldWrapper -> Write2ByteBuf (FieldWrapper, comando, buffer)); return buffer.Array (); } / ** * Los datos se escriben en ByteBuf * * @param FieldWrapper * @param instancia * @param buffer * / private static void write2byteBuf (FieldWrapper FieldWrapper, instancia de objeto, byteBuf Buffer) {field = fieldwrapper.getField (); Cadena typename = field.gettype (). GetName (); campo.setAccessible (verdadero); Valor de objeto = nulo; intente {value = field.get (instancia); } Catch (ilegalAccessException e) {new RuntimeException ("La reflexión no pudo obtener valor, archivado:" + field.getName (), e); } switch (typename) {case "java.lang.boolean": case "boolean": buffer.writeboolean ((boolean) valor); romper; Caso "Java.lang.Character": Case "char": buffer.writecharSequence ((CharSequence) Value, Charset.forname ("UTF-8")); romper; caso "java.lang.byte": caso "byte": buffer.writyte ((byte) valor); romper; caso "java.lang.short": caso "corto": buffer.writeshort ((corto) valor); romper; caso "java.lang.integer": caso "int": buffer.writeInt ((int) valor); romper; caso "java.lang.long": caso "largo": buffer.writelong ((largo) valor); romper; caso "java.lang.float": caso "flotante": buffer.writefloat ((float) valor); romper; caso "java.lang.double": caso "double": buffer.writeDouble ((doble) valor); romper; caso "java.lang.string": buffer.writeCharSequence ((CharSequence) Value, Charset.forname ("UTF-8")); romper; predeterminado: tirar nueva runtimeException (typename + "no compatible, error"); }}}Después de agregar las cinco clases anteriores, también es muy fácil de usar. Solo necesita convertir DrivStartData en una matriz de bytes como se muestra a continuación.
PayloadEncoder.getPayLoad (DrivStartData)
4 Resumen
Algunas personas pueden preguntar, los tres tipos anteriores son obviamente el segundo tipo para convertir JSON es el más simple, entonces, ¿por qué necesita usar los otros dos?
De hecho, el primer y el tercer tipos se pueden clasificar en la misma categoría, ambas convirtiendo el objeto directamente en una matriz de bytes. Si se analiza la siguiente capa, se puede tomar una por una;
El segundo caso es convertir la cadena JSON del objeto en una matriz de bytes. El problema es que el comienzo de la cadena JSON es "{", es decir, el primer dígito de la matriz de bytes convertido es "{" correspondiente al valor de "{"
En uso, debe basarse en la situación. Si la siguiente capa analiza los elementos directamente, use el primero si hay menos objetos; Use el tercero si hay muchos objetos;
Si la siguiente capa analiza algunos formatos de JSON, use el segundo.
Todo lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.