ConvertFactory增加nullable配置
This commit is contained in:
@@ -60,7 +60,9 @@ public final class ApiDocCommand {
|
|||||||
|
|
||||||
if (params != null && params.length > 0) {
|
if (params != null && params.length > 0) {
|
||||||
for (String param : params) {
|
for (String param : params) {
|
||||||
if (param == null) continue;
|
if (param == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
param = param.toLowerCase();
|
param = param.toLowerCase();
|
||||||
if (param.startsWith("--api-skiprpc=")) {
|
if (param.startsWith("--api-skiprpc=")) {
|
||||||
skipRPC = "true".equalsIgnoreCase(param.substring("--api-skiprpc=".length()));
|
skipRPC = "true".equalsIgnoreCase(param.substring("--api-skiprpc=".length()));
|
||||||
@@ -80,7 +82,9 @@ public final class ApiDocCommand {
|
|||||||
List<Map> swaggerTags = new ArrayList<>();
|
List<Map> swaggerTags = new ArrayList<>();
|
||||||
Map<String, Map<String, Object>> swaggerComponentsMap = new LinkedHashMap<>();
|
Map<String, Map<String, Object>> swaggerComponentsMap = new LinkedHashMap<>();
|
||||||
for (NodeServer node : app.servers) {
|
for (NodeServer node : app.servers) {
|
||||||
if (!(node instanceof NodeHttpServer)) continue;
|
if (!(node instanceof NodeHttpServer)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
final Map<String, Object> map = new LinkedHashMap<>();
|
final Map<String, Object> map = new LinkedHashMap<>();
|
||||||
serverList.add(map);
|
serverList.add(map);
|
||||||
HttpServer server = node.getServer();
|
HttpServer server = node.getServer();
|
||||||
@@ -89,12 +93,20 @@ public final class ApiDocCommand {
|
|||||||
List<Map<String, Object>> servletsList = new ArrayList<>();
|
List<Map<String, Object>> servletsList = new ArrayList<>();
|
||||||
map.put("servlets", servletsList);
|
map.put("servlets", servletsList);
|
||||||
String plainContentType = server.getResponseConfig() == null ? "application/json" : server.getResponseConfig().plainContentType;
|
String plainContentType = server.getResponseConfig() == null ? "application/json" : server.getResponseConfig().plainContentType;
|
||||||
if (plainContentType == null || plainContentType.isEmpty()) plainContentType = "application/json";
|
if (plainContentType == null || plainContentType.isEmpty()) {
|
||||||
if (plainContentType.indexOf(';') > 0) plainContentType = plainContentType.substring(0, plainContentType.indexOf(';'));
|
plainContentType = "application/json";
|
||||||
|
}
|
||||||
|
if (plainContentType.indexOf(';') > 0) {
|
||||||
|
plainContentType = plainContentType.substring(0, plainContentType.indexOf(';'));
|
||||||
|
}
|
||||||
|
|
||||||
for (HttpServlet servlet : server.getDispatcherServlet().getServlets()) {
|
for (HttpServlet servlet : server.getDispatcherServlet().getServlets()) {
|
||||||
if (!(servlet instanceof HttpServlet)) continue;
|
if (!(servlet instanceof HttpServlet)) {
|
||||||
if (servlet instanceof WebSocketServlet) continue;
|
continue;
|
||||||
|
}
|
||||||
|
if (servlet instanceof WebSocketServlet) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (servlet.getClass().getAnnotation(MessageMultiConsumer.class) != null) {
|
if (servlet.getClass().getAnnotation(MessageMultiConsumer.class) != null) {
|
||||||
node.logger.log(Level.INFO, servlet + " be skipped because has @MessageMultiConsumer");
|
node.logger.log(Level.INFO, servlet + " be skipped because has @MessageMultiConsumer");
|
||||||
continue;
|
continue;
|
||||||
@@ -128,16 +140,29 @@ public final class ApiDocCommand {
|
|||||||
Class clz = servlet.getClass();
|
Class clz = servlet.getClass();
|
||||||
HashSet<String> actionUrls = new HashSet<>();
|
HashSet<String> actionUrls = new HashSet<>();
|
||||||
do {
|
do {
|
||||||
if (Modifier.isAbstract(clz.getModifiers())) break;
|
if (Modifier.isAbstract(clz.getModifiers())) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
for (Method method : clz.getMethods()) {
|
for (Method method : clz.getMethods()) {
|
||||||
if (method.getParameterCount() != 2) continue;
|
if (method.getParameterCount() != 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
HttpMapping action = method.getAnnotation(HttpMapping.class);
|
HttpMapping action = method.getAnnotation(HttpMapping.class);
|
||||||
if (action == null) continue;
|
if (action == null) {
|
||||||
if (!action.inherited() && selfClz != clz) continue; //忽略不被继承的方法
|
continue;
|
||||||
if (actionUrls.contains(action.url())) continue;
|
}
|
||||||
if (HttpScope.class.isAssignableFrom(action.result())) continue; //忽略模板引擎的方法
|
if (!action.inherited() && selfClz != clz) {
|
||||||
if (action.rpconly() && skipRPC) continue; //不生成RPC接口
|
continue; //忽略不被继承的方法
|
||||||
|
}
|
||||||
|
if (actionUrls.contains(action.url())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (HttpScope.class.isAssignableFrom(action.result())) {
|
||||||
|
continue; //忽略模板引擎的方法
|
||||||
|
}
|
||||||
|
if (action.rpconly() && skipRPC) {
|
||||||
|
continue; //不生成RPC接口
|
||||||
|
}
|
||||||
final List<Map<String, Object>> swaggerParamsList = new ArrayList<>();
|
final List<Map<String, Object>> swaggerParamsList = new ArrayList<>();
|
||||||
|
|
||||||
final Map<String, Object> mappingMap = new LinkedHashMap<>();
|
final Map<String, Object> mappingMap = new LinkedHashMap<>();
|
||||||
@@ -241,20 +266,36 @@ public final class ApiDocCommand {
|
|||||||
swaggerParamsList.add(swaggerParamMap);
|
swaggerParamsList.add(swaggerParamMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (param.style() == HttpParam.HttpParameterStyle.BODY) hasbodyparam = true;
|
if (param.style() == HttpParam.HttpParameterStyle.BODY) {
|
||||||
if (ptype.isPrimitive() || ptype == String.class) continue;
|
hasbodyparam = true;
|
||||||
if (typesMap.containsKey(ptype.getName())) continue;
|
}
|
||||||
if (ptype.getName().startsWith("java.")) continue;
|
if (ptype.isPrimitive() || ptype == String.class) {
|
||||||
if (ptype.getName().startsWith("javax.")) continue;
|
continue;
|
||||||
|
}
|
||||||
|
if (typesMap.containsKey(ptype.getName())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ptype.getName().startsWith("java.")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ptype.getName().startsWith("javax.")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
final Map<String, Map<String, Object>> typeMap = new LinkedHashMap<>();
|
final Map<String, Map<String, Object>> typeMap = new LinkedHashMap<>();
|
||||||
Class loop = ptype;
|
Class loop = ptype;
|
||||||
final boolean filter = FilterBean.class.isAssignableFrom(loop);
|
final boolean filter = FilterBean.class.isAssignableFrom(loop);
|
||||||
do {
|
do {
|
||||||
if (loop == null || loop.isInterface()) break;
|
if (loop == null || loop.isInterface()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
for (Field field : loop.getDeclaredFields()) {
|
for (Field field : loop.getDeclaredFields()) {
|
||||||
if (Modifier.isFinal(field.getModifiers())) continue;
|
if (Modifier.isFinal(field.getModifiers())) {
|
||||||
if (Modifier.isStatic(field.getModifiers())) continue;
|
continue;
|
||||||
|
}
|
||||||
|
if (Modifier.isStatic(field.getModifiers())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, Object> fieldmap = new LinkedHashMap<>();
|
Map<String, Object> fieldmap = new LinkedHashMap<>();
|
||||||
fieldmap.put("type", field.getType().isArray() ? (field.getType().getComponentType().getName() + "[]") : field.getGenericType().getTypeName());
|
fieldmap.put("type", field.getType().isArray() ? (field.getType().getComponentType().getName() + "[]") : field.getGenericType().getTypeName());
|
||||||
@@ -276,7 +317,9 @@ public final class ApiDocCommand {
|
|||||||
fieldmap.put("updatable", (filter || col == null || col.updatable()));
|
fieldmap.put("updatable", (filter || col == null || col.updatable()));
|
||||||
|
|
||||||
if (servlet.getClass().getAnnotation(Rest.RestDyn.class) != null) {
|
if (servlet.getClass().getAnnotation(Rest.RestDyn.class) != null) {
|
||||||
if (field.getAnnotation(RestAddress.class) != null) continue;
|
if (field.getAnnotation(RestAddress.class) != null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typeMap.put(field.getName(), fieldmap);
|
typeMap.put(field.getName(), fieldmap);
|
||||||
@@ -301,11 +344,17 @@ public final class ApiDocCommand {
|
|||||||
Map<String, Object> respMap = new LinkedHashMap<>();
|
Map<String, Object> respMap = new LinkedHashMap<>();
|
||||||
respMap.put("schema", respSchemaMap);
|
respMap.put("schema", respSchemaMap);
|
||||||
Object example = formatExample(returnFactory, action.example(), action.result(), resultType);
|
Object example = formatExample(returnFactory, action.example(), action.result(), resultType);
|
||||||
if (example != null) respSchemaMap.put("example", example);
|
if (example != null) {
|
||||||
if (!swaggerRequestBody.isEmpty()) swaggerOperatMap.put("requestBody", swaggerRequestBody);
|
respSchemaMap.put("example", example);
|
||||||
|
}
|
||||||
|
if (!swaggerRequestBody.isEmpty()) {
|
||||||
|
swaggerOperatMap.put("requestBody", swaggerRequestBody);
|
||||||
|
}
|
||||||
swaggerOperatMap.put("parameters", swaggerParamsList);
|
swaggerOperatMap.put("parameters", swaggerParamsList);
|
||||||
String actiondesc = action.comment();
|
String actiondesc = action.comment();
|
||||||
if (action.rpconly()) actiondesc = "[Only for RPC API] " + actiondesc;
|
if (action.rpconly()) {
|
||||||
|
actiondesc = "[Only for RPC API] " + actiondesc;
|
||||||
|
}
|
||||||
swaggerOperatMap.put("responses", Utility.ofMap("200", Utility.ofMap("description", actiondesc, "content", Utility.ofMap("application/json", respMap))));
|
swaggerOperatMap.put("responses", Utility.ofMap("200", Utility.ofMap("description", actiondesc, "content", Utility.ofMap("application/json", respMap))));
|
||||||
|
|
||||||
String m = action.methods() == null || action.methods().length == 0 ? null : action.methods()[0].toLowerCase();
|
String m = action.methods() == null || action.methods().length == 0 ? null : action.methods()[0].toLowerCase();
|
||||||
@@ -319,7 +368,9 @@ public final class ApiDocCommand {
|
|||||||
} while ((clz = clz.getSuperclass()) != HttpServlet.class);
|
} while ((clz = clz.getSuperclass()) != HttpServlet.class);
|
||||||
mappingsList.sort((o1, o2) -> ((String) o1.get("url")).compareTo((String) o2.get("url")));
|
mappingsList.sort((o1, o2) -> ((String) o1.get("url")).compareTo((String) o2.get("url")));
|
||||||
servletsList.add(servletMap);
|
servletsList.add(servletMap);
|
||||||
if (!actionUrls.isEmpty()) swaggerTags.add(Utility.ofMap("name", tag, "description", ws.comment()));
|
if (!actionUrls.isEmpty()) {
|
||||||
|
swaggerTags.add(Utility.ofMap("name", tag, "description", ws.comment()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
servletsList.sort((o1, o2) -> {
|
servletsList.sort((o1, o2) -> {
|
||||||
String[] urlregs1 = (String[]) o1.get("urlregs");
|
String[] urlregs1 = (String[]) o1.get("urlregs");
|
||||||
@@ -337,7 +388,9 @@ public final class ApiDocCommand {
|
|||||||
swaggerResultMap.put("servers", swaggerServers);
|
swaggerResultMap.put("servers", swaggerServers);
|
||||||
swaggerResultMap.put("paths", swaggerPathsMap);
|
swaggerResultMap.put("paths", swaggerPathsMap);
|
||||||
swaggerResultMap.put("tags", swaggerTags);
|
swaggerResultMap.put("tags", swaggerTags);
|
||||||
if (!swaggerComponentsMap.isEmpty()) swaggerResultMap.put("components", Utility.ofMap("schemas", swaggerComponentsMap));
|
if (!swaggerComponentsMap.isEmpty()) {
|
||||||
|
swaggerResultMap.put("components", Utility.ofMap("schemas", swaggerComponentsMap));
|
||||||
|
}
|
||||||
final FileOutputStream out = new FileOutputStream(new File(app.getHome(), "openapi-doc.json"));
|
final FileOutputStream out = new FileOutputStream(new File(app.getHome(), "openapi-doc.json"));
|
||||||
out.write(JsonConvert.root().convertTo(swaggerResultMap).getBytes(StandardCharsets.UTF_8));
|
out.write(JsonConvert.root().convertTo(swaggerResultMap).getBytes(StandardCharsets.UTF_8));
|
||||||
out.close();
|
out.close();
|
||||||
@@ -421,8 +474,12 @@ public final class ApiDocCommand {
|
|||||||
Set<Type> types = new HashSet<>();
|
Set<Type> types = new HashSet<>();
|
||||||
Encodeable encodeable = JsonFactory.root().loadEncoder(genericType);
|
Encodeable encodeable = JsonFactory.root().loadEncoder(genericType);
|
||||||
String ct = componentKey(factory, logger, types, componentsMap, null, encodeable, true);
|
String ct = componentKey(factory, logger, types, componentsMap, null, encodeable, true);
|
||||||
if (ct == null || ct.length() == 0) return null;
|
if (ct == null || ct.length() == 0) {
|
||||||
if (componentsMap.containsKey(ct)) return ct;
|
return null;
|
||||||
|
}
|
||||||
|
if (componentsMap.containsKey(ct)) {
|
||||||
|
return ct;
|
||||||
|
}
|
||||||
Map<String, Object> cmap = new LinkedHashMap<>();
|
Map<String, Object> cmap = new LinkedHashMap<>();
|
||||||
componentsMap.put(ct, cmap); //必须在调用simpleSchemaType之前put,不然嵌套情况下死循环
|
componentsMap.put(ct, cmap); //必须在调用simpleSchemaType之前put,不然嵌套情况下死循环
|
||||||
|
|
||||||
@@ -440,11 +497,15 @@ public final class ApiDocCommand {
|
|||||||
FilterColumn fcol = member.getField().getAnnotation(FilterColumn.class);
|
FilterColumn fcol = member.getField().getAnnotation(FilterColumn.class);
|
||||||
if (fcol != null) {
|
if (fcol != null) {
|
||||||
desc = fcol.comment();
|
desc = fcol.comment();
|
||||||
if (fcol.required()) requireds.add(member.getAttribute().field());
|
if (fcol.required()) {
|
||||||
|
requireds.add(member.getAttribute().field());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
desc = col.comment();
|
desc = col.comment();
|
||||||
if (!col.nullable()) requireds.add(member.getAttribute().field());
|
if (!col.nullable()) {
|
||||||
|
requireds.add(member.getAttribute().field());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (desc.isEmpty() && member.getField().getAnnotation(Comment.class) != null) {
|
if (desc.isEmpty() && member.getField().getAnnotation(Comment.class) != null) {
|
||||||
desc = member.getField().getAnnotation(Comment.class).value();
|
desc = member.getField().getAnnotation(Comment.class).value();
|
||||||
@@ -457,11 +518,15 @@ public final class ApiDocCommand {
|
|||||||
FilterColumn fcol = member.getMethod().getAnnotation(FilterColumn.class);
|
FilterColumn fcol = member.getMethod().getAnnotation(FilterColumn.class);
|
||||||
if (fcol != null) {
|
if (fcol != null) {
|
||||||
desc = fcol.comment();
|
desc = fcol.comment();
|
||||||
if (fcol.required()) requireds.add(member.getAttribute().field());
|
if (fcol.required()) {
|
||||||
|
requireds.add(member.getAttribute().field());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
desc = col.comment();
|
desc = col.comment();
|
||||||
if (!col.nullable()) requireds.add(member.getAttribute().field());
|
if (!col.nullable()) {
|
||||||
|
requireds.add(member.getAttribute().field());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (desc.isEmpty() && member.getMethod().getAnnotation(Comment.class) != null) {
|
if (desc.isEmpty() && member.getMethod().getAnnotation(Comment.class) != null) {
|
||||||
desc = member.getMethod().getAnnotation(Comment.class).value();
|
desc = member.getMethod().getAnnotation(Comment.class).value();
|
||||||
@@ -469,11 +534,15 @@ public final class ApiDocCommand {
|
|||||||
desc = member.getMethod().getAnnotation(org.redkale.util.Comment.class).value();
|
desc = member.getMethod().getAnnotation(org.redkale.util.Comment.class).value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!desc.isEmpty()) schemaMap.put("description", desc);
|
if (!desc.isEmpty()) {
|
||||||
|
schemaMap.put("description", desc);
|
||||||
|
}
|
||||||
properties.put(member.getAttribute().field(), schemaMap);
|
properties.put(member.getAttribute().field(), schemaMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!requireds.isEmpty()) cmap.put("required", requireds);
|
if (!requireds.isEmpty()) {
|
||||||
|
cmap.put("required", requireds);
|
||||||
|
}
|
||||||
cmap.put("properties", properties);
|
cmap.put("properties", properties);
|
||||||
return ct;
|
return ct;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -484,7 +553,9 @@ public final class ApiDocCommand {
|
|||||||
|
|
||||||
private static String componentKey(JsonFactory factory, Logger logger, Set<Type> types, Map<String, Map<String, Object>> componentsMap, EnMember field, Encodeable encodeable, boolean first) {
|
private static String componentKey(JsonFactory factory, Logger logger, Set<Type> types, Map<String, Map<String, Object>> componentsMap, EnMember field, Encodeable encodeable, boolean first) {
|
||||||
if (encodeable instanceof ObjectEncoder) {
|
if (encodeable instanceof ObjectEncoder) {
|
||||||
if (types.contains(encodeable.getType())) return "";
|
if (types.contains(encodeable.getType())) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
types.add(encodeable.getType());
|
types.add(encodeable.getType());
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(((ObjectEncoder) encodeable).getTypeClass().getSimpleName());
|
sb.append(((ObjectEncoder) encodeable).getTypeClass().getSimpleName());
|
||||||
@@ -492,19 +563,33 @@ public final class ApiDocCommand {
|
|||||||
if (member.getEncoder() instanceof ArrayEncoder
|
if (member.getEncoder() instanceof ArrayEncoder
|
||||||
|| member.getEncoder() instanceof CollectionEncoder) {
|
|| member.getEncoder() instanceof CollectionEncoder) {
|
||||||
String subsb = componentKey(factory, logger, types, componentsMap, member, member.getEncoder(), false);
|
String subsb = componentKey(factory, logger, types, componentsMap, member, member.getEncoder(), false);
|
||||||
if (subsb == null) return null;
|
if (subsb == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
AccessibleObject real = member.getField() == null ? member.getMethod() : member.getField();
|
AccessibleObject real = member.getField() == null ? member.getMethod() : member.getField();
|
||||||
if (real == null) continue;
|
if (real == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Class cz = real instanceof Field ? ((Field) real).getType() : ((Method) real).getReturnType();
|
Class cz = real instanceof Field ? ((Field) real).getType() : ((Method) real).getReturnType();
|
||||||
Type ct = real instanceof Field ? ((Field) real).getGenericType() : ((Method) real).getGenericReturnType();
|
Type ct = real instanceof Field ? ((Field) real).getGenericType() : ((Method) real).getGenericReturnType();
|
||||||
if (cz == ct) continue;
|
if (cz == ct) {
|
||||||
if (field == null && encodeable.getType() instanceof Class) continue;
|
continue;
|
||||||
if (sb.length() > 0 && subsb.length() > 0) sb.append("_");
|
}
|
||||||
|
if (field == null && encodeable.getType() instanceof Class) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (sb.length() > 0 && subsb.length() > 0) {
|
||||||
|
sb.append("_");
|
||||||
|
}
|
||||||
sb.append(subsb);
|
sb.append(subsb);
|
||||||
} else if (member.getEncoder() instanceof ObjectEncoder || member.getEncoder() instanceof SimpledCoder) {
|
} else if (member.getEncoder() instanceof ObjectEncoder || member.getEncoder() instanceof SimpledCoder) {
|
||||||
AccessibleObject real = member.getField() == null ? member.getMethod() : member.getField();
|
AccessibleObject real = member.getField() == null ? member.getMethod() : member.getField();
|
||||||
if (real == null) continue;
|
if (real == null) {
|
||||||
if (types.contains(member.getEncoder().getType())) continue;
|
continue;
|
||||||
|
}
|
||||||
|
if (types.contains(member.getEncoder().getType())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
types.add(member.getEncoder().getType());
|
types.add(member.getEncoder().getType());
|
||||||
if (member.getEncoder() instanceof SimpledCoder) {
|
if (member.getEncoder() instanceof SimpledCoder) {
|
||||||
simpleSchemaType(factory, logger, componentsMap, ((SimpledCoder) member.getEncoder()).getType(), ((SimpledCoder) member.getEncoder()).getType(), new LinkedHashMap<>(), true);
|
simpleSchemaType(factory, logger, componentsMap, ((SimpledCoder) member.getEncoder()).getType(), ((SimpledCoder) member.getEncoder()).getType(), new LinkedHashMap<>(), true);
|
||||||
@@ -513,11 +598,19 @@ public final class ApiDocCommand {
|
|||||||
}
|
}
|
||||||
Class cz = real instanceof Field ? ((Field) real).getType() : ((Method) real).getReturnType();
|
Class cz = real instanceof Field ? ((Field) real).getType() : ((Method) real).getReturnType();
|
||||||
Type ct = real instanceof Field ? ((Field) real).getGenericType() : ((Method) real).getGenericReturnType();
|
Type ct = real instanceof Field ? ((Field) real).getGenericType() : ((Method) real).getGenericReturnType();
|
||||||
if (cz == ct) continue;
|
if (cz == ct) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
String subsb = componentKey(factory, logger, types, componentsMap, member, member.getEncoder(), false);
|
String subsb = componentKey(factory, logger, types, componentsMap, member, member.getEncoder(), false);
|
||||||
if (subsb == null) return null;
|
if (subsb == null) {
|
||||||
if (field == null && member.getEncoder().getType() instanceof Class) continue;
|
return null;
|
||||||
if (sb.length() > 0 && subsb.length() > 0) sb.append("_");
|
}
|
||||||
|
if (field == null && member.getEncoder().getType() instanceof Class) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (sb.length() > 0 && subsb.length() > 0) {
|
||||||
|
sb.append("_");
|
||||||
|
}
|
||||||
sb.append(subsb);
|
sb.append(subsb);
|
||||||
} else if (member.getEncoder() instanceof MapEncoder) {
|
} else if (member.getEncoder() instanceof MapEncoder) {
|
||||||
continue;
|
continue;
|
||||||
@@ -529,9 +622,13 @@ public final class ApiDocCommand {
|
|||||||
} else if (encodeable instanceof ArrayEncoder || encodeable instanceof CollectionEncoder) {
|
} else if (encodeable instanceof ArrayEncoder || encodeable instanceof CollectionEncoder) {
|
||||||
final boolean array = (encodeable instanceof ArrayEncoder);
|
final boolean array = (encodeable instanceof ArrayEncoder);
|
||||||
Encodeable subEncodeable = array ? ((ArrayEncoder) encodeable).getComponentEncoder() : ((CollectionEncoder) encodeable).getComponentEncoder();
|
Encodeable subEncodeable = array ? ((ArrayEncoder) encodeable).getComponentEncoder() : ((CollectionEncoder) encodeable).getComponentEncoder();
|
||||||
if (subEncodeable instanceof SimpledCoder && field != null) return "";
|
if (subEncodeable instanceof SimpledCoder && field != null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
final String sb = componentKey(factory, logger, types, componentsMap, null, subEncodeable, false);
|
final String sb = componentKey(factory, logger, types, componentsMap, null, subEncodeable, false);
|
||||||
if (sb == null || sb.isEmpty()) return sb;
|
if (sb == null || sb.isEmpty()) {
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
if (field != null && field.getField() != null && field.getField().getDeclaringClass() == Sheet.class) {
|
if (field != null && field.getField() != null && field.getField().getDeclaringClass() == Sheet.class) {
|
||||||
return sb;
|
return sb;
|
||||||
}
|
}
|
||||||
@@ -550,7 +647,9 @@ public final class ApiDocCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Object formatExample(JsonFactory factory, String example, Class type, Type genericType) {
|
private static Object formatExample(JsonFactory factory, String example, Class type, Type genericType) {
|
||||||
if (example != null && !example.isEmpty()) return example;
|
if (example != null && !example.isEmpty()) {
|
||||||
|
return example;
|
||||||
|
}
|
||||||
JsonFactory jsonFactory = factory == null || factory == JsonFactory.root() ? exampleFactory : factory;
|
JsonFactory jsonFactory = factory == null || factory == JsonFactory.root() ? exampleFactory : factory;
|
||||||
if (type == Flipper.class) {
|
if (type == Flipper.class) {
|
||||||
return new Flipper();
|
return new Flipper();
|
||||||
@@ -642,8 +741,12 @@ public final class ApiDocCommand {
|
|||||||
json.append("{");
|
json.append("{");
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (DeMember member : ((ObjectDecoder) decoder).getMembers()) {
|
for (DeMember member : ((ObjectDecoder) decoder).getMembers()) {
|
||||||
if (!(member.getDecoder() instanceof ObjectDecoder)) continue;
|
if (!(member.getDecoder() instanceof ObjectDecoder)) {
|
||||||
if (index > 0) json.append(",");
|
continue;
|
||||||
|
}
|
||||||
|
if (index > 0) {
|
||||||
|
json.append(",");
|
||||||
|
}
|
||||||
json.append('"').append(member.getAttribute().field()).append("\":{}");
|
json.append('"').append(member.getAttribute().field()).append("\":{}");
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
@@ -659,6 +762,6 @@ public final class ApiDocCommand {
|
|||||||
return example;
|
return example;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final JsonFactory exampleFactory = JsonFactory.create().tiny(false);
|
private static final JsonFactory exampleFactory = JsonFactory.create().tiny(false).nullable(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,21 +24,42 @@ import static java.lang.annotation.RetentionPolicy.*;
|
|||||||
public @interface ConvertCoder {
|
public @interface ConvertCoder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 需要指定的字段类型,指定了coder字段值则可以不设置此字段
|
* 需要指定的字段类型,类型必须是原字段类型的子类。
|
||||||
|
* 例如: <br>
|
||||||
|
* <blockquote><pre>
|
||||||
|
* @ConvertCoder(column = String.class)
|
||||||
|
* private CharSequence name;
|
||||||
|
* </pre></blockquote>
|
||||||
|
*
|
||||||
|
* 通常此字段值与encoder/decoder是二选一,指定了coder字段值则可以不设置此字段。
|
||||||
*
|
*
|
||||||
* @return 字段类名
|
* @return 字段类名
|
||||||
*/
|
*/
|
||||||
Class column() default Object.class;
|
Class column() default Object.class;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 序列化定制化的 Encodeable
|
* 序列化定制化的 Encodeable, 构造函数的参数可以是:<br>
|
||||||
|
* 1、ConvertFactory
|
||||||
|
* 2、Type
|
||||||
|
* 3、Class
|
||||||
|
* 4、ConvertFactory和Type
|
||||||
|
* 5、ConvertFactory和Class
|
||||||
|
*
|
||||||
|
* 类如果存在instance单实例对象字段值,则优先使用instance对象
|
||||||
*
|
*
|
||||||
* @return Encodeable 类
|
* @return Encodeable 类
|
||||||
*/
|
*/
|
||||||
Class<? extends Encodeable> encoder() default Encodeable.class;
|
Class<? extends Encodeable> encoder() default Encodeable.class;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 反序列化定制化的 Decodeable
|
* 反序列化定制化的 Decodeable, 构造函数的参数可以是:<br>
|
||||||
|
* 1、ConvertFactory
|
||||||
|
* 2、Type
|
||||||
|
* 3、Class
|
||||||
|
* 4、ConvertFactory和Type
|
||||||
|
* 5、ConvertFactory和Class
|
||||||
|
*
|
||||||
|
* 类如果存在instance单实例对象字段值,则优先使用instance对象
|
||||||
*
|
*
|
||||||
* @return Decodeable 类
|
* @return Decodeable 类
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
|||||||
|
|
||||||
protected Convert<R, W> convert;
|
protected Convert<R, W> convert;
|
||||||
|
|
||||||
protected boolean tiny; //String类型值为"",Boolean类型值为false时是否需要输出, 默认为false
|
protected boolean tiny; //值为true时 String类型值为"",Boolean类型值为false时不会输出,默认为false
|
||||||
|
|
||||||
|
protected boolean nullable; ///值为true时 字段值为null时会输出,默认为false
|
||||||
|
|
||||||
private final Encodeable<W, ?> anyEncoder = new AnyEncoder(this);
|
private final Encodeable<W, ?> anyEncoder = new AnyEncoder(this);
|
||||||
|
|
||||||
@@ -72,8 +74,9 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
|||||||
|
|
||||||
private boolean skipAllIgnore = false;
|
private boolean skipAllIgnore = false;
|
||||||
|
|
||||||
protected ConvertFactory(ConvertFactory<R, W> parent, boolean tiny) {
|
protected ConvertFactory(ConvertFactory<R, W> parent, boolean tiny, boolean nullable) {
|
||||||
this.tiny = tiny;
|
this.tiny = tiny;
|
||||||
|
this.nullable = nullable;
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
if (parent == null) {
|
if (parent == null) {
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
@@ -251,7 +254,7 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
|||||||
|
|
||||||
public abstract ConvertFactory createChild();
|
public abstract ConvertFactory createChild();
|
||||||
|
|
||||||
public abstract ConvertFactory createChild(boolean tiny);
|
public abstract ConvertFactory createChild(boolean tiny, boolean nullable);
|
||||||
|
|
||||||
protected SimpledCoder createEnumSimpledCoder(Class enumClass) {
|
protected SimpledCoder createEnumSimpledCoder(Class enumClass) {
|
||||||
return new EnumSimpledCoder(this, enumClass);
|
return new EnumSimpledCoder(this, enumClass);
|
||||||
@@ -335,6 +338,11 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ConvertFactory nullable(boolean nullable) {
|
||||||
|
this.nullable = nullable;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isConvertDisabled(AccessibleObject element) {
|
public boolean isConvertDisabled(AccessibleObject element) {
|
||||||
ConvertDisabled[] ccs = element.getAnnotationsByType(ConvertDisabled.class);
|
ConvertDisabled[] ccs = element.getAnnotationsByType(ConvertDisabled.class);
|
||||||
if (ccs.length == 0 && element instanceof Method) {
|
if (ccs.length == 0 && element instanceof Method) {
|
||||||
@@ -630,7 +638,7 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConvertFactory columnFactory(Class type, ConvertCoder[] coders, boolean encode) {
|
ConvertFactory columnFactory(Type type, ConvertCoder[] coders, boolean encode) {
|
||||||
if (coders == null || coders.length < 1) {
|
if (coders == null || coders.length < 1) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -642,7 +650,7 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
|||||||
if (!ann.type().contains(ct)) {
|
if (!ann.type().contains(ct)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Class colType = type;
|
Type colType = type;
|
||||||
if (ann.column() != Object.class) {
|
if (ann.column() != Object.class) {
|
||||||
colType = ann.column();
|
colType = ann.column();
|
||||||
}
|
}
|
||||||
@@ -679,7 +687,9 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
|||||||
if (paramTypes.length == 0) {
|
if (paramTypes.length == 0) {
|
||||||
encoder = creator.create();
|
encoder = creator.create();
|
||||||
} else if (paramTypes.length == 1) {
|
} else if (paramTypes.length == 1) {
|
||||||
if (Type.class.isAssignableFrom(paramTypes[0])) {
|
if (Class.class.isAssignableFrom(paramTypes[0])) {
|
||||||
|
encoder = creator.create((Object) TypeToken.typeToClass(colType));
|
||||||
|
} else if (Type.class.isAssignableFrom(paramTypes[0])) {
|
||||||
encoder = creator.create((Object) colType);
|
encoder = creator.create((Object) colType);
|
||||||
} else if (ConvertFactory.class.isAssignableFrom(paramTypes[0])) {
|
} else if (ConvertFactory.class.isAssignableFrom(paramTypes[0])) {
|
||||||
encoder = creator.create(this);
|
encoder = creator.create(this);
|
||||||
@@ -687,7 +697,11 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
|||||||
throw new ConvertException(enClazz + " not found public empty-parameter Constructor");
|
throw new ConvertException(enClazz + " not found public empty-parameter Constructor");
|
||||||
}
|
}
|
||||||
} else if (paramTypes.length == 2) {
|
} else if (paramTypes.length == 2) {
|
||||||
if (ConvertFactory.class.isAssignableFrom(paramTypes[0]) && Type.class.isAssignableFrom(paramTypes[1])) {
|
if (ConvertFactory.class.isAssignableFrom(paramTypes[0]) && Class.class.isAssignableFrom(paramTypes[1])) {
|
||||||
|
encoder = creator.create(this, TypeToken.typeToClass(colType));
|
||||||
|
} else if (Class.class.isAssignableFrom(paramTypes[0]) && ConvertFactory.class.isAssignableFrom(paramTypes[1])) {
|
||||||
|
encoder = creator.create(TypeToken.typeToClass(colType), this);
|
||||||
|
} else if (ConvertFactory.class.isAssignableFrom(paramTypes[0]) && Type.class.isAssignableFrom(paramTypes[1])) {
|
||||||
encoder = creator.create(this, colType);
|
encoder = creator.create(this, colType);
|
||||||
} else if (Type.class.isAssignableFrom(paramTypes[0]) && ConvertFactory.class.isAssignableFrom(paramTypes[1])) {
|
} else if (Type.class.isAssignableFrom(paramTypes[0]) && ConvertFactory.class.isAssignableFrom(paramTypes[1])) {
|
||||||
encoder = creator.create(colType, this);
|
encoder = creator.create(colType, this);
|
||||||
@@ -740,7 +754,9 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
|||||||
if (paramTypes.length == 0) {
|
if (paramTypes.length == 0) {
|
||||||
decoder = creator.create();
|
decoder = creator.create();
|
||||||
} else if (paramTypes.length == 1) {
|
} else if (paramTypes.length == 1) {
|
||||||
if (Type.class.isAssignableFrom(paramTypes[0])) {
|
if (Class.class.isAssignableFrom(paramTypes[0])) {
|
||||||
|
decoder = creator.create((Object) TypeToken.typeToClass(colType));
|
||||||
|
} else if (Type.class.isAssignableFrom(paramTypes[0])) {
|
||||||
decoder = creator.create((Object) colType);
|
decoder = creator.create((Object) colType);
|
||||||
} else if (ConvertFactory.class.isAssignableFrom(paramTypes[0])) {
|
} else if (ConvertFactory.class.isAssignableFrom(paramTypes[0])) {
|
||||||
decoder = creator.create(this);
|
decoder = creator.create(this);
|
||||||
@@ -748,7 +764,11 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
|||||||
throw new ConvertException(deClazz + " not found public empty-parameter Constructor");
|
throw new ConvertException(deClazz + " not found public empty-parameter Constructor");
|
||||||
}
|
}
|
||||||
} else if (paramTypes.length == 2) {
|
} else if (paramTypes.length == 2) {
|
||||||
if (ConvertFactory.class.isAssignableFrom(paramTypes[0]) && Type.class.isAssignableFrom(paramTypes[1])) {
|
if (ConvertFactory.class.isAssignableFrom(paramTypes[0]) && Class.class.isAssignableFrom(paramTypes[1])) {
|
||||||
|
decoder = creator.create(this, TypeToken.typeToClass(colType));
|
||||||
|
} else if (Class.class.isAssignableFrom(paramTypes[0]) && ConvertFactory.class.isAssignableFrom(paramTypes[1])) {
|
||||||
|
decoder = creator.create(TypeToken.typeToClass(colType), this);
|
||||||
|
} else if (ConvertFactory.class.isAssignableFrom(paramTypes[0]) && Type.class.isAssignableFrom(paramTypes[1])) {
|
||||||
decoder = creator.create(this, colType);
|
decoder = creator.create(this, colType);
|
||||||
} else if (Type.class.isAssignableFrom(paramTypes[0]) && ConvertFactory.class.isAssignableFrom(paramTypes[1])) {
|
} else if (Type.class.isAssignableFrom(paramTypes[0]) && ConvertFactory.class.isAssignableFrom(paramTypes[1])) {
|
||||||
decoder = creator.create(colType, this);
|
decoder = creator.create(colType, this);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
package org.redkale.convert;
|
package org.redkale.convert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert的扩展实现类加载器
|
* Convert的扩展实现类加载器, 通过此类可以创建自定义的序列化格式,例如:protobuf、xmlbean
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 详情见: https://redkale.org
|
* 详情见: https://redkale.org
|
||||||
|
|||||||
@@ -5,12 +5,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.convert;
|
package org.redkale.convert;
|
||||||
|
|
||||||
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
import static java.lang.annotation.ElementType.*;
|
import static java.lang.annotation.ElementType.*;
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 序列化时标记String字段的值是否为无转义字符且长度不超过255的字符串
|
* 序列化时标记String字段的值是否为无转义字符且长度不超过255的字符串,通常用于类名、字段名、枚举值字符串等
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* 详情见: https://redkale.org
|
* 详情见: https://redkale.org
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ public class ObjectDecoder<R extends Reader, T> implements Decodeable<R, T> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ConvertSmallString small = field.getAnnotation(ConvertSmallString.class);
|
ConvertSmallString small = field.getAnnotation(ConvertSmallString.class);
|
||||||
colFactory = factory.columnFactory(field.getType(), field.getAnnotationsByType(ConvertCoder.class), false);
|
colFactory = factory.columnFactory(field.getGenericType(), field.getAnnotationsByType(ConvertCoder.class), false);
|
||||||
Decodeable<R, ?> fieldCoder;
|
Decodeable<R, ?> fieldCoder;
|
||||||
if (small != null && field.getType() == String.class) {
|
if (small != null && field.getType() == String.class) {
|
||||||
fieldCoder = StringSimpledCoder.SmallStringSimpledCoder.instance;
|
fieldCoder = StringSimpledCoder.SmallStringSimpledCoder.instance;
|
||||||
@@ -197,9 +197,9 @@ public class ObjectDecoder<R extends Reader, T> implements Decodeable<R, T> {
|
|||||||
|
|
||||||
ConvertSmallString small = method.getAnnotation(ConvertSmallString.class);
|
ConvertSmallString small = method.getAnnotation(ConvertSmallString.class);
|
||||||
Field maybeField = ConvertFactory.readGetSetField(method);
|
Field maybeField = ConvertFactory.readGetSetField(method);
|
||||||
colFactory = factory.columnFactory(method.getParameterTypes()[0], method.getAnnotationsByType(ConvertCoder.class), false);
|
colFactory = factory.columnFactory(method.getGenericParameterTypes()[0], method.getAnnotationsByType(ConvertCoder.class), false);
|
||||||
if (maybeField != null && colFactory == factory) {
|
if (maybeField != null && colFactory == factory) {
|
||||||
colFactory = factory.columnFactory(maybeField.getType(), maybeField.getAnnotationsByType(ConvertCoder.class), false);
|
colFactory = factory.columnFactory(maybeField.getGenericType(), maybeField.getAnnotationsByType(ConvertCoder.class), false);
|
||||||
}
|
}
|
||||||
Decodeable<R, ?> fieldCoder;
|
Decodeable<R, ?> fieldCoder;
|
||||||
if (small != null && method.getParameterTypes()[0] == String.class) {
|
if (small != null && method.getParameterTypes()[0] == String.class) {
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ public class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ConvertSmallString small = field.getAnnotation(ConvertSmallString.class);
|
ConvertSmallString small = field.getAnnotation(ConvertSmallString.class);
|
||||||
colFactory = factory.columnFactory(field.getType(), field.getAnnotationsByType(ConvertCoder.class), true);
|
colFactory = factory.columnFactory(field.getGenericType(), field.getAnnotationsByType(ConvertCoder.class), true);
|
||||||
Encodeable<W, ?> fieldCoder;
|
Encodeable<W, ?> fieldCoder;
|
||||||
if (small != null && field.getType() == String.class) {
|
if (small != null && field.getType() == String.class) {
|
||||||
fieldCoder = StringSimpledCoder.SmallStringSimpledCoder.instance;
|
fieldCoder = StringSimpledCoder.SmallStringSimpledCoder.instance;
|
||||||
@@ -165,9 +165,9 @@ public class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Field maybeField = ConvertFactory.readGetSetField(method);
|
Field maybeField = ConvertFactory.readGetSetField(method);
|
||||||
colFactory = factory.columnFactory(method.getReturnType(), method.getAnnotationsByType(ConvertCoder.class), true);
|
colFactory = factory.columnFactory(method.getGenericReturnType(), method.getAnnotationsByType(ConvertCoder.class), true);
|
||||||
if (maybeField != null && colFactory == factory) {
|
if (maybeField != null && colFactory == factory) {
|
||||||
colFactory = factory.columnFactory(maybeField.getType(), maybeField.getAnnotationsByType(ConvertCoder.class), true);
|
colFactory = factory.columnFactory(maybeField.getGenericType(), maybeField.getAnnotationsByType(ConvertCoder.class), true);
|
||||||
}
|
}
|
||||||
Encodeable<W, ?> fieldCoder;
|
Encodeable<W, ?> fieldCoder;
|
||||||
if (small != null && method.getReturnType() == String.class) {
|
if (small != null && method.getReturnType() == String.class) {
|
||||||
|
|||||||
@@ -74,6 +74,13 @@ public abstract class Writer {
|
|||||||
*/
|
*/
|
||||||
public abstract boolean tiny();
|
public abstract boolean tiny();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当nullable=true时, 字段值为null时会输出该字段
|
||||||
|
*
|
||||||
|
* @return 是否简化
|
||||||
|
*/
|
||||||
|
public abstract boolean nullable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 输出null值
|
* 输出null值
|
||||||
*/
|
*/
|
||||||
@@ -132,6 +139,12 @@ public abstract class Writer {
|
|||||||
value = objFieldFunc.apply(member.attribute, obj);
|
value = objFieldFunc.apply(member.attribute, obj);
|
||||||
}
|
}
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
|
if (nullable()) {
|
||||||
|
Attribute attr = member.getAttribute();
|
||||||
|
this.writeFieldName(member, attr.field(), attr.genericType(), member.getPosition());
|
||||||
|
writeNull();
|
||||||
|
this.comma = true;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (tiny()) {
|
if (tiny()) {
|
||||||
@@ -164,6 +177,11 @@ public abstract class Writer {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void writeObjectField(final String fieldName, Type fieldType, int fieldPos, Encodeable anyEncoder, Object value) {
|
public void writeObjectField(final String fieldName, Type fieldType, int fieldPos, Encodeable anyEncoder, Object value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
|
if (nullable()) {
|
||||||
|
this.writeFieldName(null, fieldName, fieldType, fieldPos);
|
||||||
|
writeNull();
|
||||||
|
this.comma = true;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fieldType == null) {
|
if (fieldType == null) {
|
||||||
|
|||||||
@@ -26,12 +26,13 @@ public class BsonByteBufferWriter extends BsonWriter {
|
|||||||
private int index;
|
private int index;
|
||||||
|
|
||||||
public BsonByteBufferWriter(Supplier<ByteBuffer> supplier) {
|
public BsonByteBufferWriter(Supplier<ByteBuffer> supplier) {
|
||||||
this(false, supplier);
|
this(false, false, supplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BsonByteBufferWriter(boolean tiny, Supplier<ByteBuffer> supplier) {
|
protected BsonByteBufferWriter(boolean tiny, boolean nullable, Supplier<ByteBuffer> supplier) {
|
||||||
super((byte[]) null);
|
super((byte[]) null);
|
||||||
this.tiny = tiny;
|
this.tiny = tiny;
|
||||||
|
this.nullable = nullable;
|
||||||
this.supplier = supplier;
|
this.supplier = supplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +77,12 @@ public class BsonByteBufferWriter extends BsonWriter {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BsonByteBufferWriter nullable(boolean nullable) {
|
||||||
|
this.nullable = nullable;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int expand(final int byteLength) {
|
protected int expand(final int byteLength) {
|
||||||
if (this.buffers == null) {
|
if (this.buffers == null) {
|
||||||
|
|||||||
@@ -48,9 +48,12 @@ public class BsonConvert extends BinaryConvert<BsonReader, BsonWriter> {
|
|||||||
|
|
||||||
private final boolean tiny;
|
private final boolean tiny;
|
||||||
|
|
||||||
protected BsonConvert(ConvertFactory<BsonReader, BsonWriter> factory, boolean tiny) {
|
private final boolean nullable;
|
||||||
|
|
||||||
|
protected BsonConvert(ConvertFactory<BsonReader, BsonWriter> factory, boolean tiny, boolean nullable) {
|
||||||
super(factory);
|
super(factory);
|
||||||
this.tiny = tiny;
|
this.tiny = tiny;
|
||||||
|
this.nullable = nullable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -79,7 +82,7 @@ public class BsonConvert extends BinaryConvert<BsonReader, BsonWriter> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BsonConvert newConvert(final BiFunction<Attribute, Object, Object> fieldFunc, BiFunction<Object, Object, Object> mapFieldFunc, Function<Object, ConvertField[]> objExtFunc) {
|
public BsonConvert newConvert(final BiFunction<Attribute, Object, Object> fieldFunc, BiFunction<Object, Object, Object> mapFieldFunc, Function<Object, ConvertField[]> objExtFunc) {
|
||||||
return new BsonConvert(getFactory(), tiny) {
|
return new BsonConvert(getFactory(), tiny, nullable) {
|
||||||
@Override
|
@Override
|
||||||
protected <S extends BsonWriter> S configWrite(S writer) {
|
protected <S extends BsonWriter> S configWrite(S writer) {
|
||||||
return fieldFunc(writer, fieldFunc, mapFieldFunc, objExtFunc);
|
return fieldFunc(writer, fieldFunc, mapFieldFunc, objExtFunc);
|
||||||
@@ -117,11 +120,11 @@ public class BsonConvert extends BinaryConvert<BsonReader, BsonWriter> {
|
|||||||
|
|
||||||
//------------------------------ writer -----------------------------------------------------------
|
//------------------------------ writer -----------------------------------------------------------
|
||||||
public BsonByteBufferWriter pollWriter(final Supplier<ByteBuffer> supplier) {
|
public BsonByteBufferWriter pollWriter(final Supplier<ByteBuffer> supplier) {
|
||||||
return configWrite(new BsonByteBufferWriter(tiny, supplier));
|
return configWrite(new BsonByteBufferWriter(tiny, nullable, supplier));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BsonWriter pollWriter(final OutputStream out) {
|
protected BsonWriter pollWriter(final OutputStream out) {
|
||||||
return configWrite(new BsonStreamWriter(tiny, out));
|
return configWrite(new BsonStreamWriter(tiny, nullable, out));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -132,7 +135,7 @@ public class BsonConvert extends BinaryConvert<BsonReader, BsonWriter> {
|
|||||||
} else {
|
} else {
|
||||||
writerPool.set(null);
|
writerPool.set(null);
|
||||||
}
|
}
|
||||||
return configWrite(writer.tiny(tiny));
|
return configWrite(writer.tiny(tiny).nullable(nullable));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -237,7 +240,7 @@ public class BsonConvert extends BinaryConvert<BsonReader, BsonWriter> {
|
|||||||
@Override
|
@Override
|
||||||
public void convertToBytes(final ByteArray array, final Type type, final Object value) {
|
public void convertToBytes(final ByteArray array, final Type type, final Object value) {
|
||||||
Objects.requireNonNull(array);
|
Objects.requireNonNull(array);
|
||||||
final BsonWriter writer = configWrite(new BsonWriter(array).tiny(tiny));
|
final BsonWriter writer = configWrite(new BsonWriter(array).tiny(tiny).nullable(nullable));
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
writer.writeNull();
|
writer.writeNull();
|
||||||
} else {
|
} else {
|
||||||
@@ -283,7 +286,7 @@ public class BsonConvert extends BinaryConvert<BsonReader, BsonWriter> {
|
|||||||
if (value == null) {
|
if (value == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final BsonWriter writer = writerPool.get().tiny(tiny);
|
final BsonWriter writer = writerPool.get().tiny(tiny).nullable(nullable);
|
||||||
factory.loadEncoder(type == null ? value.getClass() : type).convertTo(writer, value);
|
factory.loadEncoder(type == null ? value.getClass() : type).convertTo(writer, value);
|
||||||
return writer;
|
return writer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ import org.redkale.util.TypeToken;
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public final class BsonFactory extends ConvertFactory<BsonReader, BsonWriter> {
|
public final class BsonFactory extends ConvertFactory<BsonReader, BsonWriter> {
|
||||||
|
|
||||||
private static final BsonFactory instance = new BsonFactory(null, getSystemPropertyBoolean("redkale.convert.bson.tiny", "redkale.convert.tiny", false));
|
private static final BsonFactory instance = new BsonFactory(null,
|
||||||
|
getSystemPropertyBoolean("redkale.convert.bson.tiny", "redkale.convert.tiny", true),
|
||||||
|
getSystemPropertyBoolean("redkale.convert.bson.nullable", "redkale.convert.nullable", false));
|
||||||
|
|
||||||
static final Decodeable objectDecoder = instance.loadDecoder(Object.class);
|
static final Decodeable objectDecoder = instance.loadDecoder(Object.class);
|
||||||
|
|
||||||
@@ -48,8 +50,8 @@ public final class BsonFactory extends ConvertFactory<BsonReader, BsonWriter> {
|
|||||||
//instance.register(AnyValue.class, instance.loadEncoder(AnyValue.DefaultAnyValue.class));
|
//instance.register(AnyValue.class, instance.loadEncoder(AnyValue.DefaultAnyValue.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
private BsonFactory(BsonFactory parent, boolean tiny) {
|
private BsonFactory(BsonFactory parent, boolean tiny, boolean nullable) {
|
||||||
super(parent, tiny);
|
super(parent, tiny, nullable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -62,6 +64,16 @@ public final class BsonFactory extends ConvertFactory<BsonReader, BsonWriter> {
|
|||||||
return this.tiny;
|
return this.tiny;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BsonFactory nullable(boolean nullable) {
|
||||||
|
this.nullable = nullable;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean nullable() {
|
||||||
|
return this.nullable;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BsonFactory skipAllIgnore(final boolean skipIgnore) {
|
public BsonFactory skipAllIgnore(final boolean skipIgnore) {
|
||||||
this.registerSkipAllIgnore(skipIgnore);
|
this.registerSkipAllIgnore(skipIgnore);
|
||||||
@@ -73,25 +85,26 @@ public final class BsonFactory extends ConvertFactory<BsonReader, BsonWriter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static BsonFactory create() {
|
public static BsonFactory create() {
|
||||||
return new BsonFactory(null, getSystemPropertyBoolean("redkale.convert.bson.tiny", "redkale.convert.tiny", false));
|
return new BsonFactory(null, getSystemPropertyBoolean("redkale.convert.bson.tiny", "redkale.convert.tiny", true),
|
||||||
|
getSystemPropertyBoolean("redkale.convert.bson.nullable", "redkale.convert.nullable", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final BsonConvert getConvert() {
|
public final BsonConvert getConvert() {
|
||||||
if (convert == null) {
|
if (convert == null) {
|
||||||
convert = new BsonConvert(this, tiny);
|
convert = new BsonConvert(this, tiny, nullable);
|
||||||
}
|
}
|
||||||
return (BsonConvert) convert;
|
return (BsonConvert) convert;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BsonFactory createChild() {
|
public BsonFactory createChild() {
|
||||||
return new BsonFactory(this, this.tiny);
|
return new BsonFactory(this, this.tiny, this.nullable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BsonFactory createChild(boolean tiny) {
|
public BsonFactory createChild(boolean tiny, boolean nullable) {
|
||||||
return new BsonFactory(this, tiny);
|
return new BsonFactory(this, tiny, nullable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ class BsonStreamWriter extends BsonByteBufferWriter {
|
|||||||
|
|
||||||
private OutputStream out;
|
private OutputStream out;
|
||||||
|
|
||||||
protected BsonStreamWriter(boolean tiny, OutputStream out) {
|
protected BsonStreamWriter(boolean tiny, boolean nullable, OutputStream out) {
|
||||||
super(tiny, null);
|
super(tiny, nullable, null);
|
||||||
this.out = out;
|
this.out = out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ public class BsonWriter extends Writer implements ByteTuple {
|
|||||||
|
|
||||||
protected boolean tiny = BsonFactory.root().tiny();
|
protected boolean tiny = BsonFactory.root().tiny();
|
||||||
|
|
||||||
|
protected boolean nullable = BsonFactory.root().nullable();
|
||||||
|
|
||||||
public static ObjectPool<BsonWriter> createPool(int max) {
|
public static ObjectPool<BsonWriter> createPool(int max) {
|
||||||
return ObjectPool.createSafePool(max, (Object... params) -> new BsonWriter(), null, (t) -> t.recycle());
|
return ObjectPool.createSafePool(max, (Object... params) -> new BsonWriter(), null, (t) -> t.recycle());
|
||||||
}
|
}
|
||||||
@@ -105,6 +107,16 @@ public class BsonWriter extends Writer implements ByteTuple {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean nullable() {
|
||||||
|
return nullable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BsonWriter nullable(boolean nullable) {
|
||||||
|
this.nullable = nullable;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -34,12 +34,13 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
|
|
||||||
private int index;
|
private int index;
|
||||||
|
|
||||||
public JsonByteBufferWriter(boolean tiny, Supplier<ByteBuffer> supplier) {
|
public JsonByteBufferWriter(boolean tiny, boolean nullable, Supplier<ByteBuffer> supplier) {
|
||||||
this(tiny, null, supplier);
|
this(tiny, nullable, null, supplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonByteBufferWriter(boolean tiny, Charset charset, Supplier<ByteBuffer> supplier) {
|
public JsonByteBufferWriter(boolean tiny, boolean nullable, Charset charset, Supplier<ByteBuffer> supplier) {
|
||||||
this.tiny = tiny;
|
this.tiny = tiny;
|
||||||
|
this.nullable = nullable;
|
||||||
this.charset = charset;
|
this.charset = charset;
|
||||||
this.supplier = supplier;
|
this.supplier = supplier;
|
||||||
}
|
}
|
||||||
@@ -311,6 +312,10 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void writeLatin1To(final boolean quote, final String value) {
|
public void writeLatin1To(final boolean quote, final String value) {
|
||||||
|
if (value == null) {
|
||||||
|
writeNull();
|
||||||
|
return;
|
||||||
|
}
|
||||||
byte[] bs = Utility.latin1ByteArray(value);
|
byte[] bs = Utility.latin1ByteArray(value);
|
||||||
int expandsize = expand(bs.length + (quote ? 2 : 0));
|
int expandsize = expand(bs.length + (quote ? 2 : 0));
|
||||||
if (expandsize == 0) {// 只需要一个buffer
|
if (expandsize == 0) {// 只需要一个buffer
|
||||||
@@ -564,6 +569,12 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeLastFieldLatin1Value(final byte[] fieldBytes, final String value) {
|
public void writeLastFieldLatin1Value(final byte[] fieldBytes, final String value) {
|
||||||
|
if (value == null && nullable()) {
|
||||||
|
writeTo(fieldBytes);
|
||||||
|
writeNull();
|
||||||
|
writeTo('}');
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (value == null || (tiny && value.isEmpty())) {
|
if (value == null || (tiny && value.isEmpty())) {
|
||||||
expand(1);
|
expand(1);
|
||||||
this.buffers[index].put((byte) '}');
|
this.buffers[index].put((byte) '}');
|
||||||
@@ -616,6 +627,13 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
|
|
||||||
@Override //firstFieldBytes 必须带{开头
|
@Override //firstFieldBytes 必须带{开头
|
||||||
public void writeObjectByOnlyOneLatin1FieldValue(final byte[] firstFieldBytes, final String value) {
|
public void writeObjectByOnlyOneLatin1FieldValue(final byte[] firstFieldBytes, final String value) {
|
||||||
|
if (value == null && nullable()) {
|
||||||
|
writeTo('{');
|
||||||
|
writeTo(firstFieldBytes);
|
||||||
|
writeNull();
|
||||||
|
writeTo('}');
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (value == null || (tiny && value.isEmpty())) {
|
if (value == null || (tiny && value.isEmpty())) {
|
||||||
int expandsize = expand(2);
|
int expandsize = expand(2);
|
||||||
if (expandsize == 0) { // 只需要一个buffer
|
if (expandsize == 0) { // 只需要一个buffer
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.convert.json;
|
package org.redkale.convert.json;
|
||||||
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.Type;
|
||||||
import java.nio.charset.*;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.function.*;
|
import java.util.function.Consumer;
|
||||||
import org.redkale.convert.*;
|
import org.redkale.convert.*;
|
||||||
import static org.redkale.convert.json.JsonWriter.*;
|
import static org.redkale.convert.json.JsonWriter.*;
|
||||||
import org.redkale.util.*;
|
import org.redkale.util.*;
|
||||||
@@ -55,8 +55,9 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple {
|
|||||||
this.count = array.length();
|
this.count = array.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonBytesWriter(boolean tiny, ByteArray array) {
|
public JsonBytesWriter(boolean tiny, boolean nullable, ByteArray array) {
|
||||||
this.tiny = tiny;
|
this.tiny = tiny;
|
||||||
|
this.nullable = nullable;
|
||||||
this.content = array.content();
|
this.content = array.content();
|
||||||
this.count = array.length();
|
this.count = array.length();
|
||||||
}
|
}
|
||||||
@@ -158,6 +159,10 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void writeLatin1To(final boolean quote, final String value) {
|
public void writeLatin1To(final boolean quote, final String value) {
|
||||||
|
if (value == null) {
|
||||||
|
writeNull();
|
||||||
|
return;
|
||||||
|
}
|
||||||
byte[] bs = Utility.latin1ByteArray(value);
|
byte[] bs = Utility.latin1ByteArray(value);
|
||||||
int len = bs.length;
|
int len = bs.length;
|
||||||
if (quote) {
|
if (quote) {
|
||||||
@@ -271,6 +276,12 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeLastFieldLatin1Value(final byte[] fieldBytes, final String value) {
|
public void writeLastFieldLatin1Value(final byte[] fieldBytes, final String value) {
|
||||||
|
if (value == null && nullable()) {
|
||||||
|
writeTo(fieldBytes);
|
||||||
|
writeNull();
|
||||||
|
writeTo('}');
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (value == null || (tiny && value.isEmpty())) {
|
if (value == null || (tiny && value.isEmpty())) {
|
||||||
expand(1);
|
expand(1);
|
||||||
content[count++] = '}';
|
content[count++] = '}';
|
||||||
@@ -294,6 +305,13 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple {
|
|||||||
|
|
||||||
@Override //firstFieldBytes 必须带{开头
|
@Override //firstFieldBytes 必须带{开头
|
||||||
public void writeObjectByOnlyOneLatin1FieldValue(final byte[] firstFieldBytes, final String value) {
|
public void writeObjectByOnlyOneLatin1FieldValue(final byte[] firstFieldBytes, final String value) {
|
||||||
|
if (value == null && nullable()) {
|
||||||
|
writeTo('{');
|
||||||
|
writeTo(firstFieldBytes);
|
||||||
|
writeNull();
|
||||||
|
writeTo('}');
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (value == null || (tiny && value.isEmpty())) {
|
if (value == null || (tiny && value.isEmpty())) {
|
||||||
expand(2);
|
expand(2);
|
||||||
content[count++] = '{';
|
content[count++] = '{';
|
||||||
|
|||||||
@@ -104,6 +104,10 @@ public class JsonCharsWriter extends JsonWriter {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void writeLatin1To(final boolean quote, final String value) {
|
public void writeLatin1To(final boolean quote, final String value) {
|
||||||
|
if (value == null) {
|
||||||
|
writeNull();
|
||||||
|
return;
|
||||||
|
}
|
||||||
int len = value.length();
|
int len = value.length();
|
||||||
expand(len + (quote ? 2 : 0));
|
expand(len + (quote ? 2 : 0));
|
||||||
if (quote) {
|
if (quote) {
|
||||||
@@ -220,6 +224,12 @@ public class JsonCharsWriter extends JsonWriter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeLastFieldLatin1Value(final byte[] fieldBytes, final String value) {
|
public void writeLastFieldLatin1Value(final byte[] fieldBytes, final String value) {
|
||||||
|
if (value == null && nullable()) {
|
||||||
|
writeTo(fieldBytes);
|
||||||
|
writeNull();
|
||||||
|
writeTo('}');
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (value == null || (tiny && value.isEmpty())) {
|
if (value == null || (tiny && value.isEmpty())) {
|
||||||
expand(1);
|
expand(1);
|
||||||
content[count++] = '}';
|
content[count++] = '}';
|
||||||
@@ -241,6 +251,13 @@ public class JsonCharsWriter extends JsonWriter {
|
|||||||
|
|
||||||
@Override //firstFieldBytes 必须带{开头
|
@Override //firstFieldBytes 必须带{开头
|
||||||
public void writeObjectByOnlyOneLatin1FieldValue(final byte[] firstFieldBytes, final String value) {
|
public void writeObjectByOnlyOneLatin1FieldValue(final byte[] firstFieldBytes, final String value) {
|
||||||
|
if (value == null && nullable()) {
|
||||||
|
writeTo('{');
|
||||||
|
writeTo(firstFieldBytes);
|
||||||
|
writeNull();
|
||||||
|
writeTo('}');
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (value == null || (tiny && value.isEmpty())) {
|
if (value == null || (tiny && value.isEmpty())) {
|
||||||
expand(2);
|
expand(2);
|
||||||
content[count++] = '{';
|
content[count++] = '{';
|
||||||
|
|||||||
@@ -42,13 +42,16 @@ public class JsonConvert extends TextConvert<JsonReader, JsonWriter> {
|
|||||||
|
|
||||||
private final boolean tiny;
|
private final boolean tiny;
|
||||||
|
|
||||||
|
private final boolean nullable;
|
||||||
|
|
||||||
private Encodeable lastConvertEncodeable;
|
private Encodeable lastConvertEncodeable;
|
||||||
|
|
||||||
private Decodeable lastConvertDecodeable;
|
private Decodeable lastConvertDecodeable;
|
||||||
|
|
||||||
protected JsonConvert(JsonFactory factory, boolean tiny) {
|
protected JsonConvert(JsonFactory factory, boolean tiny, boolean nullable) {
|
||||||
super(factory);
|
super(factory);
|
||||||
this.tiny = tiny;
|
this.tiny = tiny;
|
||||||
|
this.nullable = nullable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -77,7 +80,7 @@ public class JsonConvert extends TextConvert<JsonReader, JsonWriter> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonConvert newConvert(final BiFunction<Attribute, Object, Object> objFieldFunc, BiFunction<Object, Object, Object> mapFieldFunc, Function<Object, ConvertField[]> objExtFunc) {
|
public JsonConvert newConvert(final BiFunction<Attribute, Object, Object> objFieldFunc, BiFunction<Object, Object, Object> mapFieldFunc, Function<Object, ConvertField[]> objExtFunc) {
|
||||||
return new JsonConvert(getFactory(), tiny) {
|
return new JsonConvert(getFactory(), tiny, nullable) {
|
||||||
@Override
|
@Override
|
||||||
protected <S extends JsonWriter> S configWrite(S writer) {
|
protected <S extends JsonWriter> S configWrite(S writer) {
|
||||||
return fieldFunc(writer, objFieldFunc, mapFieldFunc, objExtFunc);
|
return fieldFunc(writer, objFieldFunc, mapFieldFunc, objExtFunc);
|
||||||
@@ -112,7 +115,7 @@ public class JsonConvert extends TextConvert<JsonReader, JsonWriter> {
|
|||||||
} else {
|
} else {
|
||||||
bytesWriterPool.set(null);
|
bytesWriterPool.set(null);
|
||||||
}
|
}
|
||||||
return configWrite((JsonBytesWriter) writer.tiny(tiny));
|
return configWrite((JsonBytesWriter) writer.tiny(tiny).nullable(nullable));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -132,7 +135,7 @@ public class JsonConvert extends TextConvert<JsonReader, JsonWriter> {
|
|||||||
} else {
|
} else {
|
||||||
bytesWriterPool.set(null);
|
bytesWriterPool.set(null);
|
||||||
}
|
}
|
||||||
return configWrite((JsonBytesWriter) writer.tiny(tiny));
|
return configWrite((JsonBytesWriter) writer.tiny(tiny).nullable(nullable));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void offerJsonBytesWriter(final JsonBytesWriter writer) {
|
private void offerJsonBytesWriter(final JsonBytesWriter writer) {
|
||||||
@@ -392,7 +395,7 @@ public class JsonConvert extends TextConvert<JsonReader, JsonWriter> {
|
|||||||
@Override
|
@Override
|
||||||
public void convertToBytes(final ByteArray array, final Type type, final Object value) {
|
public void convertToBytes(final ByteArray array, final Type type, final Object value) {
|
||||||
Objects.requireNonNull(array);
|
Objects.requireNonNull(array);
|
||||||
JsonBytesWriter writer = configWrite(new JsonBytesWriter(tiny, array));
|
JsonBytesWriter writer = configWrite(new JsonBytesWriter(tiny, nullable, array));
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
writer.writeNull();
|
writer.writeNull();
|
||||||
} else {
|
} else {
|
||||||
@@ -412,10 +415,10 @@ public class JsonConvert extends TextConvert<JsonReader, JsonWriter> {
|
|||||||
|
|
||||||
public void convertTo(final OutputStream out, final Type type, final Object value) {
|
public void convertTo(final OutputStream out, final Type type, final Object value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
configWrite(new JsonStreamWriter(tiny, out)).writeNull();
|
configWrite(new JsonStreamWriter(tiny, nullable, out)).writeNull();
|
||||||
} else {
|
} else {
|
||||||
final Type t = type == null ? value.getClass() : type;
|
final Type t = type == null ? value.getClass() : type;
|
||||||
JsonStreamWriter writer = configWrite(new JsonStreamWriter(tiny, out));
|
JsonStreamWriter writer = configWrite(new JsonStreamWriter(tiny, nullable, out));
|
||||||
Encodeable encoder = this.lastConvertEncodeable;
|
Encodeable encoder = this.lastConvertEncodeable;
|
||||||
if (encoder == null || encoder.getType() != t) {
|
if (encoder == null || encoder.getType() != t) {
|
||||||
encoder = factory.loadEncoder(t);
|
encoder = factory.loadEncoder(t);
|
||||||
@@ -431,7 +434,7 @@ public class JsonConvert extends TextConvert<JsonReader, JsonWriter> {
|
|||||||
@Override
|
@Override
|
||||||
public ByteBuffer[] convertTo(final Supplier<ByteBuffer> supplier, final Type type, final Object value) {
|
public ByteBuffer[] convertTo(final Supplier<ByteBuffer> supplier, final Type type, final Object value) {
|
||||||
Objects.requireNonNull(supplier);
|
Objects.requireNonNull(supplier);
|
||||||
JsonByteBufferWriter out = configWrite(new JsonByteBufferWriter(tiny, supplier));
|
JsonByteBufferWriter out = configWrite(new JsonByteBufferWriter(tiny, nullable, supplier));
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
out.writeNull();
|
out.writeNull();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -386,7 +386,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
final Map<String, AccessibleObject> mixedNames = mixedNames0;
|
final Map<String, AccessibleObject> mixedNames = mixedNames0;
|
||||||
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||||
final String newDynName = "org/redkaledyn/json/_Dyn" + JsonDynEncoder.class.getSimpleName()
|
final String newDynName = "org/redkaledyn/json/_Dyn" + JsonDynEncoder.class.getSimpleName()
|
||||||
+ "__" + clazz.getName().replace('.', '_').replace('$', '_') + "_" + factory.tiny() + "_" + Utility.md5Hex(memberb.toString()); //tiny必须要加上, 同一个类会有多个字段定制Convert
|
+ "__" + clazz.getName().replace('.', '_').replace('$', '_') + "_" + factory.tiny() + "_" + factory.nullable() + "_" + Utility.md5Hex(memberb.toString()); //tiny必须要加上, 同一个类会有多个字段定制Convert
|
||||||
try {
|
try {
|
||||||
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
|
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
|
||||||
Class newClazz = clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz;
|
Class newClazz = clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz;
|
||||||
@@ -512,7 +512,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
int maxLocals = 4;
|
int maxLocals = 4;
|
||||||
int elementIndex = -1;
|
int elementIndex = -1;
|
||||||
final Class firstType = readGetSetFieldType(members.get(0));
|
final Class firstType = readGetSetFieldType(members.get(0));
|
||||||
final boolean mustHadComma = firstType.isPrimitive() && (firstType != boolean.class || !factory.tiny()); //byte/short/char/int/float/long/double
|
final boolean mustHadComma = firstType.isPrimitive() && (firstType != boolean.class || !factory.tiny() || factory.nullable()); //byte/short/char/int/float/long/double
|
||||||
|
|
||||||
if (onlyOneLatin1FieldObjectFlag) {
|
if (onlyOneLatin1FieldObjectFlag) {
|
||||||
//out.writeObjectByOnlyOneLatin1FieldValue(messageFirstFieldBytes, value.getMessage());elementIndex++;
|
//out.writeObjectByOnlyOneLatin1FieldValue(messageFirstFieldBytes, value.getMessage());elementIndex++;
|
||||||
@@ -670,7 +670,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label msgnotemptyif = null;
|
Label msgnotemptyif = null;
|
||||||
if (!fieldtype.isPrimitive()) { //if (message != null) { start
|
if (!fieldtype.isPrimitive() && !factory.nullable()) { //if (message != null) { start
|
||||||
mv.visitVarInsn(loadid, maxLocals);
|
mv.visitVarInsn(loadid, maxLocals);
|
||||||
msgnotemptyif = new Label();
|
msgnotemptyif = new Label();
|
||||||
mv.visitJumpInsn(IFNULL, msgnotemptyif);
|
mv.visitJumpInsn(IFNULL, msgnotemptyif);
|
||||||
@@ -794,7 +794,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
mv.visitVarInsn(loadid, maxLocals);
|
mv.visitVarInsn(loadid, maxLocals);
|
||||||
mv.visitMethodInsn(INVOKEINTERFACE, encodeableName, "convertTo", "(" + writerDesc + "Ljava/lang/Object;)V", true);
|
mv.visitMethodInsn(INVOKEINTERFACE, encodeableName, "convertTo", "(" + writerDesc + "Ljava/lang/Object;)V", true);
|
||||||
}
|
}
|
||||||
if (!fieldtype.isPrimitive()) { //if (message != null) } end
|
if (!fieldtype.isPrimitive() && !factory.nullable()) { //if (message != null) } end
|
||||||
mv.visitLabel(msgnotemptyif);
|
mv.visitLabel(msgnotemptyif);
|
||||||
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
|
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
|
||||||
} else if (fieldtype == boolean.class && factory.tiny()) {
|
} else if (fieldtype == boolean.class && factory.tiny()) {
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ import org.redkale.util.Uint128;
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public final class JsonFactory extends ConvertFactory<JsonReader, JsonWriter> {
|
public final class JsonFactory extends ConvertFactory<JsonReader, JsonWriter> {
|
||||||
|
|
||||||
private static final JsonFactory instance = new JsonFactory(null, getSystemPropertyBoolean("redkale.convert.json.tiny", "redkale.convert.tiny", false));
|
private static final JsonFactory instance = new JsonFactory(null,
|
||||||
|
getSystemPropertyBoolean("redkale.convert.json.tiny", "redkale.convert.tiny", false),
|
||||||
|
getSystemPropertyBoolean("redkale.convert.json.nullable", "redkale.convert.nullable", false));
|
||||||
|
|
||||||
static {
|
static {
|
||||||
instance.register(Serializable.class, instance.loadEncoder(Object.class));
|
instance.register(Serializable.class, instance.loadEncoder(Object.class));
|
||||||
@@ -33,8 +35,8 @@ public final class JsonFactory extends ConvertFactory<JsonReader, JsonWriter> {
|
|||||||
//instance.register(AnyValue.class, instance.loadEncoder(AnyValue.DefaultAnyValue.class));
|
//instance.register(AnyValue.class, instance.loadEncoder(AnyValue.DefaultAnyValue.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonFactory(JsonFactory parent, boolean tiny) {
|
private JsonFactory(JsonFactory parent, boolean tiny, boolean nullable) {
|
||||||
super(parent, tiny);
|
super(parent, tiny, nullable);
|
||||||
if (parent == null) {
|
if (parent == null) {
|
||||||
this.register(InetAddress.class, InetAddressSimpledCoder.InetAddressJsonSimpledCoder.instance);
|
this.register(InetAddress.class, InetAddressSimpledCoder.InetAddressJsonSimpledCoder.instance);
|
||||||
this.register(InetSocketAddress.class, InetAddressSimpledCoder.InetSocketAddressJsonSimpledCoder.instance);
|
this.register(InetSocketAddress.class, InetAddressSimpledCoder.InetSocketAddressJsonSimpledCoder.instance);
|
||||||
@@ -59,6 +61,12 @@ public final class JsonFactory extends ConvertFactory<JsonReader, JsonWriter> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonFactory nullable(boolean nullable) {
|
||||||
|
this.nullable = nullable;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonFactory skipAllIgnore(final boolean skipIgnore) {
|
public JsonFactory skipAllIgnore(final boolean skipIgnore) {
|
||||||
this.registerSkipAllIgnore(skipIgnore);
|
this.registerSkipAllIgnore(skipIgnore);
|
||||||
@@ -70,7 +78,8 @@ public final class JsonFactory extends ConvertFactory<JsonReader, JsonWriter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static JsonFactory create() {
|
public static JsonFactory create() {
|
||||||
return new JsonFactory(null, getSystemPropertyBoolean("redkale.convert.json.tiny", "redkale.convert.tiny", false));
|
return new JsonFactory(null, getSystemPropertyBoolean("redkale.convert.json.tiny", "redkale.convert.tiny", false),
|
||||||
|
getSystemPropertyBoolean("redkale.convert.json.nullable", "redkale.convert.nullable", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -92,22 +101,26 @@ public final class JsonFactory extends ConvertFactory<JsonReader, JsonWriter> {
|
|||||||
return this.tiny;
|
return this.tiny;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean nullable() {
|
||||||
|
return this.nullable;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final JsonConvert getConvert() {
|
public final JsonConvert getConvert() {
|
||||||
if (convert == null) {
|
if (convert == null) {
|
||||||
convert = new JsonConvert(this, tiny);
|
convert = new JsonConvert(this, tiny, nullable);
|
||||||
}
|
}
|
||||||
return (JsonConvert) convert;
|
return (JsonConvert) convert;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonFactory createChild() {
|
public JsonFactory createChild() {
|
||||||
return new JsonFactory(this, this.tiny);
|
return new JsonFactory(this, this.tiny, this.nullable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonFactory createChild(boolean tiny) {
|
public JsonFactory createChild(boolean tiny, boolean nullable) {
|
||||||
return new JsonFactory(this, tiny);
|
return new JsonFactory(this, tiny, nullable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -21,12 +21,12 @@ class JsonStreamWriter extends JsonByteBufferWriter {
|
|||||||
|
|
||||||
private OutputStream out;
|
private OutputStream out;
|
||||||
|
|
||||||
protected JsonStreamWriter(boolean tiny, OutputStream out) {
|
protected JsonStreamWriter(boolean tiny, boolean nullable, OutputStream out) {
|
||||||
this(tiny, null, out);
|
this(tiny, nullable, null, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JsonStreamWriter(boolean tiny, Charset charset, OutputStream out) {
|
protected JsonStreamWriter(boolean tiny, boolean nullable, Charset charset, OutputStream out) {
|
||||||
super(tiny, charset, null);
|
super(tiny, nullable, charset, null);
|
||||||
this.out = out;
|
this.out = out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,6 +101,10 @@ class JsonStreamWriter extends JsonByteBufferWriter {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void writeLatin1To(final boolean quote, final String value) {
|
public void writeLatin1To(final boolean quote, final String value) {
|
||||||
|
if (value == null) {
|
||||||
|
writeNull();
|
||||||
|
return;
|
||||||
|
}
|
||||||
char[] chs = Utility.charArray(value);
|
char[] chs = Utility.charArray(value);
|
||||||
writeTo(quote, chs, 0, chs.length);
|
writeTo(quote, chs, 0, chs.length);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ public abstract class JsonWriter extends Writer {
|
|||||||
|
|
||||||
protected boolean tiny = JsonFactory.root().tiny();
|
protected boolean tiny = JsonFactory.root().tiny();
|
||||||
|
|
||||||
|
protected boolean nullable = JsonFactory.root().nullable();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tiny() {
|
public boolean tiny() {
|
||||||
return tiny;
|
return tiny;
|
||||||
@@ -37,6 +39,16 @@ public abstract class JsonWriter extends Writer {
|
|||||||
return this.objExtFunc == null && this.objFieldFunc == null;
|
return this.objExtFunc == null && this.objFieldFunc == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean nullable() {
|
||||||
|
return nullable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonWriter nullable(boolean nullable) {
|
||||||
|
this.nullable = nullable;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
public abstract void writeTo(final char ch); //只能是 0 - 127 的字符
|
public abstract void writeTo(final char ch); //只能是 0 - 127 的字符
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,19 @@ import org.redkale.util.*;
|
|||||||
*/
|
*/
|
||||||
public class BsonMainTest {
|
public class BsonMainTest {
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Throwable {
|
||||||
|
BsonMainTest test = new BsonMainTest();
|
||||||
|
test.run1();
|
||||||
|
test.run2();
|
||||||
|
test.run3();
|
||||||
|
test.run4();
|
||||||
|
test.run5();
|
||||||
|
test.run6();
|
||||||
|
test.run7();
|
||||||
|
test.run8();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void run1() throws Throwable {
|
public void run1() throws Throwable {
|
||||||
Serializable[] sers = new Serializable[]{"aaa", 4};
|
Serializable[] sers = new Serializable[]{"aaa", 4};
|
||||||
@@ -38,7 +51,7 @@ public class BsonMainTest {
|
|||||||
SimpleChildEntity entry = SimpleChildEntity.create();
|
SimpleChildEntity entry = SimpleChildEntity.create();
|
||||||
byte[] bytes = convert.convertTo(SimpleEntity.class, entry);
|
byte[] bytes = convert.convertTo(SimpleEntity.class, entry);
|
||||||
System.out.println("长度: " + bytes.length);
|
System.out.println("长度: " + bytes.length);
|
||||||
Assertions.assertEquals(271, bytes.length);
|
Assertions.assertEquals(260, bytes.length);
|
||||||
BsonByteBufferWriter writer = convert.pollWriter(() -> ByteBuffer.allocate(1));
|
BsonByteBufferWriter writer = convert.pollWriter(() -> ByteBuffer.allocate(1));
|
||||||
convert.convertTo(writer, SimpleEntity.class, entry);
|
convert.convertTo(writer, SimpleEntity.class, entry);
|
||||||
ByteBuffer[] buffers = writer.toBuffers();
|
ByteBuffer[] buffers = writer.toBuffers();
|
||||||
@@ -52,7 +65,7 @@ public class BsonMainTest {
|
|||||||
b.flip();
|
b.flip();
|
||||||
}
|
}
|
||||||
System.out.println("长度: " + len);
|
System.out.println("长度: " + len);
|
||||||
Assertions.assertEquals(271, len);
|
Assertions.assertEquals(260, len);
|
||||||
SimpleChildEntity entry2 = convert.convertFrom(SimpleChildEntity.class, buffers);
|
SimpleChildEntity entry2 = convert.convertFrom(SimpleChildEntity.class, buffers);
|
||||||
System.out.println(entry);
|
System.out.println(entry);
|
||||||
Assertions.assertEquals(entry.toString(), entry2.toString());
|
Assertions.assertEquals(entry.toString(), entry2.toString());
|
||||||
|
|||||||
@@ -17,11 +17,21 @@ public class Json5Test {
|
|||||||
public static void main(String[] args) throws Throwable {
|
public static void main(String[] args) throws Throwable {
|
||||||
Json5Test test = new Json5Test();
|
Json5Test test = new Json5Test();
|
||||||
test.main = true;
|
test.main = true;
|
||||||
test.run();
|
test.run1();
|
||||||
|
test.run2();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void run() throws Exception {
|
public void run1() throws Exception {
|
||||||
|
JsonFactory factory = JsonFactory.root().tiny(true).nullable(true);
|
||||||
|
final JsonConvert convert = factory.getConvert();
|
||||||
|
Json5Bean bean = new Json5Bean();
|
||||||
|
bean.id = 60;
|
||||||
|
System.out.println(convert.convertTo(bean));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void run2() throws Exception {
|
||||||
JsonConvert convert = JsonConvert.root();
|
JsonConvert convert = JsonConvert.root();
|
||||||
Json5Bean bean = new Json5Bean();
|
Json5Bean bean = new Json5Bean();
|
||||||
bean.id = 500;
|
bean.id = 500;
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public class JsonMainTest {
|
|||||||
String json = "{\"access_token\":\"null\",\"priv\":null, vvv:nulla,\"priv2\":\"nulla\",\"expires_in\":7200, \"aa\":\"\"}";
|
String json = "{\"access_token\":\"null\",\"priv\":null, vvv:nulla,\"priv2\":\"nulla\",\"expires_in\":7200, \"aa\":\"\"}";
|
||||||
Map<String, String> map = convert.convertFrom(JsonConvert.TYPE_MAP_STRING_STRING, json);
|
Map<String, String> map = convert.convertFrom(JsonConvert.TYPE_MAP_STRING_STRING, json);
|
||||||
System.out.println(map);
|
System.out.println(map);
|
||||||
|
System.out.println(map.get("priv") == null);
|
||||||
String rs = convert.convertTo(map);
|
String rs = convert.convertTo(map);
|
||||||
System.out.println(rs);
|
System.out.println(rs);
|
||||||
ByteBuffer[] buffers = convert.convertTo(() -> ByteBuffer.allocate(1024), map);
|
ByteBuffer[] buffers = convert.convertTo(() -> ByteBuffer.allocate(1024), map);
|
||||||
@@ -52,7 +53,7 @@ public class JsonMainTest {
|
|||||||
SimpleChildEntity entry = SimpleChildEntity.create();
|
SimpleChildEntity entry = SimpleChildEntity.create();
|
||||||
String json = convert.convertTo(SimpleEntity.class, entry);
|
String json = convert.convertTo(SimpleEntity.class, entry);
|
||||||
System.out.println("长度: " + json.length());
|
System.out.println("长度: " + json.length());
|
||||||
JsonByteBufferWriter writer = new JsonByteBufferWriter(false, () -> ByteBuffer.allocate(1)) {
|
JsonByteBufferWriter writer = new JsonByteBufferWriter(false, false, () -> ByteBuffer.allocate(1)) {
|
||||||
};
|
};
|
||||||
convert.convertTo(writer, SimpleEntity.class, entry);
|
convert.convertTo(writer, SimpleEntity.class, entry);
|
||||||
ByteBuffer[] buffers = writer.toBuffers();
|
ByteBuffer[] buffers = writer.toBuffers();
|
||||||
|
|||||||
Reference in New Issue
Block a user