前言:最近在做一个通用查询单表的组件,所以 sql 的写法就是 select *,然后 resultType="map" ,然后使用 jackson @ResponseBody 返回前端报错。 转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9708485.html

后台报错:

26-Sep-2018 22:18:08.209 WARNING [http-apr-8080-exec-8] org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.handleHttpMessageNotWritable Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS); nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.HashMap["pageData"]->java.util.ArrayList[2]->java.util.HashMap["UPDATE_TIME"]->oracle.sql.TIMESTAMP["stream"])

表字段(oracle):

sql (mybatis):

原因:

经测试,oracle 数据库字段为 Data 型的并不会报错,只有 timestamp 类型会报错。

从后台报错日志中发现(through reference chain: java.util.HashMap["pageData"]->java.util.ArrayList[2]->java.util.HashMap["UPDATE_TIME"]->oracle.sql.TIMESTAMP["stream"]) ,

然后发现返回的 map 里面 update_time 字段为 oracle.sql.TIMESTAMP 类型,并不是 java.sql.Timestamp,所以 json 转换出错。

其实都是因为 mybatis 当 ResultMap 为 map 时,会把数据的原始类型原样返回,所以得到的map里面都是 oracle.sql.DATE、oracle.sql.TIMESTAMP 之类的。因为 mybatis 在没有指定类型时都会采用 ObjectTypeHandle 来处理字段。

解决方案:

自定义 typeHandle 来统一处理数据库字段类型为 timestamp 等特殊的字段。

这里 typeHandle 里面使用注解配置 JdbcType 和 JavaType。这两个注解的定义是:

  • @MappedTypes 定义的是 JavaType 类型,可以指定哪些 Java 类型被拦截。
  • @MappedJdbcTypes 定义的是 JdbcType 类型,它需要满足枚举类 org.apache.ibatis.type.JdbcType 所列的枚举类型。

代码如下:

myBatis 的配置文件中加入:

    <typeHandlers>
<typeHandler handler="com.yule.system.typehandler.MyObjectTypeHandle"/>
</typeHandlers>

新增新的 java 类:

package com.yule.system.typehandler;

import oracle.sql.DATE;
import oracle.sql.TIMESTAMP;
import oracle.sql.TIMESTAMPLTZ;
import oracle.sql.TIMESTAMPTZ;
import org.apache.ibatis.type.*; import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date; /**
* 模仿 ObjectTypeHandle 来处理 timestamp 报错问题
* @author yule
* @date 2018/9/26 22:43
*/
@MappedTypes({Object.class})
@MappedJdbcTypes(value = {JdbcType.TIMESTAMP})
public class MyObjectTypeHandle extends BaseTypeHandler<Object> { public MyObjectTypeHandle() {
} @Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
ps.setObject(i, parameter);
} @Override
public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
Object result = rs.getObject(columnName);
return rs.wasNull() ? null : dealResult(result);
} @Override
public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
Object result = rs.getObject(columnIndex);
return rs.wasNull() ? null : dealResult(result);
} @Override
public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
Object result = cs.getObject(columnIndex);
return cs.wasNull() ? null : dealResult(result);
} /**
* 为了解决错误:
* 26-Sep-2018 14:21:06.634 WARNING [http-apr-8080-exec-6] org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.handleHttpMessageNotWritable Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException:
* Could not write JSON: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer
* (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS);
* nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
* (through reference chain: java.util.HashMap["pageData"]->java.util.ArrayList[0]->java.util.HashMap["UPDATE_TIME"]->oracle.sql.TIMESTAMP["stream"])
* @param result
* @return
* @throws SQLException
*/
private Object dealResult(Object result) throws SQLException {
if (result instanceof TIMESTAMP) {
return new Date(((TIMESTAMP) result).dateValue().getTime());
} else if (result instanceof DATE) {
return new Date(((DATE) result).dateValue().getTime());
} else if (result instanceof TIMESTAMPLTZ) {
return new Date(((TIMESTAMPLTZ) result).dateValue().getTime());
} else if (result instanceof TIMESTAMPTZ) {
return new Date(((TIMESTAMPTZ) result).dateValue().getTime());
} else{
return result;
}
}
}

转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9708485.html

