美文网首页
fastjson字段序列化

fastjson字段序列化

作者: 鹅鹅鹅_ | 来源:发表于2020-01-20 22:29 被阅读0次

    在利用fastjson做序列化的时候发现这么一个错误:

    It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false) java.lang.IllegalStateException:
    It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false
    

    后来发现是因为格式化了HttpServletRequest类型:
    原文

    image.png

    文章里说FastJson是根据bean的get/set方法做反射解析的,对此有些疑问,经过与同事的探讨,并没有解决,所以自己直接上手ut来验证了:

    public class FastJsonTest {
        private final EasyRandom RANDOM = new EasyRandom();
    
        @Test
        public void test() {
            Foo foo = RANDOM.nextObject(Foo.class);
            String rstJson = JSON.toJSONString(foo, true);
            System.out.println(rstJson);
    
            rstJson = JSON.toJSONString(foo, SerializerFeature.IgnoreNonFieldGetter, SerializerFeature.PrettyFormat);
            System.out.println(rstJson);
        }
    
        private static class Foo {
            @Getter
            private String strWithGetter;
    
            private String strNoGetter;
    
            @Getter
            private static Integer intStaticWithGetter;
    
            private static Integer intStaticNoGetter;
    
            @Getter
            private EnumFoo enumWithGetter;
    
            private EnumFoo enumNoGetter;
    
            @Getter
            private static EnumFoo enumStaticWithGetter;
    
            private static EnumFoo enumStaticNoGetter;
    
            public String noFiledGetter() {
                return "noFiledGetter";
            }
    
            public String getNoFiledGetter() {
                return "getNoFiledGetter";
            }
        }
    
        private enum EnumFoo {
            ENUM1, ENUM2
        }
    }
    

    Run result

    {
        "enumWithGetter":"ENUM2",
        "noFiledGetter":"getNoFiledGetter",
        "strWithGetter":"eOMtThyhVNLWUZNRcBaQKxI"
    }
    {
        "enumWithGetter":"ENUM2",
        "strWithGetter":"eOMtThyhVNLWUZNRcBaQKxI"
    }
    

    结果证明:
    1、 FastJson确实是根据bean的get/set方法做反射解析的
    2、 FastJson不会格式化静态字段进入json,即使其有getter方法
    3、 SerializerFeature.IgnoreNonFieldGetter会忽略没有对应实际字段的getter方法
    4、 FastJson会格式化有getter方法的枚举字段

    针对FastJson格式化HttpServletRequest失败的问题,网上有几种方法可以解决,一种是添加SerializerFeature.IgnoreNonFieldGetter特性,另一种是将不能进行序列化的入参过滤掉:

     Object[] args = point.getArgs();
     List<Object> argsList=new ArrayList<>();
    for (int i = 0; i < args.length; i++) {
    // 如果参数类型是请求和响应的http,则不需要拼接【这两个参数,使用JSON.toJSONString()转换会抛异常】
    if (args[i] instanceof HttpServletRequest || args[i] instanceof HttpServletResponse)
    {
      continue;
    }
    argsList.add(args[i]);
    }
    

    但是感觉这些都不靠谱,经过研究发现其实可以添加SerializerFeature.IgnoreErrorGetter特性,这样可以忽略格式化失败的字段,但是其他可以格式化的字段也可以出现在结果中。

    相关文章

      网友评论

          本文标题:fastjson字段序列化

          本文链接:https://www.haomeiwen.com/subject/fudszctx.html