SpringUtil.getBean<GenericConversionService>().addConverter(Date2LocalDateTimeConverter())
var handerAdapter = SpringUtil.context.getBean(RequestMappingHandlerAdapter::class.java); var listResolvers = mutableListOf<HandlerMethodArgumentResolver>()
listResolvers.add(RequestParameterConverter(listOf(ApiParam::class.java)));
listResolvers.addAll(handerAdapter.argumentResolvers) handerAdapter.argumentResolvers = listResolvers;
internal class MyJsonMapper
@JvmOverloads private constructor()
: ObjectMapper() { init {
// 设置输出时包含属性的风格
this.findAndRegisterModules();
this.setSerializationInclusion(JsonInclude.Include.NON_EMPTY) // 允许单引号、允许不带引号的字段名称
this.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
this.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true) // 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
// 空值处理为空串
this.serializerProvider.setNullValueSerializer(object : JsonSerializer<Any>() {
@Throws(IOException::class, JsonProcessingException::class)
override fun serialize(value: Any, jgen: JsonGenerator,
provider: SerializerProvider) {
jgen.writeString("")
}
}) this.registerModule(CustomModule()); // 进行HTML解码。
// this.registerModule(SimpleModule().addSerializer(String::class.java, object : JsonSerializer<String>() {
// @Throws(IOException::class, JsonProcessingException::class)
// override fun serialize(value: String, jgen: JsonGenerator,
// provider: SerializerProvider) {
// jgen.writeString(StringEscapeUtils.unescapeHtml4(value))
// }
// }))
// 设置时区
this.setTimeZone(TimeZone.getDefault())//getTimeZone("GMT+8:00")
} companion object { /**
* 创建只输出非Null且非Empty(如List.isEmpty)的属性到Json字符串的Mapper,建议在外部接口中使用.
*/
val instance: MyJsonMapper = MyJsonMapper();
}
} // 先定义一个json生成器
class ObjectIdJsonSerializer : JsonSerializer<ObjectId>() {
override fun serialize(o: ObjectId?, j: JsonGenerator, s: SerializerProvider) {
if (o == null) {
j.writeNull()
} else {
j.writeString(o.toString())
}
}
} class LocalDateJsonSerializer : JsonSerializer<LocalDate>() {
override fun serialize(value: LocalDate?, generator: JsonGenerator, serializers: SerializerProvider) {
if (value == null) {
generator.writeNull()
} else {
generator.writeNumber(Date.from(value.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()).time)
}
}
} class LocalTimeJsonSerializer : JsonSerializer<LocalTime>() {
override fun serialize(value: LocalTime?, generator: JsonGenerator, serializers: SerializerProvider) {
if (value == null) {
generator.writeNull()
} else {
generator.writeString(value.AsString())
}
}
} class LocalDateTimeJsonSerializer : JsonSerializer<LocalDateTime>() {
override fun serialize(value: LocalDateTime?, generator: JsonGenerator, serializers: SerializerProvider) {
if (value == null) {
generator.writeNull()
} else {
generator.writeNumber(Date.from(value.atZone(ZoneId.systemDefault()).toInstant()).time)
}
}
} class LocalDateJsonDeserializer : JsonDeserializer<LocalDate>() {
override fun deserialize(json: JsonParser?, ctxt: DeserializationContext?): LocalDate? {
if (json == null) {
return null;
} if (json.valueAsString.contains("-")) {
return json.valueAsString.AsLocalDateTime().toLocalDate();
} return Date(json.longValue).AsLocalDateTime().toLocalDate();
}
} class LocalTimeJsonDeserializer : JsonDeserializer<LocalTime>() {
override fun deserialize(json: JsonParser?, ctxt: DeserializationContext?): LocalTime? {
if (json == null) {
return null;
} if (json.valueAsString.contains(".")) {
return LocalTime.parse(json.valueAsString, DateTimeFormatter.ofPattern("HH:mm:ss.sss"))
} return LocalTime.parse(json.valueAsString, DateTimeFormatter.ofPattern("HH:mm:ss"))
}
} class LocalDateTimeJsonDeserializer : JsonDeserializer<LocalDateTime>() {
override fun deserialize(json: JsonParser?, ctxt: DeserializationContext?): LocalDateTime? {
if (json == null) {
return null;
} if (json.valueAsString.contains("-")) {
return json.valueAsString.AsLocalDateTime();
} return Date(json.longValue).AsLocalDateTime();
}
} //Jackson 输出的时候,进行自定义序列化格式。
// http://www.jianshu.com/p/a0fb6559f56d
@Component
class CustomModule() : SimpleModule(PackageVersion.VERSION) {
init {
addSerializer(ObjectId::class.java, ObjectIdJsonSerializer());
addSerializer(LocalDate::class.java, LocalDateJsonSerializer());
addSerializer(LocalTime::class.java, LocalTimeJsonSerializer());
addSerializer(LocalDateTime::class.java, LocalDateTimeJsonSerializer()); addDeserializer(LocalDate::class.java, LocalDateJsonDeserializer())
addDeserializer(LocalTime::class.java, LocalTimeJsonDeserializer())
addDeserializer(LocalDateTime::class.java, LocalDateTimeJsonDeserializer())
}
} fun <T> T.ToJson(): String {
if (this is String) return this; return MyJsonMapper.instance.writeValueAsString(this) ?: ""
} fun <T> String.FromJson(collectionClass: Class<T>): T {
if (collectionClass == String::class.java) {
return this as T
} var jsonString = this.RemoveComment().Remove("\r\n", "\n")
if (jsonString.isEmpty()) {
return collectionClass.newInstance();
} return MyJsonMapper.instance.readValue(jsonString, collectionClass)!!
} inline fun <reified T> String.FromJson(): T {
return this.FromJson(T::class.java)
}

