Jfinal Model 转JSON遇到的坑

配置如下:

me.setJsonFactory(new FastJsonFactory());


Model 中定义方法

public List<MemberLoginBackground> getAll() {
    return find("select id,image from member_login_background where is_del='N' ");
}


使用JsonKit.toJson

List<MemberLoginBackground> rand = MemberLoginBackground.dao.getAll();
String bb = JsonKit.toJson(rand);


然后就卡死了,最终StackOverflowError

Caused by: java.lang.StackOverflowError

at com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor.visit(MySqlOutputVisitor.java:639)

at com.alibaba.druid.sql.ast.expr.SQLCharExpr.accept0(SQLCharExpr.java:43)

at com.alibaba.druid.sql.ast.SQLObjectImpl.accept(SQLObjectImpl.java:41)

at com.alibaba.druid.sql.visitor.SQLASTOutputVisitor.visitorBinaryRight(SQLASTOutputVisitor.java:435)

at com.alibaba.druid.sql.visitor.SQLASTOutputVisitor.visit(SQLASTOutputVisitor.java:396)

at com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr.accept0(SQLBinaryOpExpr.java:98)

at com.alibaba.druid.sql.ast.SQLObjectImpl.accept(SQLObjectImpl.java:41)

at com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor.visit(MySqlOutputVisitor.java:277)

at com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.accept0(MySqlSelectQueryBlock.java:219)

at com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.accept0(MySqlSelectQueryBlock.java:210)

at com.alibaba.druid.sql.ast.SQLObjectImpl.accept(SQLObjectImpl.java:41)

at com.alibaba.druid.sql.visitor.SQLASTOutputVisitor.visit(SQLASTOutputVisitor.java:1033)

at com.alibaba.druid.sql.ast.statement.SQLSelect.accept0(SQLSelect.java:87)

at com.alibaba.druid.sql.ast.SQLObjectImpl.accept(SQLObjectImpl.java:41)

at com.alibaba.druid.sql.visitor.SQLASTOutputVisitor.visit(SQLASTOutputVisitor.java:1279)

at com.alibaba.druid.sql.ast.statement.SQLSelectStatement.accept0(SQLSelectStatement.java:63)

at com.alibaba.druid.sql.ast.SQLObjectImpl.accept(SQLObjectImpl.java:41)

at com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils.parameterize(ParameterizedOutputVisitorUtils.java:66)

at com.alibaba.druid.wall.WallProvider.getWhiteSql(WallProvider.java:463)

at com.alibaba.druid.wall.WallProvider.checkWhiteAndBlackList(WallProvider.java:730)

at com.alibaba.druid.wall.WallProvider.checkInternal(WallProvider.java:596)

at com.alibaba.druid.wall.WallProvider.check(WallProvider.java:574)

at com.alibaba.druid.wall.WallFilter.check(WallFilter.java:712)

at com.alibaba.druid.wall.WallFilter.connection_prepareStatement(WallFilter.java:253)

at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:448)

at com.alibaba.druid.filter.FilterAdapter.connection_prepareStatement(FilterAdapter.java:928)

at com.alibaba.druid.filter.FilterEventAdapter.connection_prepareStatement(FilterEventAdapter.java:122)

at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:448)

at com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl.prepareStatement(ConnectionProxyImpl.java:342)

at com.alibaba.druid.pool.DruidPooledConnection.prepareStatement(DruidPooledConnection.java:346)

at com.jfinal.plugin.activerecord.Model.find(Model.java:641)

at com.jfinal.plugin.activerecord.Model.find(Model.java:660)

at com.jfinal.plugin.activerecord.Model.find(Model.java:672)

at com.ibdyr.model.system.MemberLoginBackground.getAll(MemberLoginBackground.java:18)

at com.alibaba.fastjson.serializer.ASMSerializer_1_MemberLoginBackground.write(Unknown Source)

at com.alibaba.fastjson.serializer.ASMSerializer_1_MemberLoginBackground.write(Unknown Source)

at com.alibaba.fastjson.serializer.ASMSerializer_1_MemberLoginBackground.write(Unknown Source)

at com.alibaba.fastjson.serializer.ASMSerializer_1_MemberLoginBackground.write(Unknown Source)

at com.alibaba.fastjson.serializer.ASMSerializer_1_MemberLoginBackground.write(Unknown Source)

at com.alibaba.fastjson.serializer.ASMSerializer_1_MemberLoginBackground.write(Unknown Source)

at com.alibaba.fastjson.serializer.ASMSerializer_1_MemberLoginBackground.write(Unknown Source)

at com.alibaba.fastjson.serializer.ASMSerializer_1_MemberLoginBackground.write(Unknown Source)

at com.alibaba.fastjson.serializer.ASMSerializer_1_MemberLoginBackground.write(Unknown Source)

at com.alibaba.fastjson.serializer.ASMSerializer_1_MemberLoginBackground.write(Unknown Source)

at com.alibaba.fastjson.serializer.ASMSerializer_1_MemberLoginBackground.write(Unknown Source)

at com.alibaba.fastjson.serializer.ASMSerializer_1_MemberLoginBackground.write(Unknown Source)

at com.alibaba.fastjson.serializer.ASMSerializer_1_MemberLoginBackground.write(Unknown Source)

at com.alibaba.fastjson.serializer.ASMSerializer_1_MemberLoginBackground.write(Unknown Source)

at com.alibaba.fastjson.serializer.ASMSerializer_1_MemberLoginBackground.write(Unknown Source)

at com.alibaba.fastjson.serializer.ASMSerializer_1_MemberLoginBackground.write(Unknown Source)


评论区

杜福忠

2018-08-24 20:17

Model 中禁止写查询等操作, 而且还是自查, 转JSON时 getAll()等写法, 会被当字段属性被调的!! 然后查询的还是自己这个类, 又会被当属性调,,无限循环中..... 虽然默认有递归次数, 但是这样写, 肯定是不规范的!

只要记住一点, Model 中禁止写业务代码即可.

还有一点, 问题写在 [反馈] 栏目

JFinal

2018-08-24 20:43

fastjson 默认没有处理这类循环依赖的转换情况,碰到这种情况,可以用一下:
me.setJsonFactory(new MixedJsonFactory());

这样就可以用 jfinal 的实现去转换 json ,而 jfinal 自己的实现是限定过转换深度的,确保安全

如果希望一直使用 FastJsonFactory,还可以在这种情况下临时使用 jfinal json:
JFinalJson.get().toJson(...);

临时使用不需要配置,随时都可以

热门分享

扫码入社