diff --git a/src/main/java/org/redkale/convert/pb/ProtobufCoders.java b/src/main/java/org/redkale/convert/pb/ProtobufCoders.java index 3fcf8a85d..d10281afc 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufCoders.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufCoders.java @@ -4,11 +4,13 @@ */ package org.redkale.convert.pb; +import java.io.Serializable; import java.lang.reflect.Type; import java.math.BigDecimal; import java.math.BigInteger; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.atomic.*; import org.redkale.convert.SimpledCoder; @@ -714,6 +716,77 @@ public abstract class ProtobufCoders { } } + // 只识别类型: Integer/Long/String/BigInteger + public static class ProtobufSerializableSimpledCoder + extends SimpledCoder + implements ProtobufEncodeable { + + public static final ProtobufSerializableSimpledCoder instance = new ProtobufSerializableSimpledCoder(); + + private static final byte STRING = 0; + private static final byte INTEGER = 1; + private static final byte LONG = 2; + private static final byte BIGINTEGER = 3; + private static final byte[] STRINGS = new byte[] {STRING}; + private static final byte[] INTEGERS = new byte[] {INTEGER}; + private static final byte[] LONGS = new byte[] {LONG}; + private static final byte[] BIGINTEGERS = new byte[] {BIGINTEGER}; + + @Override + public void convertTo(ProtobufWriter out, Serializable value) { + ProtobufByteArraySimpledCoder.instance.convertTo(out, formatValue(value)); + } + + @Override + public Serializable convertFrom(ProtobufReader in) { + byte[] bs = ProtobufByteArraySimpledCoder.instance.convertFrom(in); + if (bs == null || bs.length == 0) { + return null; + } + byte type = bs[0]; + if (type == INTEGER) { + return ((bs[1] & 0xff) | ((bs[2] & 0xff) << 8) | ((bs[3] & 0xff) << 16) | ((bs[4] & 0xff) << 24)); + } else if (type == LONG) { + return ((bs[1] & 0xffL) + | ((bs[2] & 0xffL) << 8) + | ((bs[3] & 0xffL) << 16) + | ((bs[4] & 0xffL) << 24) + | ((bs[5] & 0xffL) << 32) + | ((bs[6] & 0xffL) << 40) + | ((bs[7] & 0xffL) << 48) + | ((bs[8] & 0xffL) << 56)); + } else if (type == BIGINTEGER) { + return new BigInteger(bs, 1, bs.length - 1); + } else { + return new String(bs, 1, bs.length - 1, StandardCharsets.UTF_8); + } + } + + @Override + public int computeSize(ProtobufWriter out, int tagSize, Serializable value) { + return ProtobufByteArraySimpledCoder.instance.computeSize(out, tagSize, formatValue(value)); + } + + private byte[] formatValue(Serializable value) { + if (value == null) { + return null; + } else if (value instanceof Integer) { + return Utility.append(INTEGERS, ProtobufWriter.fixed32((Integer) value)); + } else if (value instanceof Long) { + return Utility.append(LONGS, ProtobufWriter.fixed64((Long) value)); + } else if (value instanceof BigInteger) { + return Utility.append(BIGINTEGERS, ((BigInteger) value).toByteArray()); + } else { + return Utility.append(STRINGS, value.toString().getBytes(StandardCharsets.UTF_8)); + } + } + + @Override + public Type getType() { + return Serializable.class; + } + } + // ------------------------------------- boolean[] ------------------------------------- public static class ProtobufBoolArraySimpledCoder extends SimpledCoder implements ProtobufEncodeable { diff --git a/src/main/java/org/redkale/convert/pb/ProtobufFactory.java b/src/main/java/org/redkale/convert/pb/ProtobufFactory.java index 4f5b40e98..5ef0ad2b9 100644 --- a/src/main/java/org/redkale/convert/pb/ProtobufFactory.java +++ b/src/main/java/org/redkale/convert/pb/ProtobufFactory.java @@ -5,6 +5,7 @@ */ package org.redkale.convert.pb; +import java.io.Serializable; import java.lang.reflect.*; import java.math.BigDecimal; import java.math.BigInteger; @@ -84,6 +85,7 @@ public class ProtobufFactory extends ConvertFactory + * 注意: userid类型只能是: Integer/Long/String/BigInteger * * * @@ -746,7 +747,8 @@ public abstract class WebSocket { } /** - * 创建userid, null表示异常, 必须实现该方法 + * 创建userid, null表示异常, 必须实现该方法
+ * 注意: userid类型只能是: Integer/Long/String/BigInteger * * @return userid */ diff --git a/src/main/java/org/redkale/net/http/WebSocketServlet.java b/src/main/java/org/redkale/net/http/WebSocketServlet.java index 8823eb4c1..4ae56a7e4 100644 --- a/src/main/java/org/redkale/net/http/WebSocketServlet.java +++ b/src/main/java/org/redkale/net/http/WebSocketServlet.java @@ -7,6 +7,7 @@ package org.redkale.net.http; import java.io.*; import java.lang.reflect.*; +import java.math.BigInteger; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.CompletionHandler; @@ -354,6 +355,19 @@ public abstract class WebSocketServlet extends HttpServlet implements Resourcabl response.kill(); return; } + if (userid != null + && userid.getClass() != Integer.class + && userid.getClass() != Long.class + && userid.getClass() != String.class + && userid.getClass() != BigInteger.class) { + logger.log( + Level.SEVERE, + "WebSocket userid must be Integer/Long/String/BigInteger type, but " + + userid.getClass().getName()); + response.kill(); + return; + } + Runnable runHandler = () -> { webSocket._userid = userid; if (single && !anyuser) { diff --git a/src/test/java/org/redkale/test/convert/pb/UserTest.java b/src/test/java/org/redkale/test/convert/pb/UserTest.java index 6ba117761..0e7504751 100644 --- a/src/test/java/org/redkale/test/convert/pb/UserTest.java +++ b/src/test/java/org/redkale/test/convert/pb/UserTest.java @@ -4,8 +4,11 @@ */ package org.redkale.test.convert.pb; +import java.io.Serializable; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.redkale.convert.ConvertColumn; +import org.redkale.convert.json.JsonConvert; import org.redkale.convert.pb.ProtobufConvert; /** @@ -17,6 +20,7 @@ public class UserTest { public static void main(String[] args) throws Throwable { UserTest test = new UserTest(); test.run(); + test.run2(); } @Test @@ -29,4 +33,33 @@ public class UserTest { System.out.println(user2); Assertions.assertEquals(user.toString(), user2.toString()); } + + @Test + public void run2() throws Exception { + InnerBean bean = new InnerBean(); + bean.id = 20; + bean.time = 1122334455; + bean.names = new Serializable[] {"aaa", "bbb"}; + byte[] bs = ProtobufConvert.root().convertTo(bean); + InnerBean bean2 = ProtobufConvert.root().convertFrom(InnerBean.class, bs); + System.out.println(bean2); + Assertions.assertEquals(bean.toString(), bean2.toString()); + } + + public static class InnerBean { + + @ConvertColumn(index = 1) + public Serializable id; + + @ConvertColumn(index = 2) + public Serializable[] names; + + @ConvertColumn(index = 3) + public Serializable time; + + @Override + public String toString() { + return JsonConvert.root().convertTo(this); + } + } }