当你的序列化方式采用的FastJson时,该如何处理这种类型转换问题呢?一模一样的套路…
SpringMVC 使用FastJson序列化方式
1.增加类型转换类:
public class FastJsonConfigExt extends FastJsonConfig {
public FastJsonConfigExt(){
super();
SerializeConfig serializeConfig = SerializeConfig.globalInstance;
serializeConfig.put(BigInteger.class, ToStringSerializer.instance);
serializeConfig.put(Long.class,ToStringSerializer.instance);
serializeConfig.put(Long.TYPE,ToStringSerializer.instance);
this.setSerializeConfig(serializeConfig);
}
}
2.spring mvc 配置文件增加:
<!--解决fastJson 转换long型,精度丢失的问题-->
<bean id="fastJsonConfigExt" class="com.ymm.web.configuration.FastJsonConfigExt"/>
<!-- 解决@ResponseBody注解直接返回对象并转换成JSON时出现406问题,同时解决了返回String类型乱码的问题 -->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="fastJsonConfig" ref="fastJsonConfigExt" />
<property name="supportedMediaTypes">
<list>
<value>application/json; charset=UTF-8</value>
<value>application/x-www-form-urlencoded; charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
</list>
</property>
<property name="features">
<list>
<!-- null String也要输出 -->
<value>WriteMapNullValue</value>
<!-- 输出key时是否使用双引号 -->
<value>QuoteFieldNames</value>
<!-- 字符类型字段如果为null,输出为"",而非null -->
<value>WriteNullStringAsEmpty</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
执行完以上两个步骤,便可以将Long类型转为String类型,然后在序列化为JSON数据。但是存在一个问题:fastjson不支持基础类型如long double等的转换,仅支持包装类型。如何解决呢,请看下文。
使用FastJson自定义过滤器,过滤指定字段
1.通过实现FastJson的ValueFilter接口,增加自定义类型转换器。
public class FastJsonFilterExt implements ValueFilter {
@Override
public Object process(Object object, String name, Object value) {
String userIdStr = "";
switch (name.toLowerCase()) {
case "userid":
case "orderid":{
if (value != null) {
userIdStr = String.valueOf(value);
return userIdStr;
}
}
}
return value;
}
}
2.xml追加配置:
<!--解决fastJson 转换long型,精度丢失的问题-->
<bean id="fastJsonFilterExt" class="com.ymm.web.configuration.FastJsonFilterExt"/>
<!-- 解决@ResponseBody注解直接返回对象并转换成JSON时出现406问题,同时解决了返回String类型乱码的问题 -->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json; charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
</list>
</property>
<property name="features">
<list>
<!-- null String也要输出 -->
<value>WriteMapNullValue</value>
<!-- 输出key时是否使用双引号 -->
<value>QuoteFieldNames</value>
<!-- 字符类型字段如果为null,输出为"",而非null -->
<value>WriteNullStringAsEmpty</value>
</list>
</property>
<property name="filters">
<list>
<ref bean="fastJsonFilterExt"></ref>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
上面通过指定字段名称的方式进行过滤转换类型,解决了long等基础数据类型不能转换为String的问题,同时指定字段进行类型转换避免了所有Long类型字段都被转换的尴尬。
使用自定义注解,过滤指定字段
当然也可以通过增加自定义注解方式,在实体属性上面增加自定义注解,指定要转换的字段,在转换器中判断是否包含注解。
1.增加自定义注解:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface FieldToString {
public String value() default "true";
}
2.增加转换器:
public class BeanPropertyFilter implements ValueFilter {
private Field field = null;
@Override
public Object process(Object obj, String name, Object value) {
Boolean flag = false;
try {
field = obj.getClass().getDeclaredField(name);
// 获取注解
flag = field.getAnnotation(FieldToString.class).value().equals("true");
if (flag == true && value != null) {
// 将其他类型转换成String类型
value = String.valueOf(value);
}
} catch (NoSuchFieldException e) {
return value;
} catch (Exception e) {
return value;
}
return value;
}
}
3.使用方式
直接在要转换的字段上增加@FieldToString注解即可。
参考:
https://www.jianshu.com/p/8d8152725114?from=singlemessage