diff --git a/xxl-job-core/src/main/java/com/xxl/job/core/util/ByteHexConverter.java b/xxl-job-core/src/main/java/com/xxl/job/core/util/ByteHexConverter.java index 85000317..fbb6936a 100644 --- a/xxl-job-core/src/main/java/com/xxl/job/core/util/ByteHexConverter.java +++ b/xxl-job-core/src/main/java/com/xxl/job/core/util/ByteHexConverter.java @@ -42,7 +42,25 @@ public class ByteHexConverter { public static byte[] radix2byte(String val, int radix){ return new BigInteger(val, radix).toByteArray(); } - + + /** + * get length of string + * @param str + * @return + */ + public static int getByteLen(String str){ + if (str==null || str.length()==0) { + return 0; + } + // because java base on unicode, and one china code's length is one, but it's cost 2 bytes. + int len = str.getBytes().length * 2; + if (len % 4 != 0) { + // Length is best in multiples of four + len = (len/4 + 1) * 4; + } + return len; + } + public static void main(String[] args) { // hex - byte[] 方案A:位移 String temp = "1111111111113d1f3a51sd3f1a32sd1f32as1df2a13sd21f3a2s1df32a13sd2f123s2a3d13fa13sd9999999999"; diff --git a/xxl-job-core/src/main/java/com/xxl/job/core/util/ByteReadFactory.java b/xxl-job-core/src/main/java/com/xxl/job/core/util/ByteReadFactory.java new file mode 100644 index 00000000..f136246b --- /dev/null +++ b/xxl-job-core/src/main/java/com/xxl/job/core/util/ByteReadFactory.java @@ -0,0 +1,98 @@ +package com.xxl.job.core.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; + +/** + * byte read util + * @author xuxueli 2015-11-15 03:50:10 + */ +public class ByteReadFactory { + private static transient Logger logger = LoggerFactory.getLogger(ByteReadFactory.class); + private int m_iPos; + private int m_iReqLen; + private byte[] m_byte = null; + + public ByteReadFactory(byte[] hexBytes){ + m_iPos = 0; + m_byte = hexBytes; + m_iReqLen = m_byte.length; + } + + public int readInt() { + if (m_iPos + 4 > m_iReqLen) { + return 0; + } + int iInt = (m_byte[m_iPos] & 0xff) + | ((m_byte[m_iPos + 1] & 0xff) << 8) + | ((m_byte[m_iPos + 2] & 0xff) << 16) + | ((m_byte[m_iPos + 3] & 0xff) << 24); + m_iPos += 4; + return iInt; + } + + public long readLong() { + if (m_iPos + 8 > m_iReqLen) { + return 0; + } + long iLong = (m_byte[m_iPos] & 0xff) + | ((m_byte[m_iPos + 1] & 0xff) << 8) + | ((m_byte[m_iPos + 2] & 0xff) << 16) + | ((m_byte[m_iPos + 3] & 0xff) << 24) + | ((m_byte[m_iPos + 4] & 0xff) << 32) + | ((m_byte[m_iPos + 5] & 0xff) << 40) + | ((m_byte[m_iPos + 6] & 0xff) << 48) + | ((m_byte[m_iPos + 7] & 0xff) << 56); + m_iPos += 8; + return iLong; + } + + public String readString(int length) { + if (m_iPos + length > m_iReqLen) { + logger.error("[byte stream factory read string length error.]"); + return ""; + } + + int index = 0; + for (index = 0; index < length; index++) { + if (m_byte[m_iPos + index] == 0) { + break; + } + } + String msg = ""; + try { + msg = new String(m_byte, m_iPos, index, "UTF-8"); + } catch (UnsupportedEncodingException e) { + logger.error("[byte stream factory read string exception.]", e); + } + m_iPos += length; + + return msg; + } + + public byte[] read(int length) { + if (m_iPos + length > m_iReqLen || length<=0) { + logger.error("[byte stream factory read string length error.]"); + return null; + } + for (int i = 0; i < length; i++) { + if (m_byte[m_iPos + i] == 0) { + break; + } + } + + byte[] result = new byte[length]; + for (int i = 0; i < length; i++) { + result[i] = m_byte[m_iPos + i]; + } + m_iPos += length; + return result; + } + + public byte[] readByteAll() { + return read(m_iReqLen - m_iPos); + } + +} diff --git a/xxl-job-core/src/main/java/com/xxl/job/core/util/ByteWriteFactory.java b/xxl-job-core/src/main/java/com/xxl/job/core/util/ByteWriteFactory.java new file mode 100644 index 00000000..51cc236a --- /dev/null +++ b/xxl-job-core/src/main/java/com/xxl/job/core/util/ByteWriteFactory.java @@ -0,0 +1,64 @@ +package com.xxl.job.core.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; + +/** + * byte write util + * @author xuxueli 2015-11-15 03:49:36 + */ +public class ByteWriteFactory { + private static transient Logger logger = LoggerFactory.getLogger(ByteWriteFactory.class); + private ByteBuffer m_byteBuf = null; + public ByteWriteFactory() { + m_byteBuf = ByteBuffer.allocate(1024 * 4); + } + + public void writeInt(int intValue) { + byte[] intBytes = new byte[4]; + for (int index = 0; index < 4; index++) { + intBytes[index] = (byte) (intValue >>> (index * 8)); + } + m_byteBuf.put(intBytes); + } + + public void write(int[] intArr) { + for (int index = 0; index < intArr.length; index++) { + writeInt(intArr[index]); + } + } + + public void write(byte[] byteArr) { + m_byteBuf.put(byteArr); + } + + public void writeString(String value, int length) { + byte[] bytes = new byte[length]; + if (value != null && value.trim().length() > 0) { + try { + byte[] infoBytes = value.getBytes("UTF-8"); + int len = infoBytes.length < length ? infoBytes.length : length; + System.arraycopy(infoBytes, 0, bytes, 0, len); + } catch (UnsupportedEncodingException e) { + logger.error("[response stream factory encoding exception.]", e); + } + } + m_byteBuf.put(bytes); + } + + public byte[] getBytes() { + m_byteBuf.flip(); + if (m_byteBuf.limit() == 0) { + return null; + } + + byte[] bytes = new byte[m_byteBuf.limit()]; + m_byteBuf.get(bytes); + + return bytes; + } + +} diff --git a/xxl-job-core/src/main/java/com/xxl/job/core/util/XxlJobNetCommUtil.java b/xxl-job-core/src/main/java/com/xxl/job/core/util/XxlJobNetCommUtil.java index 387e1d0d..7afb3cae 100644 --- a/xxl-job-core/src/main/java/com/xxl/job/core/util/XxlJobNetCommUtil.java +++ b/xxl-job-core/src/main/java/com/xxl/job/core/util/XxlJobNetCommUtil.java @@ -30,14 +30,25 @@ public class XxlJobNetCommUtil { // hex param key public static final String HEX = "hex"; + /** * format object to hex-json * @param obj * @return */ public static String formatObj2HexJson(Object obj){ + // obj to json String json = JacksonUtil.writeValueAsString(obj); - String hex = ByteHexConverter.byte2hex(json.getBytes()); + int len = ByteHexConverter.getByteLen(json); + + // json to byte[] + ByteWriteFactory byteWriteFactory = new ByteWriteFactory(); + byteWriteFactory.writeInt(len); + byteWriteFactory.writeString(json, len); + byte[] bytes = byteWriteFactory.getBytes(); + + // byte to hex + String hex = ByteHexConverter.byte2hex(bytes); return hex; } @@ -48,14 +59,25 @@ public class XxlJobNetCommUtil { * @return */ public static T parseHexJson2Obj(String hex, Class clazz){ - String json = new String(ByteHexConverter.hex2Byte(hex)); + // hex to byte[] + byte[] bytes = ByteHexConverter.hex2Byte(hex); + + // byte[] to json + ByteReadFactory byteReadFactory = new ByteReadFactory(bytes); + String json = byteReadFactory.readString(byteReadFactory.readInt()); + + // json to obj T obj = JacksonUtil.readValue(json, clazz); return obj; } public static void main(String[] args) { - System.out.println(parseHexJson2Obj("7B2274696D657374616D70223A313436393432323136303032362C22616374696F6E223A2252554E222C226A6F6247726F7570223A2264656661756C7473222C226A6F624E616D65223A22323031363037323530393030353730363632222C226578656375746F7248616E646C6572223A2264656D6F4A6F6248616E646C6572222C226578656375746F72506172616D73223A2231303030303030222C22676C7565537769746368223A66616C73652C226C6F6741646472657373223A2231302E35372E3132332E32383A38383838222C226C6F674964223A3138382C226C6F674461746554696D223A302C22737461747573223A2253554343455353222C226D7367223A6E756C6C7D", RequestModel.class)); - System.out.println(parseHexJson2Obj("7B22737461747573223A2253554343455353222C226D7367223A6E756C6C7D", ResponseModel.class)); + RequestModel requestModel = new RequestModel(); + requestModel.setJobGroup("group"); + + String hex = formatObj2HexJson(requestModel); + System.out.println(hex); + System.out.println(parseHexJson2Obj(hex, RequestModel.class)); } /** @@ -94,8 +116,12 @@ public class XxlJobNetCommUtil { EntityUtils.consume(entity); // i do not know why - responseHex = responseHex.replace("\n", ""); - responseHex = responseHex.replace("\r", ""); + //responseHex = responseHex.replace("\n", ""); + //responseHex = responseHex.replace("\r", ""); + + if (responseHex!=null) { + responseHex = responseHex.trim(); + } // parse hex-json to ResponseModel ResponseModel responseModel = XxlJobNetCommUtil.parseHexJson2Obj(responseHex, ResponseModel.class); diff --git a/xxl-job-executor-example/pom.xml b/xxl-job-executor-example/pom.xml index a66cb34c..6901ba7c 100644 --- a/xxl-job-executor-example/pom.xml +++ b/xxl-job-executor-example/pom.xml @@ -101,7 +101,7 @@ maven-war-plugin 2.2 - true + false