class RequestParameterConverter(var canIgnoreAnnotationClazzes: List<Class<*>> = listOf()) : HandlerMethodArgumentResolver {
override fun supportsParameter(parameter: MethodParameter?): Boolean { if (parameter == null) return false if (ServletRequest::class.java.isAssignableFrom(parameter.parameterType)) return false
if (ServletResponse::class.java.isAssignableFrom(parameter.parameterType)) return false
if (HttpSession::class.java.isAssignableFrom(parameter.parameterType)) return false if (parameter.hasParameterAnnotation(PathVariable::class.java)) return false;
if (parameter.hasParameterAnnotation(CookieValue::class.java)) return false;
if (parameter.hasParameterAnnotation(RequestHeader::class.java)) return false;
if (parameter.hasParameterAnnotation(RequestParam::class.java)) return false; var parameterAnnotations = parameter.parameterAnnotations.toMutableList();
parameterAnnotations.removeAll { Nullable::class.java.isInstance(it) }
parameterAnnotations.removeAll { NotNull::class.java.isInstance(it) } canIgnoreAnnotationClazzes.forEach { ignoreClazz ->
parameterAnnotations.removeAll { ignoreClazz.isInstance(it) }
} if (parameterAnnotations.size > 0) return false; return true
//return parameter?.hasParameterAnnotation(JsonValue::class.java) ?: false;
} override fun resolveArgument(parameter: MethodParameter?, mavContainer: ModelAndViewContainer?, webRequest: NativeWebRequest?, binderFactory: WebDataBinderFactory?): Any? {
if (parameter == null || mavContainer == null || webRequest == null || binderFactory == null) return null var key = parameter.parameterName
var request = (webRequest as ServletWebRequest).request as MyHttpRequestWrapper;
var value: Any? = null if (request.json.containsKey(key)) {
value = request.json.get(key)
} else if (request.requestMap.contains(key)) {
value = request.requestMap.get(request.queryString);
} if (value == null || (value is String && value.isEmpty())) {
if (parameter.parameterType == String::class.java) {
return "";
} else if (Number::class.java.isAssignableFrom(parameter.parameterType)) {
return MyUtil.getSimpleClassDefaultValue(parameter.parameterType);
} else if (parameter.parameterType.isArray) {
return "[]".FromJson(parameter.parameterType)
} else if (Iterable::class.java.isAssignableFrom(parameter.parameterType)) {
return "[]".FromJson(parameter.parameterType);
}
return null;
// var nullable = parameter.parameterAnnotations.any { Nullable::class.java.isInstance(it) }
//
// if (nullable) {
// return null;
// }
// return MyUtil.getSimpleClassDefaultValue(parameter.parameterType)
} if (parameter.parameterType.isEnum) {
return value.AsString().ToEnum(parameter.parameterType)
} else if (value.javaClass.isInstance(parameter.parameterType)) {
return value;
} else if (parameter.parameterType == Boolean::class.java) {
return value.AsBoolean()
} else if (parameter.parameterType == Character::class.java) {
return value.toString()[0]
} else if (parameter.parameterType == Byte::class.java) {
return value.AsInt().toByte()
} else if (parameter.parameterType == Short::class.java) {
return value.AsInt().toShort()
} else if (parameter.parameterType == Int::class.java ||
parameter.parameterType == java.lang.Integer::class.java) {
return value.AsInt()
} else if (parameter.parameterType == Long::class.java) {
return value.AsLong()
} else if (parameter.parameterType == Float::class.java) {
return value.AsDouble()
} else if (parameter.parameterType == Double::class.java) {
return value.AsDouble().toLong()
} else if (parameter.parameterType == String::class.java) {
return value.AsString()
} else if (parameter.parameterType == LocalDate::class.java) {
return value.AsLocalDateTime().toLocalDate()
} else if (parameter.parameterType == LocalTime::class.java) {
return value.AsLocalDateTime().toLocalTime()
} else if (parameter.parameterType == LocalDateTime::class.java) {
return value.AsLocalDateTime()
} else if (parameter.parameterType == Date::class.java) {
return Date.from(value.AsLocalDateTime().atZone(ZoneId.systemDefault()).toInstant());
} else {
return value.AsString().FromJson(parameter.parameterType);
}
return value
} }
@Configuration
open class MongoConfig { @Bean
@Throws(Exception::class)
open fun mongoTemplate(): MongoTemplate { var dbFactory = SpringUtil.getBean<MongoDbFactory>();
//remove _class
val converter = MappingMongoConverter(DefaultDbRefResolver(dbFactory), MongoMappingContext())
converter.typeMapper = DefaultMongoTypeMapper(null) (converter.conversionService as GenericConversionService).addConverter(Date2LocalDateTimeConverter()) return MongoTemplate(dbFactory, converter)
} } class Date2LocalDateTimeConverter : GenericConverter {
override fun getConvertibleTypes(): MutableSet<GenericConverter.ConvertiblePair> {
var pairs = hashSetOf<GenericConverter.ConvertiblePair>();
pairs.add(GenericConverter.ConvertiblePair(String::class.java, LocalDate::class.java));
pairs.add(GenericConverter.ConvertiblePair(String::class.java, LocalTime::class.java));
pairs.add(GenericConverter.ConvertiblePair(String::class.java, LocalDateTime::class.java));
pairs.add(GenericConverter.ConvertiblePair(Date::class.java, LocalDate::class.java));
pairs.add(GenericConverter.ConvertiblePair(Date::class.java, LocalTime::class.java));
pairs.add(GenericConverter.ConvertiblePair(Date::class.java, LocalDateTime::class.java));
pairs.add(GenericConverter.ConvertiblePair(LocalDate::class.java, Date::class.java));
pairs.add(GenericConverter.ConvertiblePair(LocalTime::class.java, Date::class.java));
pairs.add(GenericConverter.ConvertiblePair(LocalDateTime::class.java, Date::class.java));
return pairs;
} override fun convert(value: Any?, sourceType: TypeDescriptor?, targetType: TypeDescriptor?): Any? {
if (value == null || sourceType == null || targetType == null) return null var valueClass = sourceType.type;
var targetClass = targetType.type; if (valueClass == String::class.java) {
var strValue = value.AsString();
if (strValue.isEmpty()) {
return null;
} if (targetClass == LocalDate::class.java) {
return strValue.AsLocalDateTime().toLocalDate();
}
if (targetClass == LocalTime::class.java) {
return strValue.AsLocalDateTime().toLocalTime()
}
if (targetClass == LocalDateTime::class.java) {
return strValue.AsLocalDateTime();
}
} if (valueClass == Date::class.java) {
if (targetClass == LocalDate::class.java) {
return value.AsLocalDateTime().toLocalDate();
}
if (targetClass == LocalTime::class.java) {
return value.AsLocalDateTime().toLocalTime();
}
if (targetClass == LocalDateTime::class.java) {
return value.AsLocalDateTime()
}
} if (targetClass == Date::class.java) {
if (valueClass == LocalDate::class.java) {
return Date.from((value as LocalDate).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
}
if (valueClass == LocalTime::class.java) {
return Date.from((value as LocalTime).atDate("1970-01-01".AsLocalDateTime().toLocalDate()).atZone(ZoneId.systemDefault()).toInstant());
}
if (valueClass == LocalDateTime::class.java) {
return Date.from((value as LocalDateTime).atZone(ZoneId.systemDefault()).toInstant());
}
} return null;
} }

问题

返回实体时,如:

  • JsonTypedResult 类型, 当有消息时, 仅返回: JsonResult
  • JsonTypedResult 类型, 当 data.id 为 "000000000" 时, 返回 id= ""

SpringBoot笔记--Jackson的更多相关文章

  1. springboot之jackson的两种配置方式

    springboot 针对jackson是自动化配置的,如果需要修改,有两种方式: 方式一:通过application.yml 配置属性说明:## spring.jackson.date-format ...

  2. SpringBoot与jackson.databind兼容报错问题

    SpringBoot与jackson.databind兼容报错问题 ———————————————— 1.SpringBoot版本V2.0.0其依赖的jackson-databind版本为V2.9.4 ...

  3. 源码分析springboot自定义jackson序列化,默认null值个性化处理返回值

    最近项目要实现一种需求,对于后端返回给前端的json格式的一种规范,不允许缺少字段和字段值都为null,所以琢磨了一下如何进行将springboot的Jackson序列化自定义一下,先看看如何实现,再 ...

  4. spring学习笔记---Jackson的使用和定制

      前言: JAVA总是把实体对象(数据库/Nosql等)转换为POJO对象再处理, 虽然有各类框架予以强力支持. 但实体对象和POJO, 由于"饮食习惯", "民族特色 ...

  5. SpringBoot笔记一

    1 开始 1.1 spring介绍 Spring Boot使开发独立的,产品级别的基于Spring的应用变得非常简单,你只需"just run". 我们为Spring平台及第三方库 ...

  6. SpringBoot笔记十六:ElasticSearch

    目录 ElasticSearch官方文档 ElasticSearch安装 ElasticSearch简介 ElasticSearch操作数据,RESTful风格 存储 检查是否存在 删除 查询 更新 ...

  7. 让SpringBoot的jackson支持JavaBean嵌套的protobuf

    问题背景 REST 项目使用protobuf 来加速项目开发,定义了很多model,vo,最终返回的仍然是JSON. 项目中一般使用 一个Response类, public class Respons ...

  8. SpringBoot系列——Jackson序列化

    前言 Spring Boot提供了与三个JSON映射库的集成: Gson Jackson JSON-B Jackson是首选的默认库. 官网介绍: https://docs.spring.io/spr ...

  9. SpringBoot全局Jackson配置未生效

    在做一个小项目,后台服务第一次用SpringBoot构建.接口使用Json格式,在application.properties中配置如下: spring.jackson.default-propert ...

随机推荐

  1. SQL中的每一张表都必须设有主键吗

    问题描述: 公司的数据库表有时候会看到没有主键的,SQL中的每一张表都必须设有主键吗? 主键的作用: 1)保证实体的完整性: 2)加快数据库的操作速度: 3)在表中添加新记录时,数据库ACCESS会自 ...

  2. MyEclipse10或者eclipse中配置开发Python的Pydev插件安装教程

    注意使用LiClipse的用户 PyDev已经预装在LiClipse中,所以可以跳过这一步(请注意,如果使用LiClipse,PyDev不能单独安装或更新,因为它必须始终作为一个整体更新). 必需品 ...

  3. svg 认识及动画

    svg在线中文教程 https://svg.brucewar.me/ http://www.zhangxinxu.com/wordpress/tag/svg/ http://svgtrick.com ...

  4. Orcale新增、修改、删除字段

    一.新增字段 alert table user add( userName VARCHAR2(255 CHAR) ) ; 设置字段不为空, 给出默认值 alert table user add( us ...

  5. phoneGap使用 (MAC)

    一.安装 ①先安装NodeJS(如果有的就不用安装了) http://nodejs.org/ ②.sudo npm install -g phonegap 需要等待安装完成 ③.检测是否安装成功 no ...

  6. SQL注入的绕过

    一.常用符号的绕过 1.空格 1 空格代替:+ %20 %09 %0a %0b %0c %0d %a0 %00 /**/ /*!*/ 2 括号绕过:常用于基于时间延迟的盲注,例如构造语句: ?id=1 ...

  7. Dubbo+zookeeper+SpringMVC搭建最简单的分布式项目

    Dubbo 是什么 一款分布式服务框架 高性能和透明化的RPC远程服务调用方案 SOA服务治理方案 Dubbo 架构流程图 Provider:服务提供方 Consumer:服务消费者 Registry ...

  8. Python解析器

    当我们编写Python代码时,我们得到的是一个包含Python代码的以.py为扩展名的文本文件.要运行代码,就需要Python解释器去执行.py文件. 由于整个Python语言从规范到解释器都是开源的 ...

  9. 为什么MySQL数据库索引选择使用B+树?

    在进一步分析为什么MySQL数据库索引选择使用B+树之前,我相信很多小伙伴对数据结构中的树还是有些许模糊的,因此我们由浅入深一步步探讨树的演进过程,在一步步引出B树以及为什么MySQL数据库索引选择使 ...

  10. smartpass

    1.smartpass 是用户注册后,产生的用户名密码 与每个摄像头的用户名密码不一致 2.每个设备初始化登录密码为admin admin,如果需要修改,则在进入该设备IP地址,设置——>用户管 ...