This commit is contained in:
Redkale
2022-06-20 11:08:23 +08:00
parent a1e6413704
commit 481cde05bf
17 changed files with 250 additions and 47 deletions

View File

@@ -732,7 +732,10 @@ public final class Application {
if (key.startsWith("redkale.datasource[") || key.startsWith("redkale.cachesource[")) {
sourceProperties.put(key, value);
} else if (key.startsWith("system.property.")) {
System.setProperty(key.substring("system.property.".length()), value);
String propName = key.substring("system.property.".length());
if (System.getProperty(propName) == null) { //命令行传参数优先级高
System.setProperty(propName, value);
}
} else if (key.startsWith("mimetype.property.")) {
MimeType.add(key.substring("mimetype.property.".length()), value);
} else if (key.startsWith("property.")) {

View File

@@ -50,6 +50,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
public LoggingConsoleHandler() {
super();
setFormatter(new LoggingFormater());
configure();
}

View File

@@ -42,6 +42,13 @@ public abstract class Convert<R extends Reader, W extends Writer> {
return writer;
}
protected <S extends W> S fieldFunc(S writer, BiFunction<Object, Object, Object> mapFieldFunc, BiFunction<Attribute, Object, Object> objFieldFunc, Function<Object, ConvertField[]> objExtFunc) {
writer.mapFieldFunc = mapFieldFunc;
writer.objFieldFunc = objFieldFunc;
writer.objExtFunc = objExtFunc;
return writer;
}
public abstract Convert<R, W> newConvert(final BiFunction<Attribute, Object, Object> objFieldFunc);
public abstract Convert<R, W> newConvert(final BiFunction<Attribute, Object, Object> objFieldFunc, Function<Object, ConvertField[]> objExtFunc);

View File

@@ -61,6 +61,8 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
private final Set<Class> skipIgnores = new HashSet();
final Set<String> ignoreMapColumns = new HashSet();
//key:需要屏蔽的字段value排除的字段名
private final ConcurrentHashMap<Class, Set<String>> ignoreAlls = new ConcurrentHashMap();
@@ -707,7 +709,9 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
if (set == null) {
ignoreAlls.put(type, new HashSet<>(Arrays.asList(excludeColumns)));
} else {
set.addAll(Arrays.asList(excludeColumns));
synchronized (set) {
set.addAll(Arrays.asList(excludeColumns));
}
}
}
@@ -716,17 +720,47 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
if (set == null) {
ignoreAlls.put(type, new HashSet<>(excludeColumns));
} else {
set.addAll(new ArrayList(excludeColumns));
synchronized (set) {
set.addAll(new ArrayList(excludeColumns));
}
}
}
public final void register(final Class type, boolean ignore, String... columns) {
if (type == Map.class) {
synchronized (ignoreMapColumns) {
if (ignore) {
for (String column : columns) {
ignoreMapColumns.add(column);
}
} else {
for (String column : columns) {
ignoreMapColumns.remove(column);
}
}
}
return;
}
for (String column : columns) {
register(type, column, new ConvertColumnEntry(column, ignore));
}
}
public final void register(final Class type, boolean ignore, Collection<String> columns) {
if (type == Map.class) {
synchronized (ignoreMapColumns) {
if (ignore) {
for (String column : columns) {
ignoreMapColumns.add(column);
}
} else {
for (String column : columns) {
ignoreMapColumns.remove(column);
}
}
}
return;
}
for (String column : columns) {
register(type, column, new ConvertColumnEntry(column, ignore));
}

View File

@@ -7,7 +7,8 @@ package org.redkale.convert;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.*;
import java.util.function.BiFunction;
/**
* Map的序列化操作类
@@ -32,6 +33,8 @@ public class MapEncoder<K, V> implements Encodeable<Writer, Map<K, V>> {
protected final Object lock = new Object();
protected final Set<String> ignoreMapColumns;
public MapEncoder(final ConvertFactory factory, final Type type) {
this.type = type;
try {
@@ -43,6 +46,9 @@ public class MapEncoder<K, V> implements Encodeable<Writer, Map<K, V>> {
this.keyEncoder = factory.getAnyEncoder();
this.valueEncoder = factory.getAnyEncoder();
}
synchronized (factory.ignoreMapColumns) {
this.ignoreMapColumns = factory.ignoreMapColumns.isEmpty() ? null : new HashSet<>(factory.ignoreMapColumns);
}
} finally {
inited = true;
synchronized (lock) {
@@ -74,11 +80,15 @@ public class MapEncoder<K, V> implements Encodeable<Writer, Map<K, V>> {
}
}
}
Set<String> ignoreColumns = this.ignoreMapColumns;
BiFunction<K, V, V> mapFieldFunc = (BiFunction) out.mapFieldFunc;
if (out.writeMapB(values.size(), (Encodeable) keyEncoder, (Encodeable) valueEncoder, value) < 0) {
boolean first = true;
for (Map.Entry<K, V> en : values.entrySet()) {
if (ignoreColumns != null && ignoreColumns.contains(en.getKey())) continue;
V v = mapFieldFunc == null ? en.getValue() : mapFieldFunc.apply(en.getKey(), en.getValue());
if (!first) out.writeArrayMark();
writeMemberValue(out, member, en.getKey(), en.getValue(), first);
writeMemberValue(out, member, en.getKey(), v, first);
if (first) first = false;
}
}

View File

@@ -25,6 +25,9 @@ public abstract class Writer {
//convertTo时是否以指定Type的ObjectEncoder进行处理
protected Type specify;
//对某个key值进行动态处理仅供MapEncoder使用
protected BiFunction<Object, Object, Object> mapFieldFunc;
//对某个字段值进行动态处理
protected BiFunction<Attribute, Object, Object> objFieldFunc;

View File

@@ -58,16 +58,25 @@ public class JsonConvert extends TextConvert<JsonReader, JsonWriter> {
}
@Override
public JsonConvert newConvert(final BiFunction<Attribute, Object, Object> fieldFunc) {
return newConvert(fieldFunc, null);
public JsonConvert newConvert(final BiFunction<Attribute, Object, Object> objFieldFunc) {
return newConvert(objFieldFunc, null);
}
@Override
public JsonConvert newConvert(final BiFunction<Attribute, Object, Object> fieldFunc, Function<Object, ConvertField[]> objExtFunc) {
public JsonConvert newConvert(final BiFunction<Attribute, Object, Object> objFieldFunc, Function<Object, ConvertField[]> objExtFunc) {
return new JsonConvert(getFactory(), tiny) {
@Override
protected <S extends JsonWriter> S configWrite(S writer) {
return fieldFunc(writer, fieldFunc, objExtFunc);
return fieldFunc(writer, objFieldFunc, objExtFunc);
}
};
}
public JsonConvert newConvert(BiFunction<Object, Object, Object> mapFieldFunc, final BiFunction<Attribute, Object, Object> objFieldFunc, Function<Object, ConvertField[]> objExtFunc) {
return new JsonConvert(getFactory(), tiny) {
@Override
protected <S extends JsonWriter> S configWrite(S writer) {
return fieldFunc(writer, mapFieldFunc, objFieldFunc, objExtFunc);
}
};
}

View File

@@ -34,8 +34,10 @@ public class HttpMessageRequest extends HttpRequest {
return this;
}
public void setRequestURI(String uri) {
@Override
public HttpMessageRequest setRequestURI(String uri) {
this.requestURI = uri;
return this;
}
@Override

View File

@@ -62,6 +62,7 @@ public abstract class PrepareServlet<K extends Serializable, C extends Context,
Set<S> newservlets = new HashSet<>(servlets);
newservlets.remove(servlet);
this.servlets = newservlets;
doAfterRemove(servlet);
}
}
@@ -95,8 +96,9 @@ public abstract class PrepareServlet<K extends Serializable, C extends Context,
synchronized (lock2) {
if (mappings.containsKey(key)) {
Map<K, S> newmappings = new HashMap<>(mappings);
newmappings.remove(key);
S s = newmappings.remove(key);
this.mappings = newmappings;
doAfterRemove(s);
}
}
}
@@ -112,9 +114,13 @@ public abstract class PrepareServlet<K extends Serializable, C extends Context,
}
for (K key : keys) newmappings.remove(key);
this.mappings = newmappings;
doAfterRemove(servlet);
}
}
protected void doAfterRemove(S servlet) {
}
protected S mappingServlet(K key) {
return mappings.get(key);
}

View File

@@ -57,6 +57,19 @@ public abstract class Request<C extends Context> {
this.jsonConvert = context.getJsonConvert();
}
protected Request(Request<C> request) {
this.context = request.context;
this.bsonConvert = request.bsonConvert;
this.jsonConvert = request.jsonConvert;
this.createTime = request.createTime;
this.keepAlive = request.keepAlive;
this.pipelineIndex = request.pipelineIndex;
this.pipelineCount = request.pipelineCount;
this.pipelineOver = request.pipelineOver;
this.hashid = request.hashid;
this.channel = request.channel;
}
protected Request copyHeader() {
return null;
}

View File

@@ -21,4 +21,24 @@ public abstract class HttpFilter extends Filter<HttpContext, HttpRequest, HttpRe
//Server执行start后运行此方法
public void postStart(HttpContext context, AnyValue config) {
}
protected void setMethod(HttpRequest request, String method) {
request.setMethod(method);
}
protected void setRequestURI(HttpRequest request, String requestURI) {
request.setRequestURI(requestURI);
}
protected void setRemoteAddr(HttpRequest request, String remoteAddr) {
request.setRemoteAddr(remoteAddr);
}
protected void setParameter(HttpRequest request, String name, String value) {
request.setParameter(name, value);
}
protected void setHeader(HttpRequest request, String name, String value) {
request.setHeader(name, value);
}
}

View File

@@ -50,6 +50,8 @@ public class HttpPrepareServlet extends PrepareServlet<String, HttpContext, Http
private BiPredicate<String, String>[] forbidURIPredicates; //禁用的URL的Predicate, 必须与 forbidURIMaps 保持一致
private HttpServlet lastRunServlet;
private List<HttpServlet> removeHttpServlet(final Predicate<MappingEntry> predicateEntry, final Predicate<Map.Entry<String, WebSocketServlet>> predicateFilter) {
List<HttpServlet> servlets = new ArrayList<>();
synchronized (allMapStrings) {
@@ -91,6 +93,7 @@ public class HttpPrepareServlet extends PrepareServlet<String, HttpContext, Http
allMapStrings.remove(key);
}
}
this.lastRunServlet = null;
}
return servlets;
}
@@ -365,7 +368,7 @@ public class HttpPrepareServlet extends PrepareServlet<String, HttpContext, Http
} else if (mappingpath != null && !mappingpath.isEmpty()) {
if (servlet._actionmap != null && servlet._actionmap.containsKey(mappingpath)) {
//context.addRequestURINode(mappingpath);
putMapping(mappingpath, new HttpServlet.HttpActionServlet(servlet._actionmap.get(mappingpath), servlet));
putMapping(mappingpath, new HttpServlet.HttpActionServlet(servlet._actionmap.get(mappingpath), servlet, mappingpath));
} else {
putMapping(mappingpath, servlet);
}
@@ -434,6 +437,22 @@ public class HttpPrepareServlet extends PrepareServlet<String, HttpContext, Http
return predicate == null ? servletStream() : servletStream().filter(predicate);
}
@Override
protected HttpServlet mappingServlet(String key) {
HttpServlet last = this.lastRunServlet;
if (last != null && last._actionSimpleMappingUrl != null && last._actionSimpleMappingUrl.equalsIgnoreCase(key)) {
return last;
}
HttpServlet s = super.mappingServlet(key);
this.lastRunServlet = s;
return s;
}
@Override
protected void doAfterRemove(HttpServlet servlet) {
this.lastRunServlet = null;
}
@Override
public void destroy(HttpContext context, AnyValue config) {
super.destroy(context, config); //必须要执行

View File

@@ -840,6 +840,32 @@ public class HttpRequest extends Request<HttpContext> {
}
}
protected HttpRequest setMethod(String method) {
this.method = method;
this.getmethod = "GET".equalsIgnoreCase(method);
return this;
}
protected HttpRequest setRequestURI(String requestURI) {
this.requestURI = requestURI;
return this;
}
protected HttpRequest setRemoteAddr(String remoteAddr) {
this.remoteAddr = remoteAddr;
return this;
}
protected HttpRequest setParameter(String name, String value) {
this.params.put(name, value);
return this;
}
protected HttpRequest setHeader(String name, String value) {
this.headers.put(name, value);
return this;
}
protected static String toDecodeString(ByteArray array, int offset, int len, final Charset charset) {
byte[] content = array.content();
int start = offset;
@@ -2471,14 +2497,14 @@ public class HttpRequest extends Request<HttpContext> {
}
/**
* 获取翻页对象 同 getFlipper("flipper", needcreate, 0);
* 获取翻页对象 同 getFlipper("flipper", autoCreate, 0);
*
* @param needcreate 无参数时是否创建新Flipper对象
* @param autoCreate 无参数时是否创建新Flipper对象
*
* @return Flipper翻页对象
*/
public org.redkale.source.Flipper getFlipper(boolean needcreate) {
return getFlipper(needcreate, 0);
public org.redkale.source.Flipper getFlipper(boolean autoCreate) {
return getFlipper(autoCreate, 0);
}
/**
@@ -2493,44 +2519,46 @@ public class HttpRequest extends Request<HttpContext> {
}
/**
* 获取翻页对象 同 getFlipper("flipper", needcreate, maxLimit)
* 获取翻页对象 同 getFlipper("flipper", autoCreate, maxLimit)
*
* @param needcreate 无参数时是否创建新Flipper对象
* @param autoCreate 无参数时是否创建新Flipper对象
* @param maxLimit 最大行数, 小于1则值为Flipper.DEFAULT_LIMIT
*
* @return Flipper翻页对象
*/
public org.redkale.source.Flipper getFlipper(boolean needcreate, int maxLimit) {
return getFlipper("flipper", needcreate, maxLimit);
public org.redkale.source.Flipper getFlipper(boolean autoCreate, int maxLimit) {
return getFlipper("flipper", autoCreate, maxLimit);
}
/**
* 获取翻页对象 https://redkale.org/pipes/users/list/offset:0/limit:20/sort:createtime%20ASC <br>
* https://redkale.org/pipes/users/list?flipper={'offset':0,'limit':20, 'sort':'createtime ASC'} <br>
* 以上两种接口都可以获取到翻页对象
* 获取翻页对象 https://redkale.org/pipes/users/list?flipper={'offset':0,'limit':20, 'sort':'createtime ASC'} <br>
*
*
* @param name Flipper对象的参数名默认为 "flipper"
* @param needcreate 无参数时是否创建新Flipper对象
* @param autoCreate 无参数时是否创建新Flipper对象
* @param maxLimit 最大行数, 小于1则值为Flipper.DEFAULT_LIMIT
*
* @return Flipper翻页对象
*/
public org.redkale.source.Flipper getFlipper(String name, boolean needcreate, int maxLimit) {
public org.redkale.source.Flipper getFlipper(String name, boolean autoCreate, int maxLimit) {
org.redkale.source.Flipper flipper = getJsonParameter(org.redkale.source.Flipper.class, name);
if (flipper == null) {
if (maxLimit < 1) maxLimit = org.redkale.source.Flipper.DEFAULT_LIMIT;
int limit = getRequstURIPath("limit:", 0);
int offset = getRequstURIPath("offset:", 0);
String sort = getRequstURIPath("sort:", "");
if (limit > 0) {
if (limit > maxLimit) limit = maxLimit;
flipper = new org.redkale.source.Flipper(limit, offset, sort);
}
// if (maxLimit < 1) maxLimit = org.redkale.source.Flipper.DEFAULT_LIMIT;
// String limitstr = getParameter("limit");
// if (limitstr != null && !limitstr.isEmpty()) {
// String offsetstr = getParameter("offset");
// if (offsetstr != null && !offsetstr.isEmpty()) {
// int limit = Integer.parseInt(limitstr);
// int offset = Integer.parseInt(offsetstr);
// String sort = getParameter("sort");
// if (limit > maxLimit) limit = maxLimit;
// flipper = new org.redkale.source.Flipper(limit, offset, sort);
// }
// }
} else if (flipper.getLimit() < 1 || (maxLimit > 0 && flipper.getLimit() > maxLimit)) {
flipper.setLimit(maxLimit);
}
if (flipper != null || !needcreate) return flipper;
if (flipper != null || !autoCreate) return flipper;
if (maxLimit < 1) maxLimit = org.redkale.source.Flipper.DEFAULT_LIMIT;
return new org.redkale.source.Flipper(maxLimit);
}

View File

@@ -33,6 +33,8 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
public static final int RET_METHOD_ERROR = 1200_0002;
String _actionSimpleMappingUrl; //只给HttpActionServlet使用_actionSimpleMappingUrl不能包含正则表达式比如 /json /createRecord, 不能是 /user/**
String _prefix = ""; //当前HttpServlet的path前缀
String _reqtopic; //根据RestService+MQ生成的值 @since 2.5.0
@@ -454,9 +456,12 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
final HttpServlet servlet;
public HttpActionServlet(ActionEntry actionEntry, HttpServlet servlet) {
public HttpActionServlet(ActionEntry actionEntry, HttpServlet servlet, String actionSimpleMappingUrl) {
this.action = actionEntry;
this.servlet = servlet;
if (actionSimpleMappingUrl != null && !Utility.contains(actionSimpleMappingUrl, '*', '{', '[', '(', '|', '^', '$', '+', '?', '\\')) {
this._actionSimpleMappingUrl = actionSimpleMappingUrl;
}
}
@Override

View File

@@ -0,0 +1,43 @@
/*
*/
package org.redkale.test.convert;
import java.util.*;
import org.junit.jupiter.api.*;
import org.redkale.convert.json.*;
/**
*
* @author zhangjx
*/
public class MapIgnoreColumnTest {
private boolean main;
public static void main(String[] args) throws Throwable {
MapIgnoreColumnTest test = new MapIgnoreColumnTest();
test.main = true;
test.run();
}
@Test
public void run() throws Exception {
Map<String, Object> map = new LinkedHashMap<>();
map.put("aaa", "123");
map.put("bbb", List.of(1, 2));
System.out.println(JsonConvert.root().convertTo(map));
JsonFactory factory = JsonFactory.create();
factory.register(Map.class, true, "aaa");
JsonConvert convert = factory.getConvert();
String rs = "{\"bbb\":[1,2]}";
if (!main) Assertions.assertEquals(rs, convert.convertTo(map));
System.out.println(convert.convertTo(map));
JsonConvert convert2 = JsonConvert.root().newConvert((k, v) -> {
if ("bbb".equals(k)) return null;
return v;
}, null, null);
if (!main) Assertions.assertEquals("{\"aaa\":\"123\",\"bbb\":null}", convert2.convertTo(map));
System.out.println(convert2.convertTo(map));
}
}