A conversão de objetos Java em matrizes de bytes é muito comum em cenários em que a transmissão do protocolo de comunicação é usada usando a Netty. Por exemplo, o protocolo possui alguns cabeçalhos de protocolo estabelecidos, classes, MessageIds e outras informações, e outro conteúdo importante é a carga útil. Diferentes conteúdos de protocolo serão colocados na carga útil, e essa carga geralmente é uma matriz de bytes.
Então, como construir convenientemente um objeto Java em uma matriz de bytes?
1 bytebuf preenchimento
Vamos dar um exemplo do seguinte objeto:
classe pública ugvdata implementa serialisible {private estático final serialversionuid = -219988432063763456l; // status de byte de código de status; // Longitude de longitude GPS atual; // Latitude de latitude GPS atual Latitude; // A unidade de velocidade de acionamento é m/s, com uma velocidade de flutuação de ponto decimal; // porcentagem de bateria atual Esforcada de bateria; // Número da tarefa Longa missão; public byte [] TobyteArray () {bytebuf buf = nãooled.Buffer (32); buf.WriteByte (this.getStatus ()); buf.WriteFloat (getLongitude ()); buf.WriteFloat (getLatitude ()); buf.writefloat (getspeed ()); BUF.WRITESHORT (getBatteryperCentage ()); buf.Writelong (getQuest ()); retornar buf.array (); } // omita se definir}Então você só precisa de novo o objeto acima e chamar seu método TobyTearray para converter esse objeto em uma matriz de bytes.
2. Use JSON habilmente
Todos sabemos que as cordas podem ser convertidas em matrizes de bytes. Também é fácil converter um objeto em uma string json, basta usar o fastjson diretamente. Se você tiver problemas para usar o fastjson, pode conferir outro blog do meu JSON.ParseObject e JSON.TojSoSonstring instância
Json.tojSonstring (ugvdata) .getBytes ()
3 Método de reflexão
A desvantagem do primeiro método é que cada classe deve escrever um método TobyteArray como esse. Se houver muitas aulas, é muito problemático. Existe alguma maneira conveniente? Obviamente, há um, que usa reflexão (ele refletirá apenas a primeira vez, e o cache local será feito posteriormente, para que a sobrecarga de desempenho não seja grande). Você precisa adicionar as cinco a seguir em uma pasta
1.Codecable
importar com.fasterxml.jackson.annotation.jsonignore; importar com.google.common.collect.lists; importar lombok.data; importar java.lang.reflect.field; import java.util.util.Collections; import java.util.comparator; import qava.util.list.List; ResolveFileldWrapperList (classe clazz) {field [] campos = clazz.getDecLaredFields (); List <FieldWrapper> fieldWrapperList = lists.newArrayList (); para (campo de campo: campos) {codecProprety codecProPrety = field.getAnnotation (codecProprety.class); if (codecProPrety == null) {continua; } FieldWrapper FW = new FieldWrapper (campo, codecProPrety); FieldWrapperList.add (FW); } Coleções.sort (FieldWrapperList, novo comparador <FieldWrapper> () {@Override public Int Compare (FieldWrapper O1, FieldWrapper O2) {return o1.getCodecProprety (). Order () - o2.GetCodecProprety (). ();}}); Retornar FieldWrapperList; } @Jsonignore list abstrate2.CodecProprety
importar java.lang.annotation.ElementType; importar java.lang.annotation.retention; importar java.lang.annotation.retionPolicy; importar java.lang.annoTation.Target; @return */ int order (); /*** Comprimento dos dados. Utilizado durante a decodificação, ele funciona apenas, exceto por um tipo de dados simples (como string). * @return */ int length () padrão 0;}
3. FieldWrapper
importar lombok.allargsconstructor; importar lombok.data; importar java.lang.reflect.field;@data@alargsconstructorpublic class FieldWrapper { / *** atributos de dados para cima e para baixo* / campo privado de campo; / *** Anotações nos atributos de dados para cima e para baixo4. PayloadDecoder
importar io.netty.buffer.bytebuf; importar io.netty.buffer.unpooled; importar java.lang.reflect.field; importar java.lang.reflet.method; codsloaddecod.nio.charset.charset; import java.util.List; Classe PayDeardDecod; Resolve (byte [] src, classe <t> clazz) {t instance = null; tente {instance = clazz.newInstance (); } catch (Exceção e) {lança nova RunTimeException ("Classe de instanciação falhou", e); } List <fieldWrapper> fieldWrapperList = instance.getfieldWrapperList (); Buffer bytebuf = nãooled.buffer (). Writebytes (src); para (FieldWrapper FieldWrapper: FieldWrapperList) {FillData (FieldWrapper, Instância, Buffer); } Instância de retorno; } private static void FillData (FieldWrapper FieldWrapper, Instância do Objeto, Buffer Bytebuf) {Field Field = FieldWrapper.getfield (); field.setAccessible (true); String typename = field.getType (). GetName (); tente {switch (typename) {case "java.lang.boolean": case "boolean": boolean b = buffer.readboolean (); field.set (instância, b); quebrar; case "java.lang.Character": case "char": charsequence charsequence = buffer.readcharsequence (fieldWrapper.getCodecProprety (). length (), charset.formoname ("utf-8")); field.set (instância, charquence); quebrar; Caso "java.lang.byte": case "byte": byte ": byte b1 = buffer.readbyte (); field.set (instância, b1); quebra; case" java.lang.short ": case" curto ": short readshort = buffer.readshort (); fieldSet.Set (instance, readshort"; Buffer.readIny); "Java.lang.double": case "duplo": readdouble duplo = buffer.readdouble (); Field.Set (Instância, ReadString);5. PayloadEncoder
importar io.netty.buffer.bytebuf; importar io.netty.buffer.unpooled; importar java.lang.reflect.field; importar java.lang.reflect.method; getPayload (comando t) {list <fieldWrapper> fieldWrapperList = command.getfieldWrapperList (); Buffer bytebuf = nãooled.Buffer (); FieldWrapperList.ForEach (FieldWrapper -> write2ByTeBuf (FieldWrapper, Command, Buffer)); retornar buffer.array (); } / ** * Os dados são gravados em bytebuf * * @param fieldwrapper * @param instância * @param buffer * / private static void write2bytebuf (fieldwrapperwrapper, instância de objeto, buffer bytebuf) {field field = fieldWrapper.getfield (); String typename = field.getType (). GetName (); field.setAccessible (true); Valor do objeto = nulo; tente {value = field.get (instância); } catch (ilegalAccessException e) {new RunTimeException ("A reflexão não conseguiu obter valor, arquivado:" + field.getName (), e); } switch (typename) {case "java.lang.boolean": case "boolean": buffer.writeboolean (((boolean) valor); quebrar; case "java.lang.Character": case "char": buffer.writecharsequence ((Charsequence) Valor, charset.forname ("utf-8")); quebrar; case "java.lang.byte": case "byte": buffer.writebyte ((byte) valor); quebrar; case "java.lang.short": case "curto": buffer.writeShort (((curto) valor); quebrar; case "java.lang.integer": case "int": buffer.writeint ((int) valor); quebrar; case "java.lang.long": case "long": buffer.writelong (((longo) valor); quebrar; case "java.lang.float": case "float": buffer.writefloat (((float) valor); quebrar; case "java.lang.double": case "duplo": buffer.Writedouble ((duplo) valor); quebrar; case "java.lang.string": buffer.writecharsequence (((Charsequence) valor, charset.forname ("utf-8")); quebrar; Padrão: lança a nova RunTimeException (Typename + "não suportado, bug"); }}}Depois de adicionar as cinco classes acima, também é muito fácil de usar. Você só precisa converter o DriveStartData em uma matriz de bytes, como mostrado abaixo.
Payloadncoder.getPayload (driveStartData)
4 Resumo
Algumas pessoas podem perguntar: os três tipos acima são obviamente o segundo tipo a converter JSON é o mais simples, então por que você precisa usar os outros dois?
De fato, o primeiro e o terceiro tipos podem ser classificados na mesma categoria, ambos convertendo o objeto diretamente em uma matriz de bytes. Se a próxima camada for analisada, poderá ser tomada uma a uma;
O segundo caso é converter a sequência JSON do objeto em uma matriz de bytes. O problema é que o início da string json é "{", ou seja, o primeiro dígito da matriz de bytes convertido é "{" correspondente ao valor de "{"
Em uso, deve ser baseado na situação. Se a próxima camada analisar os elementos diretamente, use o primeiro se houver menos objetos; Use o terceiro se houver muitos objetos;
Se a próxima camada analisar alguns formatos de JSON, use o segundo.
Todos os itens acima são todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.