解决:oracle+myBatis ResultMap 类型为 map 时返回结果中存在 timestamp 时使用 jackson 转 json 报错的更多相关文章

  1. 解决:oracle+myBatis ResultMap 类型为 map 时,表字段类型有 Long/Blob/Clob 时报错

    前言:最近在做一个通用查询单表的组件,所以 sql 的写法就是 select *,然后 resultType="map" .如果数据库中的表里有字段类型为 Long 等类型时,my ...

  2. Eclipse中引入com.sun.image.codec.jpeg包报错的完美解决办法

    转: Eclipse中引入com.sun.image.codec.jpeg包报错的完美解决办法  更新时间:2018年02月14日 17:13:03   投稿:wdc   我要评论   Java开发中 ...

  3. sql中有一些保留字,当你的字段名是它的保留字时,这个时候sql语句的字段不加``就会报错

    sql中有一些保留字,当你的字段名是它的保留字时,这个时候sql语句的字段不加``就会报错

  4. mybatis mapper.xml 写关联查询 运用 resultmap 结果集中 用 association 关联其他表 并且 用 association 的 select 查询值 报错 java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for mybatis.map

    用mybaits 写一个关联查询 查询商品表关联商品规格表,并查询规格表中的数量.价格等,为了sql重用性,利用 association 节点 查询 结果并赋值报错 商品表的mapper文件为Gooo ...

  5. 解决Oracle+Mybatis批量插入报错:SQL 命令未正确结束

    Mybatis批量插入需要foreach元素.foreach元素有以下主要属性: (1)item:集合中每一个元素进行迭代时的别名. (2)index:指定一个名字,用于表示在迭代过程中,每次迭代到的 ...

  6. Java处理JPEG图片时,需要导入com.sun.image.codec.jpeg.JPEGImageEn,报错处理

    Java处理JPEG图片时,需要导入com.sun.image.codec.jpeg.JPEGImageEn,会报错,不能使用相应的方法. 原因:java访问限制级api的时候,默认的eclipse设 ...

  7. 在Openstack H版部署Nova Cell 时 ,终端输入nova service-list 和 nova host-list 命令将报错

    关于Cell的基本介绍,可以参考贤哥的一篇文章: [OpenStack]G版中关于Nova的Cell  http://blog.csdn.net/lynn_kong/article/details/8 ...

  8. IDEA导入maven中导入net.sf.json报错的解决方法

    使用IDEA搭建Maven项目导入架包时, 添加net.sf.json的jar包的时候,代码如下: 在pom.xml文件时: <dependency> <groupId>net ...

  9. 解决连接oracle报错 尝试加载Oracle客户端库时引发BadImageFomatException。如果在安装64位Oracle客户端组件的情况下以32位模式运行,将出现此问题的报错。

    最近遇到一个.NET连接Oracle的一个错误,其主要原因是换了一台电脑,在新电脑上运行以前的项目出现了的一个错误,工作环境为vs2017+Oracle 64位,win10系统 这个错误头疼了一天,找 ...

随机推荐

  1. FreePascal - CodeTyphon交叉编译,在一个操作系统生成各个操作系统可以运行的程序!

    致谢:[XE3]MN,让我加快完成了使用CodeTyphon进行交叉编译! CodeTyphon版本: 6.0 下载:http://www.pilotlogic.com/codetyphon/zips ...

  2. AGC032D Rotation Sort

    题目传送门 Description 给定\(N\)的排列(\(N\leq5000\)),将任一区间最左侧的数插到该区间最右边的代价为\(A\),将任一区间最右侧的数插到该区间最左边的代价为\(B\), ...

  3. redis 数据备份持久化方案

    本文链接:http://www.cnblogs.com/zhenghongxin/p/9050219.html 使用两种备份方案 备份方案选择RDB和AOF同时进行备份,必须打开AOF的持久化机制,除 ...

  4. maven項目創建紅叉

    出现问题的原因: 解决方案: 在pom.xml中配置jdk的版本

  5. Python(文件上传)

    day26 通过socket上传文件. post_client.py import socket import os sk = socket.socket() print(sk) address = ...

  6. 【javascript】iOS Safari 中点击事件失效的解决办法

    问题描述 当使用委托给一个元素添加click事件时,如果事件是委托到 document 或 body 上,并且委托的元素是默认不可点击的(如 div, span 等),此时 click 事件会失效. ...

  7. 阿里官方Java代码规范标准《阿里巴巴Java开发手册》下载

    https://bbs.aliyun.com/read/306592.html?page=e 2017年开春之际,诚意献上重磅大礼:阿里巴巴Java开发手册,首次公开阿里官方Java代码规范标准. 这 ...

  8. Swift 里字符串(七)stringIndex

    在 String 里,用来索引 Character 的,不是整数,而是StringIndex 内部结构 extension String { /// A position of a character ...

  9. 适配 iOS 11 & iPhone X 大全

    1.升级iOS11后造成的变化 1. 1升级后,发现某个拥有tableView的界面错乱,组间距和contentInset错乱,因为iOS11中UIViewController的automatical ...

  10. 如何安装windows7

    前因:之前安装的win7的系统,用了激活工具,刚开始的几个星期还没察觉有何问题.直到有天系统给出异常提示:系统资源不足,无法完成请求的服务.仔细排查之后发现是系统内核句柄数一直增加不释放,句柄数大概有 ...