前言: 为什么要做写这个记录。是因为遇到前端js读取long类型的值,long类型的值太大。19位数字。比如idworker生成的id就很难处理。直接出现精度丢失的问题。这样就需要传回前端前选择性的把long属性转成string类型的值。废话不错说。直接举例子。
环境: 本例子环境是 在springboot2.0搭建的
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatypegroupId>
<artifactId>jackson-datatype-jsr310artifactId>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-lang3artifactId>
<version>3.9version>
dependency>
目前是只要是long类型就全部转成string ,可以通过key值来筛选来些需要转的属性值。目前注释起来了
package com.comit.systemConfig;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonStreamContext;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
public class IdSerializer extends StdSerializer<Long> {
public IdSerializer() {
this(null);
}
public IdSerializer(Class<Long> t) {
super(t);
}
@Override
public void serialize(Long value, JsonGenerator gen, SerializerProvider provider) throws IOException {
if (value == null) {
gen.writeNull();
return;
}
JsonStreamContext context = gen.getOutputContext();
String key = getKeyName(context);
/* if ("id".equals(key) || StringUtils.endsWithAny(key, "Id", "Ids","ids","id")) {
gen.writeString(value.toString());
return;
}else{
gen.writeNumber(value);
}*/
gen.writeString(value.toString());
}
private String getKeyName(JsonStreamContext context) {
String name = null;
while (context != null && (name = context.getCurrentName()) == null) {
context = context.getParent();
}
return name;
}
}
我自己也试了一下这个配置文件 并没有起作用
package com.comit.systemConfig;
import com.comit.systemConfig.IdSerializer;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
//@Configuration
public class JacksonConfig {
private static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
private static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
@Bean
public Converter<String, LocalDateTime> localDateTimeConverter() {
return new Converter<String, LocalDateTime>() {
@Override
public LocalDateTime convert(String source) {
if (StringUtils.isEmpty(source)) {
return null;
}
return LocalDateTime.parse(source, DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT));
}
};
}
@Bean
public Converter<String, LocalDate> localDateConverter() {
return new Converter<String, LocalDate>() {
@Override
public LocalDate convert(String source) {
if (StringUtils.isEmpty(source)) {
return null;
}
return LocalDate.parse(source, DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT));
}
};
}
@Bean
public Converter<String, LocalTime> localTimeConverter() {
return new Converter<String, LocalTime>() {
@Override
public LocalTime convert(String source) {
if (StringUtils.isEmpty(source)) {
return null;
}
return LocalTime.parse(source, DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT));
}
};
}
@Bean
public ObjectMapper objectMapper() {
return getObjectMapper();
}
public static ObjectMapper getObjectMapperWithoutIdModule() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
public static ObjectMapper getObjectMapper() {
ObjectMapper objectMapper = getObjectMapperWithoutIdModule();
SimpleModule idModule = new SimpleModule("id module");
idModule.addSerializer(Long.class, new IdSerializer());
idModule.addSerializer(Long.TYPE, new IdSerializer());
// idModule.addSerializer(String.class, new PraiseRateSerializer());
objectMapper.registerModule(idModule);
return objectMapper;
}
}
如果说jackson不起作用。就如下配置就应该搞定了。
在mvc配置文件里加默认的jackson转换器就应该搞定了。
package com.comit.interceptor;
import com.comit.sm.SM2Encryptor;
import com.comit.systemConfig.IdSerializer;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.TimeZone;
/**
* @author thh
* 添加拦截器
*/
@Configuration
@EnableWebMvc
public class CustomWebMvcConfigurerAdapter implements WebMvcConfigurer {
@Bean
public MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// objectMapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);
// objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
// objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
// objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
SimpleModule idModule = new SimpleModule("id module");
idModule.addSerializer(Long.class, new IdSerializer());
idModule.addSerializer(Long.TYPE, new IdSerializer());
// idModule.addSerializer(String.class, new PraiseRateSerializer());
objectMapper.registerModule(idModule);
jsonConverter.setObjectMapper(objectMapper);
return jsonConverter;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(customJackson2HttpMessageConverter());
}
}
在pojo的字段或者属性上添加
这种方法只能对pojo上 。无法解决map类型以及其他类型的。所以看个人选择习惯吧。因为项目是一起开发的。有的人喜欢查map,有的人喜欢查对象。所以还是要看个人习惯的话 还是需要自定义的序列化才能满足。或者查出map后 自己手动把id转成string类型的。
测试:
首先自己弄个ajax来测试 手动下载个jq把
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Jquery 实现异步一title>
<script src="js/jquery-3.3.1.js">script>
<script>
function fun() {
$.get("http://localhost:8888/api/expert/expertApply/1",{},function (data) {
alert(data);
});
}
script>
head>
<body>
<input type="button" value="异步交互jquery方式" onclick="fun()"/>
<input type="text"/>
body>
html>