环境:jFinal3.3和Oracle 11g2
问题:Oracle的Timestamp类型在renderJson后无法正确显示时间
现象:
1.建表语句(创建了2个时间类型字段 test_data和test_times)
create table test(
id varchar(35) primary key,
test_date DATE,
test_times TIMESTAMP
)
2.添加测试数据,并自动生成model
3.控制层使用renderJson方法
4.访问控制层得到json
[{"ID":"1","TEST_DATE":"2017-12-11 17:47:46","TEST_TIMES":{"stream":{},"bytes":[120,117,12,11,18,48,50],"length":7}}]
注:在默认情况下Oracle的DATE字段能正常得到,但Oracle的Timestamp字段值解析便出了异常。
注:因为在renderJson判断时,oracle.sql.Timestamp没有与if分支相匹配,最后走的是value = rs.getObject(i),导致oracle.sql.Timestamp;如图(图中文件所在地址:com.jfinal.plugin.activerecord.builder.KeepByteAndShortModelBuilder中的build方法)
5.解决方法一
使用fastJson
在Config中配置fastJson作为jfinal的默认实现
访问控制层测试
Timestamp时间显示正常
注:该对象的model在自动生成时对oracle的timestamp的get,set方法经过了处理
解决方式二:
使用默认Jfinal json实现,自己新建ModelBuilder覆盖原有的KeepByteAndShortModelBuilder实现,并切换到自己的ModelBuilder
在自己项目中新建一个类MyOracleModelBuilder,
public class MyOracleModelBuilder extends ModelBuilder{
public static final MyOracleModelBuilder me = new MyOracleModelBuilder();
@SuppressWarnings({"rawtypes", "unchecked"})
public <T> List<T> build(ResultSet rs, Class<? extends Model> modelClass) throws SQLException, InstantiationException, IllegalAccessException {
List<T> result = new ArrayList<T>();
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
String[] labelNames = new String[columnCount + 1];
int[] types = new int[columnCount + 1];
buildLabelNamesAndTypes(rsmd, labelNames, types);
while (rs.next()) {
Model<?> ar = modelClass.newInstance();
Map<String, Object> attrs = CPI.getAttrs(ar);
for (int i=1; i<=columnCount; i++) {
Object value;
if(types[i] == Types.TIMESTAMP){
value = rs.getTimestamp(i);
}
else if(types[i] == Types.DATE){
value = rs.getDate(i);
}
else if (types[i] == Types.TINYINT)
value = rs.getByte(i);
else if (types[i] == Types.SMALLINT)
value = rs.getShort(i);
else if (types[i] < Types.BLOB)
value = rs.getObject(i);
else if (types[i] == Types.CLOB)
value = handleClob(rs.getClob(i));
else if (types[i] == Types.NCLOB)
value = handleClob(rs.getNClob(i));
else if (types[i] == Types.BLOB)
value = handleBlob(rs.getBlob(i));
else
value = rs.getObject(i);
attrs.put(labelNames[i], value);
}
result.add((T)ar);
}
return result;
}
}
在源码的实现上新增2个if判断(加粗部分),然后在Config中切换到我们自定义MyOracleModelBuilder
查看效果
ok,大功告成。
快看看成功了吗?