项目中使用spring注解@ResponseBody + jackson来返回JSON数据,以前的时候都很正常,最近做的一个功能的时候却
出现了问题。
发送请求后,前台报500 Internal Server Error错误,到了后台,却没有任何报错信息,DEBUG跟进的时候也没有任何问题,
查询出数据并返回数据都没有报错。所以猜测是转JSON字符串的时候报的错,在JAVA中直接用jackson的ObjectMapper把对象
转成字符串看看有没有问题,代码如下:
ObjectMapper mapper=new ObjectMapper();
String jsonString=mapper.writeValueAsString(list);
System.out.print(jsonString);
这个时候后台就打印错误信息了,如下:
org.codehaus.jackson.map.JsonMappingException: No serializer found for class java.io.BufferedReader and no properties
discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) )
(through reference chain: java.util.ArrayList[1]->com.wei.liu.springmvc.czyw.bean.Czyw["tm"]->$Proxy44["characterStream"])
看了错误提示SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS,想通过设置此属性解决,代码如下:
ObjectMapper mapper=new ObjectMapper();
mapper.configure(Feature.FAIL_ON_EMPTY_BEANS, false);
我用的是SQLSERVER,报方言不支持,不知道其它的数据库怎么样,只好想其它办法。
看到$Proxy44,想到可能是HIERNATE的懒加载引起的问题,于是想不格式化此字段,在对应的实体类上加如下代码:
@JsonIgnoreProperties(value={"hibernateLazyInitializer"})
加了之后还是不行,报同样的错。
最后发现,是clob类型的对象即使不用懒加载,也必须到数据库里再查询一次,并且HIERNATE自动给它加上了代理,想到问题原因
后就好解决了,我们自己来写json组装方法,对于clob类型的对象,直接到数据库里读取,并把值返回回去,代码如下:
public class CustomObjectMapper extends ObjectMapper {
public CustomObjectMapper(){
CustomSerializerFactory factory = new CustomSerializerFactory();
factory.addGenericMapping(Clob.class, new JsonSerializer<Clob>(){
@Override
public void serialize(Clob value,
JsonGenerator jsonGenerator,
SerializerProvider provider)
throws IOException, JsonProcessingException {
try {
Reader reader = value.getCharacterStream();
BufferedReader br = new BufferedReader(reader);
String s = br.readLine();
jsonGenerator.writeString(s);
} catch (SQLException e) {
e.printStackTrace();
}
}
});
this.setSerializerFactory(factory);
}
}
配置SPRING的JSON转制器:
<bean id="customObjectMapper" class="com.phenix.core.CustomObjectMapper"></bean>
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="customObjectMapper"></property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
重新部署,解决。