diff --git a/convert.html b/convert.html index 667ab4f98..0150b2d94 100644 --- a/convert.html +++ b/convert.html @@ -69,12 +69,13 @@ resp.setContentType("text/json; charset=UTF-8"); resp.getOutputStream().write(json.getBytes("UTF-8")); } -

      几乎所有的JSON框架提供的接口以String作为返回结果为主,其内在都是以char[]作为JsonWriter的载体。以Gson为例,Gson拼接JSON默认使用的是StringWriter,StringWriter的扩容策略是翻倍。为了方便计算,假设一个对象转换成JSON字符串大小为了10K。Gson在转换过程中产生的临时的char[]的大小: 16 + 32 + 64 + 128 + 256 + 512 + 1K + 2K + 4K + 8K + 16K = 32K, char[]转换成最终的String结果又会产生10K的char[], 最后在response输出时又回产生10K的byte[](方便计算不考虑双字节),也就是说整个对象输出过程中会产生52K的临时数据。而且常见的HTTP服务器(如实现java-servlet规范的服务器)不会把底层的ByteBuffer对象池暴露给上层。所以目前所有使用其他JSON框架输出String数据都会产生5倍于数据体积大小(其他低于1倍扩容策略的框架会产生更多)的垃圾数据。
-       RedKale框架的HTTP服务内置了Convert的JSON接口,避免了这么大量的垃圾数据产生。finishJson方法将HTTP服务的ByteBuffer对象池传给Convert, 使Convert在序列化过程中直接以UTF-8编码方式输出到ByteBuffer里。

+

      几乎所有的JSON框架提供的接口以String作为返回结果为主,其内在都是以char[]作为JsonWriter的载体。以Gson为例,Gson拼接JSON默认使用的是StringWriter,StringWriter的扩容策略是翻倍。为了方便计算,假设一个对象转换成JSON字符串大小为了10K。Gson在转换过程中产生的临时的char[]的大小: 16 + 32 + 64 + 128 + 256 + 512 + 1K + 2K + 4K + 8K + 16K = 32K, char[]转换成最终的String结果又会产生10K的char[], 最后在response输出时又回产生10K的byte[](方便计算不考虑双字节),也就是说整个对象输出过程中会产生52K的临时数据。而且常见的HTTP服务器(如实现java-servlet规范的服务器)不会把底层的ByteBuffer对象池暴露给上层。所以以String为输出结果的JSON方法都会产生5倍于数据体积大小(其他低于1倍扩容策略的框架会产生更多)的垃圾数据。
+       RedKale框架的HTTP服务内置了Convert的JSON接口,避免了大量的垃圾数据产生。RedKale的HTTP是基于AIO(NIO.2)实现且存在ByteBuffer对象池,response的finishJson系列方法将HTTP服务的ByteBuffer对象池传给Convert, 使Convert在序列化过程中直接以UTF-8编码方式输出到ByteBuffer里,输出结束后将ByteBuffer交给对象池回收,从而减少大量构建bye[]、char[]所产生的临时数据。

    protected void execute(HttpRequest req, HttpResponse resp) throws IOException {
         resp.finishJson(record);
     }
- +
+

      Convert 基本用法:

    public class UserRecord {
 
@@ -119,8 +120,30 @@
         user2 = childConvert.convertFrom(UserRecord.class, json);
         System.out.println(childConvert.convertTo(user2)); //应该也是 {"userid":100,"username":"redkalename"}
     }
+

      在RedKale里存在默认的JsonConvert、BsonConvert对象。 只需在所有Service、Servlet中增加依赖注入资源。

+
public class XXXService implements Service {
 
-            

      Convert 支持非空构造函数, 必须在其构造函数加上 @ConstructorProperties 注释,且构造函数必须是public修饰。

+ @Resource + private JsonConvert jsonConvert; + + @Resource + private BsonConvert bsonConvert; +} + +public class XXXServlet extends HttpServlet { + + @Resource + private JsonConvert jsonConvert; + + @Resource + private BsonConvert bsonConvert; + +} +
+
+ +

      Convert 支持非空构造函数。

+

       1. public 的非空构造函数加上 @java.beans.ConstructorProperties 注解:

public class UserRecord {
 
     private int userid;
@@ -148,26 +171,71 @@
         return password;
     }
 }
+

       2. 非public 的非空构造函数类自定义Creator:

+
public class UserRecord {
 
+    private int userid;
+
+    private String username = "";
+
+    private String password = "";
+
+    UserRecord(int userid, String username, String password) {
+        this.userid = userid;
+        this.username = username;
+        this.password = password;
+    }
+
+    public int getUserid() {
+        return userid;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    /**
+     * 无法提供public的构造函数可以自定义Creator方法。
+     * 1) 方法名可以随意。
+     * 2) 方法必须是static。
+     * 3)方法的参数必须为空。
+     * 4)方法的返回类型必须是Creator。
+     *
+     * @return
+     */
+    private static Creator<UserRecord> creator() {
+        return new Creator<UserRecord>() {
+            @Override
+            @Creator.ConstructorParameters({"userid", "username", "password"}) //非空构造函数必须有ConstructorParameters注解
+            public UserRecord create(Object... params) {
+                return new UserRecord((params[0] == null ? 0 : (Integer) params[0]), (String) params[1], (String) params[2]);
+            }
+        };
+    }
+}
+                
+
+

      Convert 支持自定义Decode、Encode。

-

      通过Factory显式的注册:

+

      1. 通过Factory显式的注册:

public class FileSimpleCoder<R extends Reader, W extends Writer> extends SimpledCoder<R, W, File> {
 
     public static final FileSimpleCoder instance = new FileSimpleCoder();
 
-    private static final org.redkale.convert.ext.StringSimpledCoder stringCoder = org.redkale.convert.ext.StringSimpledCoder.instance;
-
     @Override
     public void convertTo(W out, File value) {
-        stringCoder.convertTo(out, value == null ? null : value.getPath());
+        out.writeString(value == null ? null : value.getPath());
     }
 
     @Override
     public File convertFrom(R in) {
-        String path = stringCoder.convertFrom(in);
+        String path = in.readString();
         return path == null ? null : new File(path);
     }
-
 }
 
 JsonFactory.root().register(java.io.File.class, FileSimpleCoder.instance);
@@ -175,7 +243,7 @@
 BsonFactory.root().register(java.io.File.class, FileSimpleCoder.instance);
                 
-

      通过JavaBean类自定义:

+

      2. 通过JavaBean类自定义静态方法自动加载:

public class InnerCoderEntity {
 
     private final String val;
@@ -261,7 +329,8 @@
     }
 }
                 
- +
+

BSON的协议格式

      BSON类似Java自带的Serializable, 其格式如下:
            1). 基本数据类型: 直接转换成byte[]