diff --git a/arex-agent-bootstrap/src/main/java/io/arex/agent/bootstrap/util/StringUtil.java b/arex-agent-bootstrap/src/main/java/io/arex/agent/bootstrap/util/StringUtil.java
index 5d67425a9..89b6af41b 100644
--- a/arex-agent-bootstrap/src/main/java/io/arex/agent/bootstrap/util/StringUtil.java
+++ b/arex-agent-bootstrap/src/main/java/io/arex/agent/bootstrap/util/StringUtil.java
@@ -550,4 +550,17 @@ public static Integer getFirstNumeric(String s) {
public static boolean isNullWord(String str) {
return equals(str, "null") || equals(str, "NULL");
}
+
+ public static int countMatches(final String str, final String sub) {
+ if (isEmpty(str) || isEmpty(sub)) {
+ return 0;
+ }
+ int count = 0;
+ int idx = 0;
+ while ((idx = CharSequenceUtils.indexOf(str, sub, idx)) != INDEX_NOT_FOUND) {
+ count++;
+ idx += sub.length();
+ }
+ return count;
+ }
}
diff --git a/arex-instrumentation-api/src/main/java/io/arex/inst/runtime/model/ArexConstants.java b/arex-instrumentation-api/src/main/java/io/arex/inst/runtime/model/ArexConstants.java
index 4fff6f618..2a67c0aa2 100644
--- a/arex-instrumentation-api/src/main/java/io/arex/inst/runtime/model/ArexConstants.java
+++ b/arex-instrumentation-api/src/main/java/io/arex/inst/runtime/model/ArexConstants.java
@@ -31,6 +31,9 @@ private ArexConstants() {}
public static final String REPLAY_ORIGINAL_MOCKER = "arex-replay-original-mocker";
public static final String AREX_EXTENSION_ATTRIBUTE = "arex-extension-attribute";
public static final String GSON_SERIALIZER = "gson";
+ public static final String GSON_REQUEST_SERIALIZER = "gson-request";
+ public static final String JACKSON_SERIALIZER = "jackson";
+ public static final String JACKSON_REQUEST_SERIALIZER = "jackson-request";
public static final String CONFIG_DEPENDENCY = "arex_replay_prepare_dependency";
public static final String PREFIX = "arex-";
public static final String CONFIG_VERSION = "configBatchNo";
diff --git a/arex-instrumentation-api/src/main/java/io/arex/inst/runtime/serializer/Serializer.java b/arex-instrumentation-api/src/main/java/io/arex/inst/runtime/serializer/Serializer.java
index 778716a23..b59bd1c0e 100644
--- a/arex-instrumentation-api/src/main/java/io/arex/inst/runtime/serializer/Serializer.java
+++ b/arex-instrumentation-api/src/main/java/io/arex/inst/runtime/serializer/Serializer.java
@@ -122,6 +122,19 @@ public static String serialize(Object object, String serializer) {
}
}
+// public static String serializeRequest(Object object) {
+// return serializeRequest(object, ArexConstants.JACKSON_REQUEST_SERIALIZER);
+// }
+//
+// public static String serializeRequest(Object object, String serializer) {
+// try {
+// return serializeWithException(object, serializer);
+// } catch (Throwable ex) {
+// LogManager.warn("serializeRequest", StringUtil.format("can not serialize object: %s, cause: %s", TypeUtil.errorSerializeToString(object), ex.toString()));
+// return null;
+// }
+// }
+
/**
* Deserialize by Class
*
diff --git a/arex-instrumentation-foundation/pom.xml b/arex-instrumentation-foundation/pom.xml
index 0c212f70f..1fc1b551a 100644
--- a/arex-instrumentation-foundation/pom.xml
+++ b/arex-instrumentation-foundation/pom.xml
@@ -84,6 +84,16 @@
2.6
test
+
+ org.openjdk.jmh
+ jmh-core
+ 1.23
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ 1.23
+
diff --git a/arex-instrumentation-foundation/src/main/java/io/arex/foundation/serializer/GsonRequestSerializer.java b/arex-instrumentation-foundation/src/main/java/io/arex/foundation/serializer/GsonRequestSerializer.java
new file mode 100644
index 000000000..bffac88e5
--- /dev/null
+++ b/arex-instrumentation-foundation/src/main/java/io/arex/foundation/serializer/GsonRequestSerializer.java
@@ -0,0 +1,104 @@
+package io.arex.foundation.serializer;
+
+import com.google.auto.service.AutoService;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import io.arex.foundation.serializer.custom.ProtobufAdapterFactory;
+import io.arex.foundation.serializer.custom.SerializerExclusionStrategy;
+import io.arex.foundation.serializer.custom.StringAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.CalendarAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.ClassAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.DateAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.DateTimeAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.InstantAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.JodaLocalDateAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.JodaLocalDateTimeAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.JodaLocalTimeAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.LocalDateAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.LocalDateTimeAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.LocalTimeAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.OffsetDateTimeAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.TimeZoneAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.XMLGregorianCalendarAdapter;
+import io.arex.inst.runtime.serializer.StringSerializable;
+import org.joda.time.DateTime;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import java.lang.reflect.Type;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+@AutoService(StringSerializable.class)
+public class GsonRequestSerializer implements StringSerializable{
+
+ public static GsonRequestSerializer INSTANCE = new GsonRequestSerializer();
+ private final Gson serializer;
+
+ public GsonRequestSerializer() {
+ this.serializer = new GsonBuilder()
+ .registerTypeAdapter(DateTime.class, new DateTimeAdapter.GsonSerializer(true))
+ .registerTypeAdapter(org.joda.time.LocalDateTime.class, new JodaLocalDateTimeAdapter.GsonSerializer(true))
+ .registerTypeAdapter(org.joda.time.LocalDate.class, new JodaLocalDateAdapter.GsonSerializer())
+ .registerTypeAdapter(org.joda.time.LocalTime.class, new JodaLocalTimeAdapter.GsonSerializer(true))
+ .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter.GsonSerializer(true))
+ .registerTypeAdapter(LocalDate.class, new LocalDateAdapter.GsonSerializer())
+ .registerTypeAdapter(LocalTime.class, new LocalTimeAdapter.GsonSerializer(true))
+ .registerTypeAdapter(Calendar.class, new CalendarAdapter.GsonSerializer(true))
+ .registerTypeAdapter(GregorianCalendar.class, new CalendarAdapter.GsonSerializer(true))
+ .registerTypeAdapter(XMLGregorianCalendar.class, new XMLGregorianCalendarAdapter.GsonSerializer(true))
+ .registerTypeAdapter(Timestamp.class, new DateAdapter.GsonSerializer(true))
+ .registerTypeAdapter(Date.class, new DateAdapter.GsonSerializer(true))
+ .registerTypeAdapter(java.sql.Date.class, new DateAdapter.GsonSerializer(true))
+ .registerTypeAdapter(Time.class, new DateAdapter.GsonSerializer(true))
+ .registerTypeAdapter(Instant.class, new InstantAdapter.GsonSerializer(true))
+ .registerTypeAdapter(Class.class, new ClassAdapter.GsonSerializer())
+ .registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeAdapter.GsonSerializer(true))
+ .registerTypeAdapter(TimeZone.class, new TimeZoneAdapter.GsonSerializer())
+ .registerTypeAdapter(String.class, new StringAdapter.GsonSerializer())
+ .registerTypeAdapterFactory(new ProtobufAdapterFactory())
+ .enableComplexMapKeySerialization()
+ .setExclusionStrategies(new SerializerExclusionStrategy.GsonExclusion())
+ .disableHtmlEscaping()
+ .create();
+ }
+
+ @Override
+ public String name() {
+ return "gson-request";
+ }
+
+ @Override
+ public String serialize(Object object) throws Throwable {
+ if (object == null) {
+ return null;
+ }
+ return serializer.toJson(object);
+ }
+
+ @Override
+ public T deserialize(String value, Class clazz) throws Throwable {
+ // request serializer not need deserialize
+ return null;
+ }
+
+ @Override
+ public T deserialize(String value, Type type) throws Throwable {
+ // request serializer not need deserialize
+ return null;
+ }
+
+ @Override
+ public StringSerializable reCreateSerializer() {
+ INSTANCE = new GsonRequestSerializer();
+ return INSTANCE;
+ }
+}
diff --git a/arex-instrumentation-foundation/src/main/java/io/arex/foundation/serializer/GsonSerializer.java b/arex-instrumentation-foundation/src/main/java/io/arex/foundation/serializer/GsonSerializer.java
index c74d68113..7a70d8139 100644
--- a/arex-instrumentation-foundation/src/main/java/io/arex/foundation/serializer/GsonSerializer.java
+++ b/arex-instrumentation-foundation/src/main/java/io/arex/foundation/serializer/GsonSerializer.java
@@ -3,8 +3,6 @@
import com.google.auto.service.AutoService;
import com.google.common.collect.Range;
-import io.arex.agent.thirdparty.util.time.DateFormatUtils;
-import io.arex.foundation.serializer.JacksonSerializer.DateFormatParser;
import io.arex.foundation.serializer.custom.FastUtilAdapterFactory;
import io.arex.foundation.serializer.custom.GuavaRangeSerializer;
import io.arex.agent.bootstrap.util.StringUtil;
@@ -13,23 +11,40 @@
import io.arex.foundation.serializer.custom.NumberStrategy;
import io.arex.foundation.serializer.custom.ProtobufAdapterFactory;
+import io.arex.foundation.serializer.custom.SerializerExclusionStrategy;
+import io.arex.foundation.serializer.custom.StringAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.CalendarAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.ClassAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.DateAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.DateTimeAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.GregorianCalendarAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.InstantAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.JodaLocalDateAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.JodaLocalDateTimeAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.JodaLocalTimeAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.LocalDateAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.LocalDateTimeAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.LocalTimeAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.OffsetDateTimeAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.SqlDateAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.SqlTimeAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.TimeZoneAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.TimestampAdapter;
+import io.arex.foundation.serializer.custom.time.adapter.XMLGregorianCalendarAdapter;
import io.arex.inst.runtime.log.LogManager;
import io.arex.inst.runtime.serializer.StringSerializable;
import io.arex.inst.runtime.util.TypeUtil;
+
import java.sql.Time;
import java.time.Instant;
import java.time.OffsetDateTime;
-import java.time.format.DateTimeFormatter;
import java.util.Map.Entry;
import org.joda.time.DateTime;
-import org.joda.time.DateTimeZone;
-import org.joda.time.format.DateTimeFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.*;
-import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.lang.reflect.Type;
import java.sql.Timestamp;
@@ -42,133 +57,6 @@
public class GsonSerializer implements StringSerializable {
private static final Logger LOGGER = LoggerFactory.getLogger(GsonSerializer.class);
- private static final JsonSerializer DATE_TIME_JSON_SERIALIZER =
- ((src, typeOfSrc, context) -> new JsonPrimitive(src.toString(JacksonSerializer.DatePatternConstants.SIMPLE_DATE_FORMAT_WITH_TIMEZONE_DATETIME)));
- private static final JsonDeserializer DATE_TIME_JSON_DESERIALIZER =
- (json, type, context) -> {
- TimeZone timeZone = JacksonSerializer.TimezoneParser.INSTANCE.parse(json.getAsString());
- DateTimeZone dateTimeZone = DateTimeZone.forTimeZone(timeZone);
- Date date = DateFormatParser.INSTANCE.parseDate(json.getAsString(), timeZone);
- if (date == null) {
- return null;
- }
- return new DateTime(date.getTime()).withZone(dateTimeZone);
- };
-
- private static final JsonSerializer JODA_LOCAL_DATE_TIME_JSON_SERIALIZER =
- (src, typeOfSrc, context) -> new JsonPrimitive(src.toString(JacksonSerializer.DatePatternConstants.SIMPLE_DATE_FORMAT_MILLIS));
- private static final JsonDeserializer JODA_LOCAL_DATE_TIME_JSON_DESERIALIZER = (json, type, context) ->
- org.joda.time.LocalDateTime.parse(json.getAsString(), DateTimeFormat.forPattern(JacksonSerializer.DatePatternConstants.SIMPLE_DATE_FORMAT_MILLIS));
-
- private static final JsonSerializer JODA_LOCAL_DATE_JSON_SERIALIZER =
- (src, typeOfSrc, context) -> new JsonPrimitive(src.toString(JacksonSerializer.DatePatternConstants.SHORT_DATE_FORMAT));
- private static final JsonDeserializer JODA_LOCAL_DATE_JSON_DESERIALIZER = (json, type, context) ->
- org.joda.time.LocalDate.parse(json.getAsString(), DateTimeFormat.forPattern(JacksonSerializer.DatePatternConstants.SHORT_DATE_FORMAT));
-
- private static final JsonSerializer JODA_LOCAL_TIME_JSON_SERIALIZER =
- (src, typeOfSrc, context) -> new JsonPrimitive(src.toString(JacksonSerializer.DatePatternConstants.SHORT_TIME_FORMAT_MILLISECOND));
- private static final JsonDeserializer JODA_LOCAL_TIME_JSON_DESERIALIZER = (json, type, context) ->
- org.joda.time.LocalTime.parse(json.getAsString(), DateTimeFormat.forPattern(JacksonSerializer.DatePatternConstants.SHORT_TIME_FORMAT_MILLISECOND));
-
- private static final JsonSerializer LOCAL_DATE_TIME_JSON_SERIALIZER =
- ((src, typeOfSrc, context) -> new JsonPrimitive(src.format(DateTimeFormatter.ofPattern(JacksonSerializer.DatePatternConstants.localDateTimeFormat))));
- private static final JsonDeserializer LOCAL_DATE_TIME_JSON_DESERIALIZER = (json, type, context) ->
- LocalDateTime.parse(json.getAsString(), JacksonSerializer.DateFormatParser.INSTANCE.getFormatter(JacksonSerializer.DatePatternConstants.localDateTimeFormat));
- private static final JsonSerializer LOCAL_DATE_JSON_SERIALIZER =
- ((src, typeOfSrc, context) -> new JsonPrimitive(src.format(DateTimeFormatter.ofPattern(JacksonSerializer.DatePatternConstants.SHORT_DATE_FORMAT))));
-
- private static final JsonDeserializer LOCAL_DATE_JSON_DESERIALIZER = (json, type, context) ->
- LocalDate.parse(json.getAsString(), JacksonSerializer.DateFormatParser.INSTANCE.getFormatter(JacksonSerializer.DatePatternConstants.SHORT_DATE_FORMAT));
-
- private static final JsonSerializer LOCAL_TIME_JSON_SERIALIZER =
- ((src, typeOfSrc, context) -> new JsonPrimitive(src.format(DateTimeFormatter.ofPattern(JacksonSerializer.DatePatternConstants.localTimeFormat))));
-
- private static final JsonDeserializer LOCAL_TIME_JSON_DESERIALIZER = (json, type, context) ->
- LocalTime.parse(json.getAsString(), JacksonSerializer.DateFormatParser.INSTANCE.getFormatter(JacksonSerializer.DatePatternConstants.localTimeFormat));
-
- private static final JsonSerializer CALENDAR_JSON_SERIALIZER =
- (((src, typeOfSrc, context) -> new JsonPrimitive(
- DateFormatUtils.format(src, JacksonSerializer.DatePatternConstants.SIMPLE_DATE_FORMAT_WITH_TIMEZONE, src.getTimeZone()))));
-
- private static final JsonDeserializer CALENDAR_JSON_DESERIALIZER = (json, type, context) ->
- JacksonSerializer.DateFormatParser.INSTANCE.parseCalendar(json.getAsString());
-
- private static final JsonSerializer GREGORIAN_CALENDAR_JSON_SERIALIZER =
- (((src, typeOfSrc, context) -> new JsonPrimitive(DateFormatUtils.format(src, JacksonSerializer.DatePatternConstants.SIMPLE_DATE_FORMAT_WITH_TIMEZONE, src.getTimeZone()))));
-
- private static final JsonDeserializer GREGORIAN_CALENDAR_JSON_DESERIALIZER = (json, type, context) ->
- JacksonSerializer.DateFormatParser.INSTANCE.parseGregorianCalendar(json.getAsString());
-
- private static final JsonSerializer XML_GREGORIAN_CALENDAR_JSON_SERIALIZER =
- (((src, typeOfSrc, context) -> {
- GregorianCalendar calendar = src.toGregorianCalendar();
- return new JsonPrimitive(DateFormatUtils.format(calendar, JacksonSerializer.DatePatternConstants.SIMPLE_DATE_FORMAT_WITH_TIMEZONE, calendar.getTimeZone()));
- }));
-
- private static final JsonDeserializer XML_GREGORIAN_CALENDAR_JSON_DESERIALIZER =
- (json, type, context) -> {
- GregorianCalendar calendar = JacksonSerializer.DateFormatParser.INSTANCE.parseGregorianCalendar(json.getAsString());
- XMLGregorianCalendar xmlGregorianCalendar = null;
- try {
- xmlGregorianCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar);
- } catch (Exception ex) {
- LOGGER.warn("XMLGregorianCalendar.deserialize", ex);
- }
- return xmlGregorianCalendar;
- };
-
- private static final JsonSerializer TIMESTAMP_JSON_SERIALIZER =
- (((src, typeOfSrc, context) -> new JsonPrimitive(DateFormatUtils.format(src, JacksonSerializer.DatePatternConstants.SIMPLE_DATE_FORMAT_MILLIS))));
-
- private static final JsonDeserializer TIMESTAMP_JSON_DESERIALIZER = (json, typeOfT, context) ->
- Optional.ofNullable(JacksonSerializer.DateFormatParser.INSTANCE.parseDate(json.getAsString()))
- .map(date -> new Timestamp(date.getTime())).orElse(new Timestamp(System.currentTimeMillis()));
-
- private static final JsonSerializer DATE_JSON_SERIALIZER =
- (((src, typeOfSrc, context) -> new JsonPrimitive(DateFormatUtils.format(src, JacksonSerializer.DatePatternConstants.SIMPLE_DATE_FORMAT_MILLIS))));
- private static final JsonDeserializer DATE_JSON_DESERIALIZER = (json, type, context) ->
- DateFormatParser.INSTANCE.parseDate(json.getAsString());
-
- private static final JsonSerializer SQL_DATE_JSON_SERIALIZER =
- (((src, typeOfSrc, context) -> new JsonPrimitive(DateFormatUtils.format(src, JacksonSerializer.DatePatternConstants.SIMPLE_DATE_FORMAT_MILLIS))));
-
- private static final JsonDeserializer SQL_DATE_JSON_DESERIALIZER = (json, type, context) ->{
- Date date = DateFormatParser.INSTANCE.parseDate(json.getAsString());
- return new java.sql.Date(date.getTime());
- };
-
- private static final JsonSerializer