开发者社区> 问答> 正文

Json字符串格式的Model反序列化为Model时候,类型丢失问题??报错

@JFinal 你好,想跟你请教个问题:

波总,再次请教您。我这边场景是这样的,c/s桌面程序,从client发出请求到server端,请求的数据都是序列化后的Json,但是现在有一个问题,Json到达java服务端后,反序列化时候,Model中原始的属性类型丢失了。

比如datetime日期变更了字符串,float,double变成了bigdecimal格式。这个类型变异导致的结果是,我无法准确的拿到model的准确类型,使用model的基础方法, 如getfloat,getdate全部报错,需要借助工具类先将数据tostring,再Float.valueof提取到我需要的float数据,但是如此依赖,代码不够优雅,而且有不必要碎片。

在开源中国上已经看到有开发者提出了解决办法,链接如下 http://my.oschina.net/taijunfeng/blog/354181?p={{page}}

我参考这个开发者的解决思路,在json反序列为model的时候,拿到JFinal缓存下来的talbe meta,对字段类型进行修正。但是又发现了新的问题。以下是我一个表中,检测到属性 和类型的映射关系

在我圈起来的地方,数据库用的类型是smallint,然后我查看到JFinal映射到smallint类型是String,

如此依赖,在修正Model类型的时候,凡是数据库字段是smallint的就无法准确修正类型。需要在get属性值的时候,做额外处理。

请问这个,smallint格式无法准确映射到short类型是Jfinal的一个bug吗?期待您的回复。

