TLVObjectDecoder extends AbstractTLVDecoder<Object> { @SuppressWarnings("unchecked") @Override public Object codec(byte[] source, Object targetClass) { if (null == source || null == targetClass) throw new NullPointerException("source is null or targetObject is null."); if (!(targetClass instanceof Class<?>)) throw new IllegalArgumentException("targetClass must be type of class."); final Map<Integer, Field> fieldMap = new HashMap<Integer, Field>(); Class<?> targetClazz = (Class<?>) targetClass; ReflectUtils.findFields(targetClazz, new ReflectUtils.FieldFilter() { @Override public boolean accept(final Field filed) { TLVAttribute tlvAttr = filed.getAnnotation(TLVAttribute.class); if (null != tlvAttr && tlvAttr.tag() != 0) { if (!filed.isAccessible()) filed.setAccessible(true); fieldMap.put(tlvAttr.tag(), filed); } return false; } }); Object targetObject = null; try { targetObject = targetClazz.newInstance(); } catch (InstantiationException e1) { LOGGER.error("codec:", e1); return targetObject; } catch (IllegalAccessException e1) { LOGGER.error("codec:", e1); return targetObject; } NumberCodec nc = NumberCodecFactory.fetchNumberCodec(decoderProvider.getByteOrder()); ByteArrayInputStream bis = new ByteArrayInputStream(source); do { TLVConfig tlvConfig = decoderProvider.getTlvConfig(); byte[] tmp = new byte[tlvConfig.getTagLen()]; int readLen = 0; try { readLen = bis.read(tmp); } catch (IOException e) { LOGGER.error("codec:", e); } if (readLen != tlvConfig.getTagLen()) break; int tag = nc.bytes2Int(tmp, tlvConfig.getTagLen()); tmp = new byte[tlvConfig.getLengthLen()]; readLen = 0; try { readLen = bis.read(tmp); } catch (IOException e) { LOGGER.error("codec:", e); } if (readLen != tlvConfig.getLengthLen()) break; int len = nc.bytes2Int(tmp, tlvConfig.getTagLen()); if (len > bis.available()) { if (null != illegalTLVContentHandler) { illegalTLVContentHandler.handle(source); } throw new RuntimeException("Tag:" + tag + " illegal length:" + len); } tmp = new byte[len]; readLen = 0; try { readLen = bis.read(tmp); } catch (IOException e) { LOGGER.error("codec:", e); } if (readLen != len) break; Field f = fieldMap.get(tag); if(null == f){ if(LOGGER.isDebugEnabled()) LOGGER.debug("tag value " + tag + " can not match any field in " + targetClazz + ",ignore."); continue; } Class<?> fieldClass = f.getType(); TLVDecoder genericDecoder = decoderProvider.lookupCodec(fieldClass); Object fieldValue = null; if (fieldClass.isArray()) fieldValue = genericDecoder.codec(tmp, fieldClass.getComponentType()); else { TLVAttribute tlvAttr = f.getAnnotation(TLVAttribute.class); String propertyName = tlvAttr.propertyName(); if (propertyName.length() > 0) { fieldValue = createObjectWithProperty(tmp, propertyName, fieldClass); } else { fieldValue = genericDecoder.codec(tmp, fieldClass); } } try { f.set(targetObject, fieldValue); } catch (IllegalArgumentException e) { LOGGER.error("codec", e); return targetObject; } catch (IllegalAccessException e) { LOGGER.error("codec", e); return targetObject; } } while (true); return targetObject; }  @SuppressWarnings("unchecked") @Override Object codec(byte[] source, Object targetClass); @Override String[] getCodecKeyes(); @Override TLVDecoderProvider getCodecProvider(); @Override void setCodecProvider(TLVDecoderProvider codecPrivoder); void setDecoderProvider(TLVDecoderProvider decoderProvider); @Override boolean isObjectDecoder();  }
@Test public void test() { TLVEncoder<Object> tlvEncoder = TLVCodecProviders.newBigEndianTLVEncoderProvider() .getObjectEncoder(); TLVDecoder<Object> tlvDecoder = TLVCodecProviders.newBigEndianTLVDecoderProvider() .getObjectDecoder(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { bos.write(new byte[] { (byte) 0, (byte) 0, (byte) 0, (byte) 1 }); } catch (IOException e) { e.printStackTrace(); } try { bos.write(new byte[] { (byte) 0, (byte) 0, (byte) 0, (byte) 100 }); } catch (IOException e) { e.printStackTrace(); } try { bos.write(new byte[] { (byte) 3 }); } catch (IOException e) { e.printStackTrace(); } try { tlvDecoder.codec(bos.toByteArray(), Bean1.class); assertTrue(false); } catch (RuntimeException e) { e.printStackTrace(); assertTrue(true); } bos = new ByteArrayOutputStream(); try { bos.write(new byte[] { (byte) 0, (byte) 0, (byte) 0, (byte) 1 }); } catch (IOException e) { e.printStackTrace(); } try { bos.write(new byte[] { (byte) 0, (byte) 0, (byte) 0, (byte) 4 }); } catch (IOException e) { e.printStackTrace(); } try { bos.write(new byte[] { 'a', 'b', 'c', 'd' }); } catch (IOException e) { e.printStackTrace(); } Bean1 b = (Bean1) tlvDecoder.codec(bos.toByteArray(), Bean1.class); assertEquals("abcd", b.getV()); }