Java 객체를 바이트 어레이로 변환하는 것은 Netty를 사용하여 통신 프로토콜 전송을 사용하는 시나리오에서 매우 일반적입니다. 예를 들어, 프로토콜에는 일부 프로토콜 헤더, ClassIds, MessageIds 및 기타 정보가 있으며 다른 주요 컨텐츠에는 페이로드가 있습니다. 다른 프로토콜 내용은 페이로드에 배치 되며이 페이로드는 종종 바이트 어레이입니다.
그렇다면 Java 객체를 바이트 어레이로 편리하게 구성하는 방법은 무엇입니까?
1 바이트 부프 채우기
다음 객체의 예를 들어 봅시다.
공개 클래스 ugvdata는 serialisible {private static final long serialversionuid = -219988432063763456L; // 상태 코드 바이트 상태; // 현재 GPS 경도 플로트 경도; // 현재 GPS 위도 플로트 위도; // 구동 속도 장치는 M/S이며 소수점 플로트 속도; // 현재 배터리 백분율 짧은 배터리 중심; // 작업 번호 긴 퀘스트; public byte [] tobytearray () {bytebuf buf = unp -sooled.buffer (32); buf.writebyte (this.getStatus ()); buf.writefloat (getLongitude ()); buf.writefloat (getLatitude ()); buf.writefloat (getspeed ()); buf.writeshort (getBatteryPerCentage ()); buf.writelong (getquest ()); return buf.array (); } // 생략 get set}그런 다음 위의 개체 중 하나를 새롭게하고 TobyTearRay 메소드를 호출 하여이 객체를 바이트 어레이로 변환하면됩니다.
2. JSON을 능숙하게 사용하십시오
우리는 문자열이 바이트 어레이로 변환 될 수 있음을 알고 있습니다. 객체를 JSON 문자열로 변환하는 것도 쉽습니다. FastJson을 직접 사용하십시오. Fastjson을 사용하는 데 문제가있는 경우 내 json.parseobject 및 json.tojsonstring 인스턴스의 다른 블로그를 확인할 수 있습니다.
json.tojsonstring (ugvdata) .getBytes ()
3 반사 방법
첫 번째 방법의 단점은 각 클래스가 이와 같은 TobyTearRay 메소드를 작성해야한다는 것입니다. 수업이 너무 많으면 매우 번거 롭습니다. 편리한 방법이 있습니까? 물론 반사를 사용하는 것이 있습니다 (처음으로 만 반영되고 로컬 캐시가 나중에 수행되므로 성능 오버 헤드가 크지 않습니다). 폴더에 다음 5 개의 클래스를 추가해야합니다.
1. 복용 가능
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; ResolveFilelDWRAPPERLIST (클래스 Clazz) {field [] fields = clazz.getDeclaredFields (); 목록 <fieldwrapper> fieldWrapperList = lists.newarrayList (); for (필드 필드 : 필드) {codecproprety codecproprety = field.getAnnotation (codecproprety.class); if (codecproprety == null) {계속; } FieldWrapper fw = 새로운 FieldWrapper (Field, CodeCProprety); FieldWrapperList.Add (FW); } collections.sort (FieldWrapperList, 새 비교기 <fieldWrapper> () {@override public int compart (FieldWrapper O1, FieldWrapper O2) {return o1.getCodeCPropreTy (). Order () -GetCodeCPropRety (). Order ();}}); 반환 FieldWrapperList; } @jsonignore public Abstract List <FieldWrapper> getfieldWrapperList ();}2. 코드 프로토리
import java.lang.annotation.elementtype; import java.lang.annotation.retention; import java.lang.annotation.retentionpolicy; import java.lang.annotation.target; @retention (rendentionpolicy.runtime) @target ({ElementType.field}) @interecproprety} @return */ int order (); /*** 데이터 길이. 디코딩 중에 사용되면 간단한 데이터 유형 (예 : 문자열)을 제외하고 만 작동합니다. * @return */ int length () 기본값 0;}3. FieldWrapper
import lombok.allargsconstructor; import lombok.data; import java.lang.reflect.field;@data@allargsconstructorpublic fieldwrapper { / *** Up and Down Data 특성* / 개인 필드 필드; / *** 위아래 데이터 속성에 대한 주석*/ 개인 CodecProprety CodeCProprety;}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 <t rendecte (publeCloaddeCoder) [extend <t extendecled <t extend <t extend <t extend <t rendeT <t extatic. src, class <t> clazz) {t instance = null; try {instance = clazz.newinstance (); } catch (예외 e) {새로운 runtimeexception 던지기 ( "Instantiation Class 실패", e); } list <fieldWrapper> fieldWrapperList = instance.getFieldWrapperList (); BYTEBUF 버퍼 = Unpooled.buffer (). WriteBytes (SRC); for (fieldWraper FieldWrapper : FieldWrapperList) {fillData (FieldWrapper, instance, Buffer); } return 인스턴스; } private static void fillData (FieldWraper FieldWrapper, 객체 인스턴스, BYTEBUF 버퍼) {Field Field = FieldWrapper.getField (); field.setAccessible (true); 문자열 typename = field.getType (). getName (); {switch (typename) {case "java.lang.boolean": Case "boolean": boolean b = buffer.readboolean (); field.set (인스턴스, b); 부서지다; "java.lang.character": CASE "char": charSequence charSequence = buffer.readcharecence (fieldWrapper.getCodeCProprety (). longth (), charset.forname ( "UTF-8")); field.set (instance, charSequence); 부서지다; case "java.lang.byte": case "byte": byte ": byte b1 = buffer.readbyte (); field.set (instance, b1); break; case"java.lang.short ": case"short ": buffer.readshort (); field.set (instase, readshort; break); buffer.set.set "java.lang.double": "double": double readdouble = buffer.set.set (indust, readdouble); field.set (readstring);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; public class <t extend <t extendecled (publicloadencoder) {extend <t extendecle 명령) {list <fieldWrapper> fieldWrapperList = command.getFieldWrapperList (); 바이트 부프 버퍼 = Unpooled.buffer (); fieldWrapperList.FieldERCH (FieldWrapper-> write2bytebuf (FieldWrapper, Command, Buffer)); return buffer.array (); } / ** * 데이터는 bytebuf * * @param fieldwrapper * @param instance * @param buffer * / private static void write2bytebuf (fieldWripers fieldWrapper, 객체 인스턴스, bytebuf buffer) {field = fieldWrapper.getField (); 문자열 typename = field.getType (). getName (); field.setAccessible (true); 객체 값 = null; try {value = field.get (인스턴스); } catch (불법 행위 지출 E e) {새로운 runtimeexception ( "반사가 가치를 얻지 못했습니다." + field.getName (), e); } switch (typename) {case "java.lang.boolean": Case "boolean": buffer.writeboolean ((부울) 값); 부서지다; 사례 "java.lang.character": case "char": buffer.writeCharSequence ((charSedecence) value, charset.forname ( "UTF-8")); 부서지다; "java.lang.byte": case "byte": buffer.writebyte ((byte) 값); 부서지다; "java.lang.short": 사례 "짧은": buffer.writeshort ((짧은) 값); 부서지다; 사례 "java.lang.integer": case "int": buffer.writeint ((int) 값); 부서지다; "java.lang.long": Case "long": buffer.writelong ((long) 값); 부서지다; "java.lang.float": case "float": buffer.writefloat ((float) 값); 부서지다; "java.lang.double": case "double": buffer.writedouble ((double) value); 부서지다; "java.lang.string": buffer.writeCharSequence ((charSequence) value, charset.forname ( "UTF-8")); 부서지다; 기본값 : 새로운 runtimeexception을 던지십시오 (typename + "지원되지 않음, 버그"); }}}위의 5 개 클래스를 추가 한 후에는 사용하기가 매우 쉽습니다. 아래와 같이 driveStartData를 바이트 배열로 만 변환하면됩니다.
Payloadencoder.getPayLoad (driveStartData)
4 요약
어떤 사람들은 위의 세 가지 유형이 분명히 JSON을 변환하는 두 번째 유형이 가장 간단합니다. 왜 다른 두 가지를 사용해야합니까?
실제로, 첫 번째 및 세 번째 유형은 객체를 바이트 배열로 직접 변환하는 동일한 범주로 분류 될 수 있습니다. 다음 층이 구문 분석되면 하나씩 가져갈 수 있습니다.
두 번째 경우는 객체의 JSON 문자열을 바이트 어레이로 변환하는 것입니다. 문제는 JSON 문자열의 시작이 "{"라는 것입니다.
사용 중에는 상황에 따라야합니다. 다음 레이어가 요소를 직접 분석하는 경우 객체가 적은 경우 첫 번째 층을 사용하십시오. 객체가 많으면 세 번째를 사용하십시오.
다음 레이어가 JSON의 일부 형식을 구문 분석하는 경우 두 번째 레이어를 사용하십시오.
위의 모든 내용은이 기사의 전체 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.