展开
收起
爱吃鱼的程序员 2020-06-14 16:35:52 750 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    引用来自“JFinal”的评论

    publicvoidtestTypes()throwsSQLException{
     Stringsql=DbKit.config.getDialect().forTableBuilderDoBuild("jfinal");
     Statementstm=DbKit.config.getConnection().createStatement();
     ResultSetrs=stm.executeQuery(sql);
     ResultSetMetaDatarsmd=rs.getMetaData();

     for(inti=1;i<=rsmd.getColumnCount();i++){
      StringcolName=rsmd.getColumnName(i);
      StringcolClassName=rsmd.getColumnClassName(i);
       print(rsmd,i);
     }
    }

    publicvoidprint(ResultSetMetaDatarsmd,inti)throwsSQLException{
    inttype=rsmd.getColumnType(i);
    if(type==Types.BLOB)
    System.out.println(rsmd.getColumnLabel(i)+"--->BLOB--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.VARCHAR)
    System.out.println(rsmd.getColumnLabel(i)+"--->VARCHAR--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.INTEGER)
    System.out.println(rsmd.getColumnLabel(i)+"--->INTEGER--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.BINARY)
    System.out.println(rsmd.getColumnLabel(i)+"--->BINARY--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.SMALLINT)
    System.out.println(rsmd.getColumnLabel(i)+"--->SMAILLINT--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.DATE)
    System.out.println(rsmd.getColumnLabel(i)+"--->DATE--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.TIME)
    System.out.println(rsmd.getColumnLabel(i)+"--->TIME--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.TIMESTAMP)
    System.out.println(rsmd.getColumnLabel(i)+"--->TIMESTAMP--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.BIGINT)
    System.out.println(rsmd.getColumnLabel(i)+"--->BIGINT--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.TINYINT)
    System.out.println(rsmd.getColumnLabel(i)+"--->TINYINT--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.BIT)
    System.out.println(rsmd.getColumnLabel(i)+"--->BIT--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.DOUBLE)
    System.out.println(rsmd.getColumnLabel(i)+"--->DOUBLE--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.DECIMAL)
    System.out.println(rsmd.getColumnLabel(i)+"--->DECIMAL--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.CHAR)
    System.out.println(rsmd.getColumnLabel(i)+"--->CHAR--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.REAL)
    System.out.println(rsmd.getColumnLabel(i)+"--->REAL--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.VARBINARY)
    System.out.println(rsmd.getColumnLabel(i)+"--->VARBINARY--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.LONGVARBINARY)
    System.out.println(rsmd.getColumnLabel(i)+"--->LONGVARBINARY--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.LONGVARCHAR)
    System.out.println(rsmd.getColumnLabel(i)+"--->LONGVARCHAR--->"+rsmd.getColumnClassName(i));
    else
    System.out.println("没找到类型:type--->"+type+rsmd.getColumnClassName(i));
    }

      刚刚我在本地测试了一下,mysql的smallint映射为了java的Integer类型,并且在Model.getInt(String)方法的注释中也有过说明,如下:

    调试一下,类型错误是在哪个环节发生的

    引用来自“JFinal”的评论

      刚刚我在本地测试了一下,mysql的smallint映射为了java的Integer类型,并且在Model.getInt(String)方法的注释中也有过说明,如下:

    调试一下,类型错误是在哪个环节发生的

    sqlserver的话,去群里找个有环境的人测试一下,程序我在下面给出,我本地没有sqlserver环境publicvoidtestTypes()throwsSQLException{
     Stringsql=DbKit.config.getDialect().forTableBuilderDoBuild("jfinal");
     Statementstm=DbKit.config.getConnection().createStatement();
     ResultSetrs=stm.executeQuery(sql);
     ResultSetMetaDatarsmd=rs.getMetaData();

     for(inti=1;i<=rsmd.getColumnCount();i++){
      StringcolName=rsmd.getColumnName(i);
      StringcolClassName=rsmd.getColumnClassName(i);
       print(rsmd,i);
     }
    }

    publicvoidprint(ResultSetMetaDatarsmd,inti)throwsSQLException{
    inttype=rsmd.getColumnType(i);
    if(type==Types.BLOB)
    System.out.println(rsmd.getColumnLabel(i)+"--->BLOB--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.VARCHAR)
    System.out.println(rsmd.getColumnLabel(i)+"--->VARCHAR--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.INTEGER)
    System.out.println(rsmd.getColumnLabel(i)+"--->INTEGER--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.BINARY)
    System.out.println(rsmd.getColumnLabel(i)+"--->BINARY--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.SMALLINT)
    System.out.println(rsmd.getColumnLabel(i)+"--->SMAILLINT--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.DATE)
    System.out.println(rsmd.getColumnLabel(i)+"--->DATE--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.TIME)
    System.out.println(rsmd.getColumnLabel(i)+"--->TIME--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.TIMESTAMP)
    System.out.println(rsmd.getColumnLabel(i)+"--->TIMESTAMP--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.BIGINT)
    System.out.println(rsmd.getColumnLabel(i)+"--->BIGINT--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.TINYINT)
    System.out.println(rsmd.getColumnLabel(i)+"--->TINYINT--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.BIT)
    System.out.println(rsmd.getColumnLabel(i)+"--->BIT--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.DOUBLE)
    System.out.println(rsmd.getColumnLabel(i)+"--->DOUBLE--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.DECIMAL)
    System.out.println(rsmd.getColumnLabel(i)+"--->DECIMAL--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.CHAR)
    System.out.println(rsmd.getColumnLabel(i)+"--->CHAR--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.REAL)
    System.out.println(rsmd.getColumnLabel(i)+"--->REAL--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.VARBINARY)
    System.out.println(rsmd.getColumnLabel(i)+"--->VARBINARY--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.LONGVARBINARY)
    System.out.println(rsmd.getColumnLabel(i)+"--->LONGVARBINARY--->"+rsmd.getColumnClassName(i));
    elseif(type==Types.LONGVARCHAR)
    System.out.println(rsmd.getColumnLabel(i)+"--->LONGVARCHAR--->"+rsmd.getColumnClassName(i));
    else
    System.out.println("没找到类型:type--->"+type+rsmd.getColumnClassName(i));
    }
    2020-06-14 16:36:11
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载