transferConsumer = resourceFactory::inject;
+ BsonFactory.root().registerTransferConsumer(transferConsumer);
+ JsonFactory.root().registerTransferConsumer(transferConsumer);
+ ProtobufFactory.root().registerTransferConsumer(transferConsumer);
// 系统内部模块组件
moduleEngines.add(this.sourceModule); // 放第一,很多module依赖于source
diff --git a/src/main/java/org/redkale/convert/ConvertColumnEntry.java b/src/main/java/org/redkale/convert/ConvertColumnEntry.java
index 25d3dcd37..e73666868 100644
--- a/src/main/java/org/redkale/convert/ConvertColumnEntry.java
+++ b/src/main/java/org/redkale/convert/ConvertColumnEntry.java
@@ -22,14 +22,17 @@ public final class ConvertColumnEntry {
private ConvertType convertType;
+ private ConvertColumnTransfer transfer;
+
public ConvertColumnEntry() {}
- public ConvertColumnEntry(ConvertColumn column) {
+ public ConvertColumnEntry(ConvertColumn column, ConvertColumnTransfer transfer) {
if (column == null) return;
this.name = column.name();
this.index = column.index();
this.ignore = column.ignore();
this.convertType = column.type();
+ this.transfer = transfer;
}
public ConvertColumnEntry(String name) {
@@ -55,6 +58,19 @@ public final class ConvertColumnEntry {
this.convertType = convertType;
}
+ public ConvertColumnEntry(
+ String name, int index, boolean ignore, ConvertType convertType, ConvertColumnTransfer transfer) {
+ this.name = name;
+ this.index = index;
+ this.ignore = ignore;
+ this.convertType = convertType;
+ this.transfer = transfer;
+ }
+
+ public ConvertColumnTransfer transfer() {
+ return transfer;
+ }
+
public String name() {
return name == null ? "" : name;
}
@@ -89,7 +105,11 @@ public final class ConvertColumnEntry {
@Override
public String toString() {
- return "ConvertColumnEntry{" + "index=" + index + ", name=" + name + ", ignore=" + ignore + ", convertType="
- + convertType + '}';
+ return "ConvertColumnEntry{"
+ + "index=" + index
+ + ", name=" + name
+ + ", ignore=" + ignore
+ + ", convertType=" + convertType
+ + '}';
}
}
diff --git a/src/main/java/org/redkale/convert/ConvertColumnTransfer.java b/src/main/java/org/redkale/convert/ConvertColumnTransfer.java
index 7b7d70da5..1711cb1bf 100644
--- a/src/main/java/org/redkale/convert/ConvertColumnTransfer.java
+++ b/src/main/java/org/redkale/convert/ConvertColumnTransfer.java
@@ -7,10 +7,25 @@ package org.redkale.convert;
import org.redkale.util.Attribute;
/**
+ * 字段值转换器,常见于脱敏操作
+ *
+ * 详情见: https://redkale.org
*
* @author zhangjx
+ * @since 2.8.0
+ *
* @param 字段类型
*/
public interface ConvertColumnTransfer {
- public A transfer(Object obj, Attribute attribute, F value);
+
+ /**
+ * 字段值转换
+ *
+ * @param obj 父对象
+ * @param attribute 属性对象
+ * @param value 字段值
+ *
+ * @return Object
+ */
+ public Object transfer(Object obj, Attribute attribute, F value);
}
diff --git a/src/main/java/org/redkale/convert/ConvertFactory.java b/src/main/java/org/redkale/convert/ConvertFactory.java
index ec8707226..ee42e2ff8 100644
--- a/src/main/java/org/redkale/convert/ConvertFactory.java
+++ b/src/main/java/org/redkale/convert/ConvertFactory.java
@@ -15,6 +15,7 @@ import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
import java.util.regex.Pattern;
import java.util.stream.*;
import org.redkale.annotation.ConstructorParameters;
@@ -59,6 +60,8 @@ public abstract class ConvertFactory {
private final ConcurrentHashMap columnEntrys = new ConcurrentHashMap();
+ private final ConcurrentHashMap transfers = new ConcurrentHashMap();
+
private final Set skipIgnores = new HashSet();
final Set ignoreMapColumns = new HashSet();
@@ -70,6 +73,8 @@ public abstract class ConvertFactory {
private boolean skipAllIgnore = false;
+ private Consumer transferConsumer;
+
protected ConvertFactory(ConvertFactory parent, int features) {
this.features = features;
this.parent = parent;
@@ -445,7 +450,24 @@ public abstract class ConvertFactory {
return new ConvertColumnEntry(realName, true);
}
}
- ConvertColumnEntry entry = new ConvertColumnEntry(ref);
+ ConvertColumnTransfer transfer = null;
+ Class extends ConvertColumnTransfer> transferClass = ref.tranfer();
+ if (transferClass != ConvertColumnTransfer.class) {
+ transfer = findTransfer(transferClass);
+ if (transfer == null) {
+ try {
+ transfer = transferClass.getConstructor().newInstance();
+ } catch (Exception e) {
+ throw new ConvertException(e);
+ }
+ Consumer consumer = findTransferConsumer();
+ if (consumer != null) {
+ consumer.accept(transfer);
+ }
+ register((Class) transferClass, transfer);
+ }
+ }
+ ConvertColumnEntry entry = new ConvertColumnEntry(ref, transfer);
if (skipAllIgnore) {
entry.setIgnore(false);
return entry;
@@ -868,11 +890,27 @@ public abstract class ConvertFactory {
return child;
}
+ private Consumer findTransferConsumer() {
+ if (transferConsumer != null) {
+ return transferConsumer;
+ }
+ return parent == null ? null : parent.findTransferConsumer();
+ }
+
private Class findEntityAlias(String name) {
Class clazz = entitys.get(name);
return parent == null ? clazz : parent.findEntityAlias(name);
}
+ /**
+ * 设置ConvertColumnTransfer初始化的处理函数
+ *
+ * @param consumer ConvertColumnTransfer处理函数
+ */
+ public final void registerTransferConsumer(Consumer consumer) {
+ this.transferConsumer = consumer;
+ }
+
/**
* 使所有类的所有被声明为ConvertColumn.ignore = true 的字段或方法变为ConvertColumn.ignore = false
*
@@ -922,9 +960,7 @@ public abstract class ConvertFactory {
ignoreMapColumnLock.lock();
try {
if (ignore) {
- for (String column : columns) {
- ignoreMapColumns.add(column);
- }
+ ignoreMapColumns.addAll(List.of(columns));
} else {
for (String column : columns) {
ignoreMapColumns.remove(column);
@@ -945,9 +981,7 @@ public abstract class ConvertFactory {
ignoreMapColumnLock.lock();
try {
if (ignore) {
- for (String column : columns) {
- ignoreMapColumns.add(column);
- }
+ ignoreMapColumns.addAll(columns);
} else {
for (String column : columns) {
ignoreMapColumns.remove(column);
@@ -1007,7 +1041,7 @@ public abstract class ConvertFactory {
return field == null || register(field, entry);
}
- public final boolean register(final AccessibleObject field, final ConvertColumnEntry entry) {
+ public final boolean register(final AccessibleObject field, final ConvertColumnEntry entry) {
if (field == null || entry == null) {
return false;
}
@@ -1048,11 +1082,23 @@ public abstract class ConvertFactory {
return result;
}
+ public final ConvertColumnTransfer findTransfer(Class type) {
+ ConvertColumnTransfer transfer = transfers.get(type);
+ if (transfer != null) {
+ return transfer;
+ }
+ return this.parent == null ? null : this.parent.findTransfer(type);
+ }
+
// ----------------------------------------------------------------------
public final Encodeable getAnyEncoder() {
return (Encodeable) anyEncoder;
}
+ public final void register(final Class clazz, final C transfer) {
+ transfers.put(Objects.requireNonNull(clazz), Objects.requireNonNull(transfer));
+ }
+
public final void register(final Type clazz, final SimpledCoder coder) {
decoders.put(clazz, coder);
encoders.put(clazz, coder);
diff --git a/src/main/java/org/redkale/convert/DeMember.java b/src/main/java/org/redkale/convert/DeMember.java
index c62608a1b..b3f428a3e 100644
--- a/src/main/java/org/redkale/convert/DeMember.java
+++ b/src/main/java/org/redkale/convert/DeMember.java
@@ -7,7 +7,6 @@ package org.redkale.convert;
import java.lang.reflect.*;
import org.redkale.annotation.Comment;
-import org.redkale.persistence.Column;
import org.redkale.util.Attribute;
/**
@@ -45,20 +44,10 @@ public final class DeMember {
this.method = method;
if (field != null) {
Comment ct = field.getAnnotation(Comment.class);
- if (ct == null) {
- Column col = field.getAnnotation(Column.class);
- this.comment = col == null ? "" : col.comment();
- } else {
- this.comment = ct.value();
- }
+ this.comment = ct == null ? "" : ct.value();
} else if (method != null) {
Comment ct = method.getAnnotation(Comment.class);
- if (ct == null) {
- Column col = method.getAnnotation(Column.class);
- this.comment = col == null ? "" : col.comment();
- } else {
- this.comment = ct.value();
- }
+ this.comment = ct == null ? "" : ct.value();
} else {
this.comment = "";
}
diff --git a/src/main/java/org/redkale/convert/EnMember.java b/src/main/java/org/redkale/convert/EnMember.java
index 1f1303095..67eb4c63e 100644
--- a/src/main/java/org/redkale/convert/EnMember.java
+++ b/src/main/java/org/redkale/convert/EnMember.java
@@ -7,7 +7,6 @@ package org.redkale.convert;
import java.lang.reflect.*;
import org.redkale.annotation.Comment;
-import org.redkale.persistence.Column;
import org.redkale.util.Attribute;
/**
@@ -42,17 +41,25 @@ public final class EnMember {
final Method method; // 对应类成员的Method也可能为null
+ final ConvertColumnTransfer transfer; // 一般为null
+
int index;
int position; // 从1开始
int tag; // 主要给protobuf使用
- public EnMember(Attribute attribute, Encodeable encoder, Field field, Method method) {
+ public EnMember(
+ Attribute attribute,
+ Encodeable encoder,
+ Field field,
+ Method method,
+ ConvertColumnTransfer transfer) {
this.attribute = attribute;
this.encoder = encoder;
this.field = field;
this.method = method;
+ this.transfer = transfer;
Class t = attribute.type();
this.string = CharSequence.class.isAssignableFrom(t);
this.bool = t == Boolean.class || t == boolean.class;
@@ -60,20 +67,10 @@ public final class EnMember {
this.jsonFieldNameBytes = ('"' + attribute.field() + "\":").getBytes();
if (field != null) {
Comment ct = field.getAnnotation(Comment.class);
- if (ct == null) {
- Column col = field.getAnnotation(Column.class);
- this.comment = col == null ? "" : col.comment();
- } else {
- this.comment = ct.value();
- }
+ this.comment = ct == null ? "" : ct.value();
} else if (method != null) {
Comment ct = method.getAnnotation(Comment.class);
- if (ct == null) {
- Column col = method.getAnnotation(Column.class);
- this.comment = col == null ? "" : col.comment();
- } else {
- this.comment = ct.value();
- }
+ this.comment = ct == null ? "" : ct.value();
} else {
this.comment = "";
}
@@ -84,7 +81,8 @@ public final class EnMember {
final ConvertFactory factory, final Class clazz, final String fieldname) {
try {
Field field = clazz.getDeclaredField(fieldname);
- return new EnMember<>(Attribute.create(field), factory.loadEncoder(field.getGenericType()), field, null);
+ return new EnMember<>(
+ Attribute.create(field), factory.loadEncoder(field.getGenericType()), field, null, null);
} catch (Exception e) {
throw new ConvertException(e);
}
@@ -95,7 +93,7 @@ public final class EnMember {
try {
Field field = clazz.getDeclaredField(fieldname);
return new EnMember<>(
- Attribute.create(clazz, fieldname, fieldtype), factory.loadEncoder(fieldtype), field, null);
+ Attribute.create(clazz, fieldname, fieldtype), factory.loadEncoder(fieldtype), field, null, null);
} catch (Exception e) {
throw new ConvertException(e);
}
@@ -103,11 +101,16 @@ public final class EnMember {
public static EnMember create(
final Attribute attribute, final ConvertFactory factory, final Class fieldtype) {
- return new EnMember<>(attribute, factory.loadEncoder(fieldtype), null, null);
+ return new EnMember<>(attribute, factory.loadEncoder(fieldtype), null, null, null);
}
- public F getFieldValue(T obj) {
- return attribute.get(obj);
+ public Object getFieldValue(T obj) {
+ F val = attribute.get(obj);
+ if (transfer != null) {
+ return transfer.transfer(obj, attribute, val);
+ } else {
+ return val;
+ }
}
public final boolean accepts(String name) {
diff --git a/src/main/java/org/redkale/convert/ObjectEncoder.java b/src/main/java/org/redkale/convert/ObjectEncoder.java
index f93514d42..4fadcfc7a 100644
--- a/src/main/java/org/redkale/convert/ObjectEncoder.java
+++ b/src/main/java/org/redkale/convert/ObjectEncoder.java
@@ -106,7 +106,11 @@ public class ObjectEncoder implements Encodeable {
fieldCoder = colFactory.loadEncoder(t);
}
EnMember member = new EnMember(
- createAttribute(colFactory, type, clazz, field, null, null), fieldCoder, field, null);
+ createAttribute(colFactory, type, clazz, field, null, null),
+ fieldCoder,
+ field,
+ null,
+ ref == null ? null : ref.transfer());
if (ref != null) {
member.index = ref.getIndex();
}
@@ -189,7 +193,8 @@ public class ObjectEncoder implements Encodeable {
createAttribute(colFactory, type, clazz, null, method, null),
fieldCoder,
maybeField,
- method);
+ method,
+ ref == null ? null : ref.transfer());
if (Utility.contains(list, m -> m.attribute.field().equals(member.attribute.field()))) {
continue;
}
@@ -214,7 +219,11 @@ public class ObjectEncoder implements Encodeable {
// Type t = TypeToken.createClassType(f.getGenericType(), this.type);
try {
EnMember member = new EnMember(
- createAttribute(factory, type, clazz, f, null, null), null, f, null);
+ createAttribute(factory, type, clazz, f, null, null),
+ null,
+ f,
+ null,
+ ref2 == null ? null : ref2.transfer());
if (ref2 != null) {
member.index = ref2.getIndex();
}
@@ -238,7 +247,11 @@ public class ObjectEncoder implements Encodeable {
// this.type), this.type);
try {
EnMember member = new EnMember(
- createAttribute(factory, type, clazz, null, getter, null), null, null, null);
+ createAttribute(factory, type, clazz, null, getter, null),
+ null,
+ null,
+ null,
+ ref2 == null ? null : ref2.transfer());
if (ref2 != null) {
member.index = ref2.getIndex();
}
diff --git a/src/main/java/org/redkale/convert/json/JsonDynEncoder.java b/src/main/java/org/redkale/convert/json/JsonDynEncoder.java
index ac75bccc9..cb92a24bb 100644
--- a/src/main/java/org/redkale/convert/json/JsonDynEncoder.java
+++ b/src/main/java/org/redkale/convert/json/JsonDynEncoder.java
@@ -5,13 +5,12 @@
*/
package org.redkale.convert.json;
-import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES;
-import static org.redkale.asm.Opcodes.*;
-
import java.lang.reflect.*;
import java.lang.reflect.Type;
import java.util.*;
import org.redkale.asm.*;
+import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES;
+import static org.redkale.asm.Opcodes.*;
import org.redkale.convert.*;
import org.redkale.convert.ext.*;
import org.redkale.util.*;
@@ -258,6 +257,9 @@ public abstract class JsonDynEncoder implements Encodeable {
if (ref != null && ref.ignore()) {
continue;
}
+ if (ref != null && ref.transfer() != null) {
+ return null;
+ }
if (!(checkMemberType(factory, clazz, method.getGenericReturnType(), method.getReturnType()))) {
return null;
}
diff --git a/src/test/java/org/redkale/test/convert/ConvertTransferTest.java b/src/test/java/org/redkale/test/convert/ConvertTransferTest.java
new file mode 100644
index 000000000..8f1e80bc4
--- /dev/null
+++ b/src/test/java/org/redkale/test/convert/ConvertTransferTest.java
@@ -0,0 +1,72 @@
+/*
+
+*/
+
+package org.redkale.test.convert;
+
+import org.junit.jupiter.api.*;
+import org.redkale.convert.ConvertColumn;
+import org.redkale.convert.ConvertColumnTransfer;
+import org.redkale.convert.json.JsonConvert;
+import org.redkale.util.Attribute;
+
+/**
+ *
+ * @author zhangjx
+ */
+public class ConvertTransferTest {
+
+ public static void main(String[] args) throws Throwable {
+ ConvertTransferTest test = new ConvertTransferTest();
+ test.run1();
+ }
+
+ @Test
+ public void run1() throws Throwable {
+ ParamRequest param = new ParamRequest();
+ param.setName("haha");
+ param.setPhone("1381234500");
+ Assertions.assertEquals("{\"name\":\"haha\",\"phone\":\"138****00\"}", param.toString());
+ }
+
+ public static class ParamRequest {
+
+ private String name;
+
+ @ConvertColumn(tranfer = ParamTransfer.class)
+ private String phone;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ @Override
+ public String toString() {
+ return JsonConvert.root().convertTo(this);
+ }
+ }
+
+ public static class ParamTransfer implements ConvertColumnTransfer {
+
+ @Override
+ public Object transfer(Object obj, Attribute attribute, String value) {
+ if (value == null || value.length() < 5) {
+ return value;
+ } else {
+ return value.substring(0, 3) + "****" + value.substring(value.length() - 2);
+ }
+ }
+ }
+}
diff --git a/src/test/java/org/redkale/test/convert/CustMessage2Test.java b/src/test/java/org/redkale/test/convert/CustMessage2Test.java
index d7c8a0e93..d59d0fe0a 100644
--- a/src/test/java/org/redkale/test/convert/CustMessage2Test.java
+++ b/src/test/java/org/redkale/test/convert/CustMessage2Test.java
@@ -77,14 +77,14 @@ public class CustMessage2Test {
protected void afterInitEnMember(ConvertFactory factory) {
Function func1 = t -> eventName;
Attribute attribute1 = Attribute.create(clazz, "event", String.class, func1, null);
- EnMember member1 = new EnMember(attribute1, factory.loadEncoder(String.class), null, null);
+ EnMember member1 = new EnMember(attribute1, factory.loadEncoder(String.class), null, null, null);
setIndex(member1, 1);
setPosition(member1, 1);
initForEachEnMember(factory, member1);
Function func2 = t -> t;
Attribute attribute2 = Attribute.create(clazz, "result", clazz, func2, null);
- EnMember member2 = new EnMember(attribute2, valEncoder, null, null);
+ EnMember member2 = new EnMember(attribute2, valEncoder, null, null, null);
setIndex(member2, 2);
setPosition(member2, 2);
initForEachEnMember(factory, member2);
diff --git a/src/test/java/org/redkale/test/convert/CustMessageTest.java b/src/test/java/org/redkale/test/convert/CustMessageTest.java
index cc9c93d63..161e3a0e9 100644
--- a/src/test/java/org/redkale/test/convert/CustMessageTest.java
+++ b/src/test/java/org/redkale/test/convert/CustMessageTest.java
@@ -2,10 +2,9 @@
*/
package org.redkale.test.convert;
+import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.*;
import java.util.function.*;
import org.junit.jupiter.api.*;
import org.redkale.convert.*;
@@ -73,7 +72,7 @@ public class CustMessageTest {
protected void afterInitEnMember(ConvertFactory factory) {
Function func = t -> t;
Attribute attribute = Attribute.create(clazz, getMessageName(clazz), clazz, func, null);
- EnMember member = new EnMember(attribute, valEncoder, null, null);
+ EnMember member = new EnMember(attribute, valEncoder, null, null, null);
setIndex(member, 1);
setPosition(member, 1);
initForEachEnMember(factory, member);
diff --git a/src/test/java/org/redkale/test/convert/proto/PBCustMessage2Test.java b/src/test/java/org/redkale/test/convert/proto/PBCustMessage2Test.java
index 15efff1cb..4e1ebb82d 100644
--- a/src/test/java/org/redkale/test/convert/proto/PBCustMessage2Test.java
+++ b/src/test/java/org/redkale/test/convert/proto/PBCustMessage2Test.java
@@ -97,14 +97,14 @@ public class PBCustMessage2Test {
protected void afterInitEnMember(ConvertFactory factory) {
Function func1 = t -> eventName;
Attribute attribute1 = Attribute.create(clazz, "event", String.class, func1, null);
- EnMember member1 = new EnMember(attribute1, factory.loadEncoder(String.class), null, null);
+ EnMember member1 = new EnMember(attribute1, factory.loadEncoder(String.class), null, null, null);
setIndex(member1, 1);
setPosition(member1, 1);
initForEachEnMember(factory, member1);
Function func2 = t -> t;
Attribute attribute2 = Attribute.create(clazz, "data", clazz, func2, null);
- EnMember member2 = new EnMember(attribute2, valEncoder, null, null);
+ EnMember member2 = new EnMember(attribute2, valEncoder, null, null, null);
setIndex(member2, 2);
setPosition(member2, 2);
initForEachEnMember(factory, member2);
diff --git a/src/test/java/org/redkale/test/convert/proto/PBCustMessageTest.java b/src/test/java/org/redkale/test/convert/proto/PBCustMessageTest.java
index 5b35a6f6b..b1dabe002 100644
--- a/src/test/java/org/redkale/test/convert/proto/PBCustMessageTest.java
+++ b/src/test/java/org/redkale/test/convert/proto/PBCustMessageTest.java
@@ -2,10 +2,9 @@
*/
package org.redkale.test.convert.proto;
+import java.lang.annotation.*;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.*;
import java.util.*;
import java.util.function.*;
import org.junit.jupiter.api.*;
@@ -84,7 +83,7 @@ public class PBCustMessageTest {
protected void afterInitEnMember(ConvertFactory factory) {
Function func = t -> t;
Attribute attribute = Attribute.create(clazz, getMessageName(clazz), clazz, func, null);
- EnMember member = new EnMember(attribute, valEncoder, null, null);
+ EnMember member = new EnMember(attribute, valEncoder, null, null, null);
setIndex(member, 1);
setPosition(member, 1);
initForEachEnMember(factory, member);