Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
* XML limitation
* The common uses are:
* (1) single element node, XML can not distinguish between a single value or only one value in the array, unless nested wrap.
* (2) Xml can not recognize the data type, while Json has string, number, boolean, object, array
*
* Jackson Plain
* - `transient` output
* - `@Transient` No output
* - `byte[]` as base64, `[]` as `""`
* - `char[]` as String, `[]` as `""`
* - WRITE_DATES_AS_TIMESTAMPS = false
* - `ZonedDateTime` parse as `2023-04-04T21:07:08Z` lost timezone
* - `OffsetDateTime` parse as `2023-04-05T10:07:08Z` lost timezone
* Jackson Wings
* - `transient` No output
* - WRITE_DATES_AS_TIMESTAMPS = false
* - `LocalDateTime` as `"2023-04-05T06:07:08"`
* - `ZonedDateTime` as `"2023-04-05T06:07:08[America/New_York]"` keep timezone
* - `OffsetDateTime` as `"2023-04-05T06:07:08-04:00"` keep timezone
* Jackson Bean
* - `LocalDateTime` as `"2023-04-05 06:07:08"`
* - `ZonedDateTime` as `"2023-04-05 06:07:08 Asia/Shanghai"`
* - `OffsetDateTime` as `"2023-04-05 06:07:08 +08:00"`
* - `float`,`double` as `"3.14159"`
* - `BigDecimal`,`BigInteger` as `"299792458"`
*
*
* @author trydofor
* @since 2022-11-05
*/
public class JacksonHelper {
public enum Style {
/**
* at web tier with ' ' datetime and auto timezone/i18n convert
*/
Bean,
/**
* fastjon default with WRITE_DATES_AS_TIMESTAMPS=false and other Disable/Enable
*/
Plain,
/**
* wings config with 'T' datetime format, without timezone/i18n conversion
*/
Wings,
}
// spring-jackson-79.properties
public static final com.fasterxml.jackson.databind.DeserializationFeature[] EnableDeserializationFeature = {
com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS,
com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES,
com.fasterxml.jackson.databind.DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY,
com.fasterxml.jackson.databind.DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE
};
public static final com.fasterxml.jackson.core.JsonGenerator.Feature[] EnableJsonGeneratorFeature = {
com.fasterxml.jackson.core.JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN
};
public static final com.fasterxml.jackson.databind.MapperFeature[] EnableMapperFeature = {
com.fasterxml.jackson.databind.MapperFeature.PROPAGATE_TRANSIENT_MARKER,
com.fasterxml.jackson.databind.MapperFeature.DEFAULT_VIEW_INCLUSION,
com.fasterxml.jackson.databind.MapperFeature.ALLOW_EXPLICIT_PROPERTY_RENAMING
};
public static final com.fasterxml.jackson.core.JsonParser.Feature[] EnableParserFeature = {
com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_COMMENTS,
com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_YAML_COMMENTS,
com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES,
com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_SINGLE_QUOTES,
com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS,
com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_MISSING_VALUES,
com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_TRAILING_COMMA
};
public static final com.fasterxml.jackson.databind.SerializationFeature[] EnableSerializationFeature = {
com.fasterxml.jackson.databind.SerializationFeature.CLOSE_CLOSEABLE
};
public static final com.fasterxml.jackson.core.JsonParser.Feature[] DisableParserFeature = {
com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER
};
public static final com.fasterxml.jackson.databind.DeserializationFeature[] DisableDeserializationFeature = {
com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
};
public static final com.fasterxml.jackson.databind.SerializationFeature[] DisableSerializationFeature = {
com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
com.fasterxml.jackson.databind.SerializationFeature.FAIL_ON_EMPTY_BEANS
};
public static final JacksonLocalDateTimeDeserializer PlainLocalDateTimeDeserializer = new JacksonLocalDateTimeDeserializer(
DateTimeFormatter.ISO_LOCAL_DATE_TIME, List.of(DateFormatter.FMT_FULL_PSE), AutoZoneType.Off);
public static final JacksonOffsetDateTimeDeserializer PlainOffsetDateTimeDeserializer = new JacksonOffsetDateTimeDeserializer(
DateTimeFormatter.ISO_OFFSET_DATE_TIME, List.of(DateFormatter.FMT_ZONE_PSE), AutoZoneType.Off);
public static final JacksonZonedDateTimeSerializer PlainZonedDateTimeSerializer = new JacksonZonedDateTimeSerializer(
DateTimePattern.FMT_FULL_19TV, AutoZoneType.Off);
public static final JacksonZonedDateTimeDeserializer PlainZonedDateTimeDeserializer = new JacksonZonedDateTimeDeserializer(
DateTimePattern.FMT_FULL_19TV, List.of(DateFormatter.FMT_ZONE_PSE), AutoZoneType.Off);
public static final SimpleModule PlainDateTimeModule = new SimpleModule() {{
addDeserializer(LocalDateTime.class, PlainLocalDateTimeDeserializer);
addDeserializer(OffsetDateTime.class, PlainOffsetDateTimeDeserializer);
addSerializer(ZonedDateTime.class, PlainZonedDateTimeSerializer);
addDeserializer(ZonedDateTime.class, PlainZonedDateTimeDeserializer);
}};
@Contract("_->param1")
public static > T buildPlain(@NotNull T builder) {
builder
.enable(EnableDeserializationFeature)
.enable(EnableJsonGeneratorFeature)
.enable(EnableMapperFeature)
.enable(EnableParserFeature)
.enable(EnableSerializationFeature)
.disable(DisableParserFeature)
.disable(DisableDeserializationFeature)
.disable(DisableSerializationFeature)
// override
.addModule(PlainDateTimeModule);
return builder;
}
// https://github.com/FasterXML/jackson-modules-java8/tree/master/datetime#usage
public static final ObjectMapper JsonPlain = buildPlain(JsonMapper.builder().findAndAddModules()).build();
public static final XmlMapper XmlPlain = buildPlain(XmlMapper.builder().findAndAddModules()).build();
public static final TypeFactory TypeFactoryPlain = JsonPlain.getTypeFactory();
//// wings autoZone ser/des
protected static JacksonLocalDateTimeSerializer beanLocalDateTimeSerializer;
protected static JacksonLocalDateTimeDeserializer beanLocalDateTimeDeserializer;
protected static JacksonZonedDateTimeSerializer beanZonedDateTimeSerializer;
protected static JacksonZonedDateTimeDeserializer beanZonedDateTimeDeserializer;
protected static JacksonOffsetDateTimeSerializer beanOffsetDateTimeSerializer;
protected static JacksonOffsetDateTimeDeserializer beanOffsetDateTimeDeserializer;
@Contract("_->param1")
public static T buildWings(@NotNull T mapper) {
SimpleModule beanDateTimeModule = new SimpleModule();
// auto off
boolean hasBean = false;
if (beanLocalDateTimeSerializer != null) {
hasBean = true;
beanDateTimeModule.addSerializer(LocalDateTime.class, beanLocalDateTimeSerializer.autoOff());
}
if (beanLocalDateTimeDeserializer != null) {
hasBean = true;
beanDateTimeModule.addDeserializer(LocalDateTime.class, beanLocalDateTimeDeserializer.autoOff());
}
if (beanZonedDateTimeSerializer != null) {
hasBean = true;
beanDateTimeModule.addSerializer(ZonedDateTime.class, beanZonedDateTimeSerializer.autoOff());
}
if (beanZonedDateTimeDeserializer != null) {
hasBean = true;
beanDateTimeModule.addDeserializer(ZonedDateTime.class, beanZonedDateTimeDeserializer.autoOff());
}
if (beanOffsetDateTimeSerializer != null) {
hasBean = true;
beanDateTimeModule.addSerializer(OffsetDateTime.class, beanOffsetDateTimeSerializer.autoOff());
}
if (beanOffsetDateTimeDeserializer != null) {
hasBean = true;
beanDateTimeModule.addDeserializer(OffsetDateTime.class, beanOffsetDateTimeDeserializer.autoOff());
}
SimpleModule dtm = hasBean ? beanDateTimeModule : PlainDateTimeModule;
mapper.registerModule(dtm);
return mapper;
}
private static ObjectMapper JsonWings = JsonPlain;
private static XmlMapper XmlWings = XmlPlain;
private static boolean wingsPrepared = false;
protected static void prepareWings(@NotNull ObjectMapper json, @NotNull XmlMapper xml) {
JsonWings = buildWings(json);
XmlWings = buildWings(xml);
wingsPrepared = true;
}
private static ObjectMapper JsonBean = null;
private static XmlMapper XmlBean = null;
private static boolean beanPrepared = false;
protected static void prepareBean(@NotNull ObjectMapper json, @NotNull XmlMapper xml) {
JsonBean = json;
XmlBean = xml;
beanPrepared = true;
}
public static boolean isPrepared(@NotNull Style style) {
return switch (style) {
case Plain -> true;
case Wings -> wingsPrepared;
case Bean -> beanPrepared;
};
}
////
/**
* spring bean style Mapper at web tier with ' ' datetime and auto timezone/i18n convert
*/
@NotNull
public static ObjectMapper JsonBean() {
if (JsonBean == null) throw new IllegalStateException("JsonBean not init, check SlardarJacksonWebConfiguration.jacksonHelperRunner");
return JsonBean;
}
/**
* spring bean style Mapper at web tier with ' ' datetime and auto timezone/i18n convert
*/
@NotNull
public static XmlMapper XmlBean() {
if (XmlBean == null) throw new IllegalStateException("XmlBean not init, check SlardarJacksonWebConfiguration.jacksonHelperRunner");
return XmlBean;
}
/**
* spring bean style Mapper at web tier with ' ' datetime and auto timezone/i18n convert
*/
@NotNull
public static ObjectMapper MapperBean(boolean json) {
return json ? JsonBean() : XmlBean();
}
/**
* fastjon default with WRITE_DATES_AS_TIMESTAMPS=false and other Disable/Enable
*/
@NotNull
public static ObjectMapper JsonPlain() {
return JsonPlain;
}
/**
* fastjon default with WRITE_DATES_AS_TIMESTAMPS=false and other Disable/Enable
*/
@NotNull
public static XmlMapper XmlPlain() {
return XmlPlain;
}
/**
* fastjon default with WRITE_DATES_AS_TIMESTAMPS=false and other Disable/Enable
*/
@NotNull
public static ObjectMapper MapperPlain(boolean json) {
return json ? JsonPlain : XmlPlain;
}
/**
* wings config with 'T' datetime format without timezone/i18n conversion
*/
@NotNull
public static ObjectMapper JsonWings() {
return JsonWings;
}
/**
* wings config with 'T' datetime format without timezone/i18n conversion
*/
@NotNull
public static XmlMapper XmlWings() {
return XmlWings;
}
/**
* wings config with 'T' datetime format without timezone/i18n conversion
*/
@NotNull
public static ObjectMapper MapperWings(boolean json) {
return json ? JsonWings : XmlWings;
}
/**
* wings configed Mapper without auto timezone convert
*/
@NotNull
public static ObjectMapper Mapper(@NotNull Style style, boolean json) {
return switch (style) {
case Wings -> MapperWings(json);
case Plain -> MapperPlain(json);
case Bean -> MapperBean(json);
};
}
/**
* whether `str` has xml characteristics, i.e. the first and last characters are angle brackets or not
*/
@Contract("null->false")
public static boolean asXml(String str) {
if (str == null) return false;
char c1 = WhiteUtil.firstNonWhite(str);
if (c1 == '<') {
char c2 = WhiteUtil.lastNonWhite(str);
return c2 == '>';
}
return false;
}
/**
* whether `str` has xml characteristics, i.e. the first and last characters are angle brackets or not
*/
@Contract("null->false")
public static boolean asXml(byte[] str) {
if (str == null) return false;
byte c1 = WhiteUtil.firstNonWhite(str);
if (c1 == (byte) '<') {
byte c2 = WhiteUtil.lastNonWhite(str);
return c2 == (byte) '>';
}
return false;
}
/////////////
/**
* construct jackson's JavaType by TypeSugar
*/
public static JavaType javaType(@NotNull Class> targetType, Class>... generics) {
Type type = TypeSugar.type(targetType, generics);
return TypeFactoryPlain.constructType(type);
}
/**
* construct jackson's JavaType in spring way
*/
public static JavaType javaType(@NotNull TypeDescriptor targetType) {
Type type = targetType.getResolvableType().getType();
return TypeFactoryPlain.constructType(type);
}
/**
* construct jackson's JavaType in spring way
*/
public static JavaType javaType(@NotNull ResolvableType targetType) {
return TypeFactoryPlain.constructType(targetType.getType());
}
/**
* wings style read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("!null,_,_->!null")
public static T object(String text, @NotNull Class> targetType, Class>... generics) {
if (text == null) return null;
return MapperWings(!asXml(text)).readValue(text, javaType(targetType, generics));
}
/**
* Auto read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("_,!null,_,_ -> !null")
public static T object(@NotNull Style style, String text, @NotNull Class> targetType, Class>... generics) {
if (text == null) return null;
return Mapper(style, !asXml(text)).readValue(text, javaType(targetType, generics));
}
/**
* wings style read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("!null,_->!null")
public static T object(String text, @NotNull JavaType targetType) {
if (text == null) return null;
return MapperWings(!asXml(text)).readValue(text, targetType);
}
/**
* Auto read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("_,!null,_ -> !null")
public static T object(@NotNull Style style, String text, @NotNull JavaType targetType) {
if (text == null) return null;
return Mapper(style, !asXml(text)).readValue(text, targetType);
}
/**
* wings style read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("!null,_->!null")
public static T object(String text, @NotNull ResolvableType targetType) {
if (text == null) return null;
return MapperWings(!asXml(text)).readValue(text, javaType(targetType));
}
/**
* Auto read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("_,!null,_ -> !null")
public static T object(@NotNull Style style, String text, @NotNull ResolvableType targetType) {
if (text == null) return null;
return Mapper(style, !asXml(text)).readValue(text, javaType(targetType));
}
/**
* wings style read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("!null,_->!null")
public static T object(String text, @NotNull TypeDescriptor targetType) {
if (text == null) return null;
return MapperWings(!asXml(text)).readValue(text, javaType(targetType));
}
/**
* Auto read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("_,!null,_ -> !null")
public static T object(@NotNull Style style, String text, @NotNull TypeDescriptor targetType) {
if (text == null) return null;
return Mapper(style, !asXml(text)).readValue(text, javaType(targetType));
}
/**
* wings style read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("!null->!null")
public static JsonNode object(String text) {
if (text == null) return null;
return MapperWings(!asXml(text)).readTree(text);
}
/**
* wings style read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("!null,_,_->!null")
public static T object(byte[] text, @NotNull Class> targetType, Class>... generics) {
if (text == null) return null;
return MapperWings(!asXml(text)).readValue(text, javaType(targetType, generics));
}
/**
* Auto read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("_,!null,_,_ -> !null")
public static T object(@NotNull Style style, byte[] text, @NotNull Class> targetType, Class>... generics) {
if (text == null) return null;
return Mapper(style, !asXml(text)).readValue(text, javaType(targetType, generics));
}
/**
* wings style read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("!null,_->!null")
public static T object(byte[] text, @NotNull JavaType targetType) {
if (text == null) return null;
return MapperWings(!asXml(text)).readValue(text, targetType);
}
/**
* Auto read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("_, !null, _ -> !null")
public static T object(@NotNull Style style, byte[] text, @NotNull JavaType targetType) {
if (text == null) return null;
return Mapper(style, !asXml(text)).readValue(text, targetType);
}
/**
* wings style read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("!null,_->!null")
public static T object(byte[] text, @NotNull ResolvableType targetType) {
if (text == null) return null;
return MapperWings(!asXml(text)).readValue(text, javaType(targetType));
}
/**
* Auto read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("_, !null, _ -> !null")
public static T object(@NotNull Style style, byte[] text, @NotNull ResolvableType targetType) {
if (text == null) return null;
return Mapper(style, !asXml(text)).readValue(text, javaType(targetType));
}
/**
* wings style read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("!null,_->!null")
public static T object(byte[] text, @NotNull TypeDescriptor targetType) {
if (text == null) return null;
return MapperWings(!asXml(text)).readValue(text, javaType(targetType));
}
/**
* Auto read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("_, !null, _ -> !null")
public static T object(@NotNull Style style, byte[] text, @NotNull TypeDescriptor targetType) {
if (text == null) return null;
return Mapper(style, !asXml(text)).readValue(text, javaType(targetType));
}
/**
* wings style read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("!null->!null")
public static JsonNode object(byte[] text) {
if (text == null) return null;
return MapperWings(!asXml(text)).readTree(text);
}
/**
* Auto read text to object, if text asXml, read as xml, otherwise as json
*/
@SneakyThrows
@Contract("_, !null -> !null")
public static JsonNode object(@NotNull Style style, byte[] text) {
if (text == null) return null;
return Mapper(style, !asXml(text)).readTree(text);
}
/**
* wings style serialization to json
*/
@SneakyThrows
@Contract("!null->!null")
public static String string(Object obj) {
return obj == null ? null : MapperWings(true).writeValueAsString(obj);
}
/**
* serialization to json
*/
@SneakyThrows
@Contract("_, !null -> !null")
public static String string(@NotNull Style style, Object obj) {
return obj == null ? null : Mapper(style, true).writeValueAsString(obj);
}
/**
* wings style serialization to json/xml
*/
@SneakyThrows
@Contract("!null,_->!null")
public static String string(Object obj, boolean json) {
return obj == null ? null : MapperWings(json).writeValueAsString(obj);
}
/**
* serialization to json/xml
*/
@SneakyThrows
@Contract("_, !null, _ -> !null")
public static String string(@NotNull Style style, Object obj, boolean json) {
return obj == null ? null : Mapper(style, json).writeValueAsString(obj);
}
/**
* wings style serialization to json
*/
@SneakyThrows
@Contract("!null->!null")
public static byte[] bytes(Object obj) {
return obj == null ? null : MapperWings(true).writeValueAsBytes(obj);
}
/**
* serialization to json
*/
@SneakyThrows
@Contract("_, !null -> !null")
public static byte[] bytes(@NotNull Style style, Object obj) {
return obj == null ? null : Mapper(style, true).writeValueAsBytes(obj);
}
/**
* wings style serialization to json/xml
*/
@SneakyThrows
@Contract("!null,_->!null")
public static byte[] bytes(Object obj, boolean json) {
return obj == null ? null : MapperWings(json).writeValueAsBytes(obj);
}
/**
* serialization to json/xml
*/
@SneakyThrows
@Contract("_, !null, _ -> !null")
public static byte[] bytes(@NotNull Style style, Object obj, boolean json) {
return obj == null ? null : Mapper(style, json).writeValueAsBytes(obj);
}
////
@Contract("_,_,!null->!null")
public static String getString(JsonNode node, String field, String defaults) {
if (node == null) return defaults;
final JsonNode jn = node.get(field);
return jn != null ? jn.asText(defaults) : defaults;
}
public static boolean getBoolean(JsonNode node, String field, boolean defaults) {
if (node == null) return defaults;
final JsonNode jn = node.get(field);
return jn != null ? jn.asBoolean(defaults) : defaults;
}
public static int getInt(JsonNode node, String field, int defaults) {
if (node == null) return defaults;
final JsonNode jn = node.get(field);
return jn != null ? jn.asInt(defaults) : defaults;
}
public static long getLong(JsonNode node, String field, long defaults) {
if (node == null) return defaults;
final JsonNode jn = node.get(field);
return jn != null ? jn.asLong(defaults) : defaults;
}
public static double getDouble(JsonNode node, String field, double defaults) {
if (node == null) return defaults;
final JsonNode jn = node.get(field);
return jn != null ? jn.asDouble(defaults) : defaults;
}
}