Преобразование объектов Java в байтовые массивы очень распространено в сценариях, где передача протокола связи используется с использованием Netty. Например, протокол имеет некоторые установленные заголовки протокола, классики, сообщения и другая информация, а другой ключевой контент - полезная нагрузка. Различное содержание протокола будет помещено в полезную нагрузку, и эта полезная нагрузка часто является байтовым массивом.
Итак, как удобно построить объект Java в массив байтов?
1 Bytebuf Fill
Давайте приведем пример следующего объекта:
Общедоступный класс UGVData реализует Serialisible {Private Static Long Long SerialVersionUID = -219988432063763456L; // Статус байта статуса; // текущая долгота GPS Longitude Longitude; // текущая широта GPS Latitude Latitude; // Блок скорости движения составляет м/с, с скоростью поплавки десятичной точки; // Процент аккумулятора тока короткий аккумулятор; // номер задачи длинный квест; public byte [] tobytearray () {bytebuf buf = unpooled.buffer (32); buf.writebyte (this.getStatus ()); buf.writefloat (getLontuity ()); buf.writefloat (getLatituide ()); buf.writefloat (getspeed ()); buf.writeshort (getbatterypercentage ()); buf.writelong (getquest ()); return buf.array (); } // Опубликовано получить установку}Тогда вам просто нужно подать заявление о вышеуказанном объекте и вызвать его метод TobyTearray, чтобы преобразовать этот объект в массив байтов.
2. Используйте JSON умело
Мы все знаем, что строки могут быть преобразованы в байтовые массивы. Также легко преобразовать объект в строку JSON, просто используйте FastJson напрямую. Если у вас есть проблемы с использованием FastJson, вы можете проверить еще один блог моего json.parseobject и json.tojsonstring ancess
Json.tojsonstring (ugvdata) .getbytes ()
3 Метод отражения
Недостатком первого метода является то, что каждый класс должен писать такой метод TobyTearray, как этот. Если есть слишком много классов, это очень хлопотно. Есть ли удобный способ? Конечно, есть один, который использует отражение (он будет отражать только первый раз, и локальный кэш будет выполнен позже, поэтому накладные расходы на производительность не велика). Вам нужно добавить следующие пять классов в папку
1.codecable
Импорт 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; импорт java.util.list; @datapublic; ResolveFileLdWrapperlist (класс clazz) {field [] fields = clazz.getDeclaredFields (); List <fieldWrapper> FieldWrapperList = lists.newarrayList (); для (поле поле: Fields) {CodecProprety CodecProprety = field.getAnnotation (CodecProprety.class); if (codecproprety == null) {продолжить; } FieldWrapper FW = New FieldWrapper (Field, CodecProprety); FieldWrapperlist.Add (FW); } Collections.sort (FieldWrapperlist, новый компаратор <FieldWrapper> () {@Override public int compare (FieldWrapper O1, FieldWrapper O2) {return o1.getCodecProprety (). Order () - o2.getCodecProprety (). Order ();}}); возврат FieldWrapperlist; } @Jsonignore Public Abstract List <fieldWrapper> getFieldWrapperList ();}2.codecproprety
Импорт java.lang.annotation.elementtype; import java.lang.annotation.retention; импорт java.lang.annotation.retentionpolicy; import java.lang.annotation.target; @retention (streationpolicy.runtime) @Target ({elementType.field}) public @Interfface @Interfface@attlebrety} atriktrop strikprop. @return */ int order (); /*** Длина данных. Используется во время декодирования, он работает только за исключением простого типа данных (например, строки). * @return */ int length () по умолчанию 0;}3. FieldWrapper
импортировать lombok.allargscstructor; import lombok.data; import java.lang.reflect.field;@Data@allargscstrontruppublic class fieldwrapper { / *** up и вниз по атрибутам данных* / частное поле; / *** Аннотация на атрибутах данных вверх и вниз*/ Cdecproprety Codecproprety;}4. PAYLOADDECODER
Импорт io.netty.buffer.bytebuf; import io.netty.buffer.unpooled; импорт java.lang.reflect.field; import java.lang.reflect.method; импорт java.nio.charset.charset; импорт java.util.list; publicaldecoder {public static <t extense <t extense <tete. src, class <t> clazz) {t ancess = null; try {encos = clazz.newinstance (); } catch (Exception e) {бросить новое runtimeexception ("Constantiation Class не удалось", E); } List <fieldWrapper> fieldWrapperlist = exance.getFieldWrapperList (); Bytebuf buffer = unpooled.buffer (). Writebytes (src); для (FieldWrapper FieldWrapper: FieldWrapperlist) {fillData (FieldWrapper, Encement, Buffer); } return Encement; } private static void fillData (FieldWrapper FieldWrapper, экземпляр объекта, буфер bytebuf) {Field Field = FieldWrapper.getField (); Field.SetAccessible (true); String typename = field.gettype (). GetName (); try {switch (typename) {case "java.lang.boolean": case "boolean": boolean b = buffer.readboolean (); field.set (экземпляр, б); перерыв; Дело "java.lang.character": дело "char": charequescence charsecepence = buffer.readcharesecence (fieldwrapper.getCodecproprety (). Length (), charset.forname ("utf-8")); Field.set (exants, charequence); перерыв; Дело "java.lang.byte": case "byte": byte ": byte b1 = buffer.readbyte (); field.set (экземпляр, b1); break; case" java.lang.short ": case" short ": short readshort = buffer.readshort (); field.set (exactshort); break"; Buffer.readint (); "java.lang.double": Case "Double": Double Readdouble = buffer.readdouble (); Field.set (exantshystring);5. PayLoadEncoder
импорт io.netty.buffer.bytebuf; import io.netty.buffer.unpooled; импорт java.lang.reflect.field; import java.lang.reflect.method; импорт java.nio.charset.charset; import java.util.list; public payloadenc Команда) {list <fieldWrapper> fieldWrapperlist = command.getFieldWrapperList (); Bytebuf buffer = unpooled.buffer (); FieldWrapperlist.foreach (FieldWrapper -> write2bytebuf (FieldWrapper, Command, Buffer)); return buffer.array (); } / ** * Данные записываются в bytebuf * * @param fieldwrapper * @param ancement * @param buffer * / private static void write2bytebuf (fieldwrapper fieldwrapper, экземпляр объекта, буфер bytebuf) {field field = fieldWrapper.getfield (); String typename = field.gettype (). GetName (); Field.SetAccessible (true); Значение объекта = null; try {value = field.get (exante); } catch (allogalAccessException e) {new Runtimeexception («Отражение не удалось получить значение, подано:« + field.getName (), e); } switch (typename) {case "java.lang.boolean": case "boolean": buffer.writeboolean ((boolean) значение); перерыв; Дело "java.lang.character": case "char": buffer.writechar sequestence ((charsequence), charset.forname ("utf-8")); перерыв; case "java.lang.byte": case "byte": buffer.writebyte ((byte) значение); перерыв; case "java.lang.short": case "short": buffer.writeshort ((короткий) значение); перерыв; case "java.lang.integer": case "int": buffer.writeint ((int) значение); перерыв; case "java.lang.long": case "long": buffer.writelong ((long) значение); перерыв; case "java.lang.float": case "float": buffer.writefloat ((float)); перерыв; case "java.lang.double": case "Double": buffer.writedouble ((двойной) значение); перерыв; Дело "java.lang.string": buffer.writechar sequestence (((charsequence), charset.forname ("utf-8")); перерыв; по умолчанию: бросить новое runtimeexception (typename + «не поддерживается, ошибка»); }}}После добавления вышеупомянутых пять классов это также очень просты в использовании. Вам нужно только преобразовать DrivestartData в массив байтов, как показано ниже.
Payloadencoder.getPayload (rivestartData)
4 Резюме
Некоторые люди могут спросить, что вышеупомянутые три типа, очевидно, являются вторым типом, чтобы преобразовать JSON - самый простой, так зачем вам использовать два других?
Фактически, первые и третьи типы могут быть классифицированы в одну и ту же категорию, оба преобразуют объект непосредственно в массив байтов. Если следующий слой проанализирован, он может быть взят один за другим;
Второй случай состоит в том, чтобы преобразовать строку JSON объекта в байтовый массив. Проблема в том, что начало строки JSON является «{», то есть первой цифрой преобразованной байтовой массивы является «{», соответствующая значению «{»
В использовании это должно основываться на ситуации. Если следующий слой анализирует элементы напрямую, используйте первый, если меньше объектов; Используйте третий, если есть много объектов;
Если следующий слой разрабатывает некоторые форматы JSON, используйте второй.
Все вышеперечисленное - все содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.