引入依赖
xml
<dependency>
<groupId>org.hashids</groupId>
<artifactId>hashids</artifactId>
<version>1.0.3</version>
</dependency>
步骤
1、自定义注解
java
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
public @interface JsonHashId {
}
1、定义序列化
java
public class HashIdLongSerializer extends JsonSerializer<Long> implements ContextualSerializer {
@Override
public void serialize(Long value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString(HashIdUtil.encoded(value));
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException {
JsonHashId annotation = property.getAnnotation(JsonHashId.class);
if (annotation != null) {
return this;
} else{
return new NumberSerializers.LongSerializer(Long.class);
}
}
}
3、定义反序列化
java
public class HashIdLongDeserializer extends JsonDeserializer<Long> implements ContextualDeserializer {
@Override
public Long deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException, JacksonException {
String value = jsonparser.getText();
return HashIdUtil.decode(value);
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext context, BeanProperty property) throws JsonMappingException {
JsonHashId annotation = property.getAnnotation(JsonHashId.class);
if (annotation != null) {
return this;
} else {
return new NumberDeserializers.LongDeserializer(Long.class, null);
}
}
}
4、添加自定义序列化器和反序列化器
java
public class JacksonObjectMapper extends ObjectMapper {
public JacksonObjectMapper() {
super();
// 收到未知属性时不报异常
this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
// 反序列化时,属性不存在的兼容处理
this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
module..addDeserializer(Long.class, new HashIdLongDeserializer())
.addSerializer(Long.class, new HashIdLongSerializer());
// 注册功能模块 添加自定义序列化器和反序列化器
this.registerModule(module);
}
}
5、配置消息转换器
java
/**
* 配置
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
/**
* 扩展消息转换器
*
* @param converters
*/
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
// 创建消息转换器对象
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
// 设置对象转换器
messageConverter.setObjectMapper(new JacksonObjectMapper());
// 添加到mvc框架消息转换器中,优先使用自定义转换器
converters.add(0, messageConverter);
}
}
6、hashids工具类
java
package com.springboot.api.util;
import org.hashids.Hashids;
/**
* hashid
*/
public class HashIdUtil {
public static Hashids getHashids() {
return new Hashids("hashid", 8);
}
/**
* 加密
*/
public static String encoded(Long id) {
Hashids hashids = getHashids();
return hashids.encode(id);
}
/**
* 解密
*/
public static long decode(String uid) {
Hashids hashids = getHashids();
return hashids.decode(uid)[0];
}
}
测试输出
userId: 1,
加密后
"userId": "ZxWD0W68",
方式二
定义转换器,将序列化器和反序列化器写在一起
java
public class HashIdConverter {
public static class HashIdLongDeserializer extends JsonDeserializer<Long> {
@Override
public Long deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException, JacksonException {
return HashIdUtil.decode(jsonparser.getText());
}
}
public static class HashIdLongSerializer extends JsonSerializer<Long> {
@Override
public void serialize(Long value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString(HashIdUtil.encoded(value));
}
}
}
配置内省器
java
public class HashIdFieldAnnotationIntrospector extends NopAnnotationIntrospector {
@Override
public Object findSerializer(Annotated annotated) {
TableId annotation = annotated.getAnnotation(TableId.class);
if(annotation != null){
return HashIdConverter.HashIdLongSerializer.class;
} else{
return super.findSerializer(annotated);
}
}
@Override
public Object findDeserializer(Annotated annotated) {
TableId annotation = annotated.getAnnotation(TableId.class);
if(annotation != null){
return HashIdConverter.HashIdLongDeserializer.class;
} else{
return super.findDeserializer(annotated);
}
}
}
配置
java
public class JacksonObjectMapper extends ObjectMapper {
public JacksonObjectMapper() {
super();
// 将自定义注解內省器加入到Jackson注解内省器集合里,AnnotationIntrospector是双向链表结构
AnnotationIntrospector annotationIntrospector = this.getSerializationConfig().getAnnotationIntrospector();
AnnotationIntrospector pair = AnnotationIntrospectorPair.pair(annotationIntrospector, new HashIdFieldAnnotationIntrospector());
this.setAnnotationIntrospector(pair);
}
}