增加RestConvertCoder功能
This commit is contained in:
@@ -45,6 +45,8 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
||||
|
||||
private final ConcurrentHashMap<String, Class> entitys = new ConcurrentHashMap();
|
||||
|
||||
private final ConcurrentHashMap<Type, Map<String, SimpledCoder<R, W, ?>>> fieldCoders = new ConcurrentHashMap();
|
||||
|
||||
private final ConcurrentHashMap<Type, Decodeable<R, ?>> decoders = new ConcurrentHashMap();
|
||||
|
||||
private final ConcurrentHashMap<Type, Encodeable<W, ?>> encoders = new ConcurrentHashMap();
|
||||
@@ -495,6 +497,29 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
||||
encoders.put(clazz, encoder);
|
||||
}
|
||||
|
||||
//coder = null表示删除该字段的指定SimpledCoder
|
||||
public final <E> void register(final Class clazz, final String field, final SimpledCoder<R, W, E> coder) {
|
||||
if (field == null || clazz == null) return;
|
||||
try {
|
||||
clazz.getDeclaredField(field);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(clazz + " not found field(" + field + ")");
|
||||
}
|
||||
if (coder == null) {
|
||||
Map map = this.fieldCoders.get(clazz);
|
||||
if (map != null) map.remove(field);
|
||||
} else {
|
||||
this.fieldCoders.computeIfAbsent(clazz, c -> new ConcurrentHashMap<>()).put(field, coder);
|
||||
}
|
||||
}
|
||||
|
||||
public final <E> SimpledCoder<R, W, E> findFieldCoder(final Type clazz, final String field) {
|
||||
if (field == null) return null;
|
||||
Map<String, SimpledCoder<R, W, ?>> map = this.fieldCoders.get(clazz);
|
||||
if (map == null) return parent == null ? null : parent.findFieldCoder(clazz, field);
|
||||
return (SimpledCoder) map.get(field);
|
||||
}
|
||||
|
||||
public final <E> Decodeable<R, E> findDecoder(final Type type) {
|
||||
Decodeable<R, E> rs = (Decodeable<R, E>) decoders.get(type);
|
||||
if (rs != null) return rs;
|
||||
|
||||
@@ -93,8 +93,12 @@ public class ObjectDecoder<R extends Reader, T> implements Decodeable<R, T> {
|
||||
if (factory.isConvertDisabled(field)) continue;
|
||||
ref = factory.findRef(field);
|
||||
if (ref != null && ref.ignore()) continue;
|
||||
Type t = TypeToken.createClassType(TypeToken.getGenericType(field.getGenericType(), this.type), this.type);
|
||||
DeMember member = new DeMember(ObjectEncoder.createAttribute(factory, clazz, field, null, null), factory.loadDecoder(t));
|
||||
Decodeable<R, ?> fieldCoder = factory.findFieldCoder(clazz, field.getName());
|
||||
if (fieldCoder == null) {
|
||||
Type t = TypeToken.createClassType(TypeToken.getGenericType(field.getGenericType(), this.type), this.type);
|
||||
fieldCoder = factory.loadDecoder(t);
|
||||
}
|
||||
DeMember member = new DeMember(ObjectEncoder.createAttribute(factory, clazz, field, null, null), fieldCoder);
|
||||
if (ref != null) member.index = ref.getIndex();
|
||||
list.add(member);
|
||||
}
|
||||
@@ -118,8 +122,13 @@ public class ObjectDecoder<R extends Reader, T> implements Decodeable<R, T> {
|
||||
}
|
||||
ref = factory.findRef(method);
|
||||
if (ref != null && ref.ignore()) continue;
|
||||
Type t = TypeToken.createClassType(TypeToken.getGenericType(method.getGenericParameterTypes()[0], this.type), this.type);
|
||||
DeMember member = new DeMember(ObjectEncoder.createAttribute(factory, clazz, null, null, method), factory.loadDecoder(t));
|
||||
|
||||
Decodeable<R, ?> fieldCoder = factory.findFieldCoder(clazz, ConvertFactory.readGetSetFieldName(method));
|
||||
if (fieldCoder == null) {
|
||||
Type t = TypeToken.createClassType(TypeToken.getGenericType(method.getGenericParameterTypes()[0], this.type), this.type);
|
||||
fieldCoder = factory.loadDecoder(t);
|
||||
}
|
||||
DeMember member = new DeMember(ObjectEncoder.createAttribute(factory, clazz, null, null, method), fieldCoder);
|
||||
if (ref != null) member.index = ref.getIndex();
|
||||
list.add(member);
|
||||
}
|
||||
|
||||
@@ -77,8 +77,12 @@ public class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T> {
|
||||
if (factory.isConvertDisabled(field)) continue;
|
||||
ref = factory.findRef(field);
|
||||
if (ref != null && ref.ignore()) continue;
|
||||
Type t = TypeToken.createClassType(TypeToken.getGenericType(field.getGenericType(), this.type), this.type);
|
||||
EnMember member = new EnMember(createAttribute(factory, clazz, field, null, null), factory.loadEncoder(t));
|
||||
Encodeable<W, ?> fieldCoder = factory.findFieldCoder(clazz, field.getName());
|
||||
if (fieldCoder == null) {
|
||||
Type t = TypeToken.createClassType(TypeToken.getGenericType(field.getGenericType(), this.type), this.type);
|
||||
fieldCoder = factory.loadEncoder(t);
|
||||
}
|
||||
EnMember member = new EnMember(createAttribute(factory, clazz, field, null, null), fieldCoder);
|
||||
if (ref != null) member.index = ref.getIndex();
|
||||
list.add(member);
|
||||
}
|
||||
@@ -102,8 +106,12 @@ public class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T> {
|
||||
}
|
||||
ref = factory.findRef(method);
|
||||
if (ref != null && ref.ignore()) continue;
|
||||
Type t = TypeToken.createClassType(TypeToken.getGenericType(method.getGenericReturnType(), this.type), this.type);
|
||||
EnMember member = new EnMember(createAttribute(factory, clazz, null, method, null), factory.loadEncoder(t));
|
||||
Encodeable<W, ?> fieldCoder = factory.findFieldCoder(clazz, ConvertFactory.readGetSetFieldName(method));
|
||||
if (fieldCoder == null) {
|
||||
Type t = TypeToken.createClassType(TypeToken.getGenericType(method.getGenericReturnType(), this.type), this.type);
|
||||
fieldCoder = factory.loadEncoder(t);
|
||||
}
|
||||
EnMember member = new EnMember(createAttribute(factory, clazz, null, method, null), fieldCoder);
|
||||
if (ref != null) member.index = ref.getIndex();
|
||||
list.add(member);
|
||||
}
|
||||
|
||||
@@ -127,25 +127,37 @@ public final class Rest {
|
||||
}
|
||||
}
|
||||
|
||||
static JsonConvert createJsonConvert(RestConvert[] converts) {
|
||||
if (converts == null || converts.length < 1) return JsonConvert.root();
|
||||
static JsonConvert createJsonConvert(RestConvert[] converts, RestConvertCoder[] coders) {
|
||||
if ((converts == null || converts.length < 1) && (coders == null || coders.length < 1)) return JsonConvert.root();
|
||||
final JsonFactory childFactory = JsonFactory.create();
|
||||
List<Class> types = new ArrayList<>();
|
||||
for (RestConvert rc : converts) {
|
||||
if (rc.type() == void.class || rc.type() == Void.class) {
|
||||
return JsonFactory.create().skipAllIgnore(true).getConvert();
|
||||
Set<Class> reloadTypes = new HashSet<>();
|
||||
if (coders != null) {
|
||||
for (RestConvertCoder rcc : coders) {
|
||||
reloadTypes.add(rcc.type());
|
||||
childFactory.register(rcc.type(), rcc.field(), Creator.create(rcc.coder()).create());
|
||||
}
|
||||
if (types.contains(rc.type())) throw new RuntimeException("@RestConvert type(" + rc.type() + ") repeat");
|
||||
if (rc.skipIgnore()) {
|
||||
childFactory.registerSkipIgnore(rc.type());
|
||||
childFactory.reloadCoder(rc.type());
|
||||
} else {
|
||||
childFactory.register(rc.type(), false, rc.convertColumns());
|
||||
childFactory.register(rc.type(), true, rc.ignoreColumns());
|
||||
childFactory.reloadCoder(rc.type());
|
||||
}
|
||||
if (converts != null) {
|
||||
for (RestConvert rc : converts) {
|
||||
if (rc.type() == void.class || rc.type() == Void.class) {
|
||||
return JsonFactory.create().skipAllIgnore(true).getConvert();
|
||||
}
|
||||
if (types.contains(rc.type())) throw new RuntimeException("@RestConvert type(" + rc.type() + ") repeat");
|
||||
if (rc.skipIgnore()) {
|
||||
childFactory.registerSkipIgnore(rc.type());
|
||||
childFactory.reloadCoder(rc.type());
|
||||
} else {
|
||||
childFactory.register(rc.type(), false, rc.convertColumns());
|
||||
childFactory.register(rc.type(), true, rc.ignoreColumns());
|
||||
childFactory.reloadCoder(rc.type());
|
||||
}
|
||||
types.add(rc.type());
|
||||
childFactory.tiny(rc.tiny());
|
||||
}
|
||||
types.add(rc.type());
|
||||
childFactory.tiny(rc.tiny());
|
||||
}
|
||||
for (Class type : reloadTypes) {
|
||||
childFactory.reloadCoder(type);
|
||||
}
|
||||
return childFactory.getConvert();
|
||||
}
|
||||
@@ -848,7 +860,7 @@ public final class Rest {
|
||||
final Map<String, List<String>> asmParamMap = MethodParamClassVisitor.getMethodParamNames(new HashMap<>(), serviceType);
|
||||
final Map<String, java.lang.reflect.Type> bodyTypes = new HashMap<>();
|
||||
|
||||
final List<RestConvert[]> restConverts = new ArrayList<>();
|
||||
final List<Object[]> restConverts = new ArrayList<>();
|
||||
for (final MappingEntry entry : entrys) {
|
||||
RestUploadFile mupload = null;
|
||||
Class muploadType = null;
|
||||
@@ -858,7 +870,10 @@ public final class Rest {
|
||||
final Parameter[] params = method.getParameters();
|
||||
|
||||
final RestConvert[] rcs = method.getAnnotationsByType(RestConvert.class);
|
||||
if (rcs != null && rcs.length > 0) restConverts.add(rcs);
|
||||
final RestConvertCoder[] rcc = method.getAnnotationsByType(RestConvertCoder.class);
|
||||
if ((rcs != null && rcs.length > 0) || (rcc != null && rcc.length > 0)) {
|
||||
restConverts.add(new Object[]{rcs, rcc});
|
||||
}
|
||||
|
||||
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, entry.name.replace('/', '$').replace('.', '_'), "(" + reqDesc + respDesc + ")V", null, new String[]{"java/io/IOException"}));
|
||||
//mv.setDebug(true);
|
||||
@@ -1739,7 +1754,9 @@ public final class Rest {
|
||||
for (int i = 0; i < restConverts.size(); i++) {
|
||||
Field genField = newClazz.getDeclaredField(REST_JSONCONVERT_FIELD_PREFIX + (i + 1));
|
||||
genField.setAccessible(true);
|
||||
genField.set(obj, createJsonConvert(restConverts.get(i)));
|
||||
Object[] rc = restConverts.get(i);
|
||||
|
||||
genField.set(obj, createJsonConvert((RestConvert[]) rc[0], (RestConvertCoder[]) rc[1]));
|
||||
}
|
||||
Field typesfield = newClazz.getDeclaredField(REST_PARAMTYPES_FIELD_NAME);
|
||||
typesfield.setAccessible(true);
|
||||
|
||||
43
src/org/redkale/net/http/RestConvertCoder.java
Normal file
43
src/org/redkale/net/http/RestConvertCoder.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.redkale.net.http;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
import org.redkale.convert.*;
|
||||
|
||||
/**
|
||||
* 指定class某个字段的自定义序列化和反序列化策略。 <br>
|
||||
* 只能依附在Service实现类的public方法上, 当方法的返回值以JSON输出时对指定类型的转换设定。 <br>
|
||||
*
|
||||
* <p>
|
||||
* 详情见: https://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
@Inherited
|
||||
@Documented
|
||||
@Target({METHOD})
|
||||
@Retention(RUNTIME)
|
||||
@Repeatable(RestConvertCoder.RestConvertCoders.class)
|
||||
public @interface RestConvertCoder {
|
||||
|
||||
Class type();
|
||||
|
||||
String field();
|
||||
|
||||
Class<? extends SimpledCoder> coder();
|
||||
|
||||
@Inherited
|
||||
@Documented
|
||||
@Target({METHOD})
|
||||
@Retention(RUNTIME)
|
||||
@interface RestConvertCoders {
|
||||
|
||||
RestConvertCoder[] value();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user