将Json反序化为嵌套的pojo

时间:2017-04-12 21:37:48

标签: java jackson

似乎有一些类似的问题,但我似乎无法找到答案?

我试图解析控制器中jqGrid过滤器属性返回的json。为了让它正常工作,我以一种非常笨重的方式进行操作,虽然一旦我开始工作,我希望下一步并将其作为RequestBody传递,让Spring处理其中一些。现在我想尽可能让它以这种方式工作?好像它应该只是工作,所以也许我犯了一个愚蠢的错误?

json样本

  {"groupOp":"AND","rules":[{"field":"accountName","op":"cn","data":"E"},{"field":"accountRef","op":"cn","data":"E"}]}

我已经制作了2个快速pojos来尝试反序列化数据

@SuppressWarnings("unused")
private class Filter {

    private String groupOp;
    private List<Rule> rules; 

    public String getGroupOp() {
        return groupOp;
    }
    public void setGroupOp(String groupOp) {
        this.groupOp = groupOp;
    }

    public List<Rule> getRules() {
        return rules;
    }
    public void setRules(List<Rule> rules) {
        this.rules = rules;
    }

}   

private class Rule {

        private String field;
        private String op; 
        private String data; 

        public String getField() {
            return field;
        }
        public void setField(String field) {
            this.field = field;
        }

        public String getOp() {
            return op;
        }
        public void setOp(String op) {
            this.field = op;
        }

        public String getData() {
            return data;
        }
        public void setData(String data) {
            this.data = data;
        }
}

json字符串在一个名为filter的String参数中,有一个非常基本的代码来反序列化它

byte[] jsonData = filter.getBytes();

ObjectMapper objectMapper = new ObjectMapper();         
Filter f = objectMapper.readValue(jsonData, Filter.class);

我对样本的阅读是这是非常基础和写得不好但应该做的工作。相反,我得到一个错误......

我在这里复制了完整的错误,这可能是落水的?谁能告诉我哪里出错?

com.fasterxml.jackson.databind.JsonMappingException: Can not construct 
instance of com.app.AppController$Filter: no String-argument constructor/factory method to deserialize from String value (' {"groupOp":"AND","rules":[{"field":"accountName","op":"cn","data":"E"},{"field":"accountRef","op":"cn","data":"E"}]}')
 at [Source: [B@5bfd2bb5; line: 1, column: 1]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270) ~[jackson-databind-2.8.7.jar:2.8.7]
    at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:1456) ~[jackson-databind-2.8.7.jar:2.8.7]
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1012) ~[jackson-databind-2.8.7.jar:2.8.7]
    at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:370) ~[jackson-databind-2.8.7.jar:2.8.7]
    at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:315) ~[jackson-databind-2.8.7.jar:2.8.7]
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1290) ~[jackson-databind-2.8.7.jar:2.8.7]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:159) ~[jackson-databind-2.8.7.jar:2.8.7]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:150) ~[jackson-databind-2.8.7.jar:2.8.7]
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3798) ~[jackson-databind-2.8.7.jar:2.8.7]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2929) ~[jackson-databind-2.8.7.jar:2.8.7]
    at com.app.AppController.downloadAccounts(AppController.java:580) ~[classes/:na]
    at com.app.AppController$$FastClassBySpringCGLIB$$6a077f1a.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-5.0.0.M3.jar:5.0.0.M3]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720) ~[spring-aop-5.0.0.M3.jar:5.0.0.M3]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-5.0.0.M3.jar:5.0.0.M3]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-5.0.0.M3.jar:5.0.0.M3]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-5.0.0.M3.jar:5.0.0.M3]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) ~[spring-aop-5.0.0.M3.jar:5.0.0.M3]
    at com.app.AppControllerController$$EnhancerBySpringCGLIB$$8ff0ac7a.downloaAccounts(<generated>) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_101]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:220) ~[spring-web-5.0.0.M3.jar:5.0.0.M3]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134) ~[spring-web-5.0.0.M3.jar:5.0.0.M3]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116) ~[spring-webmvc-5.0.0.M3.jar:5.0.0.M3]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-5.0.0.M3.jar:5.0.0.M3]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-5.0.0.M3.jar:5.0.0.M3]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-5.0.0.M3.jar:5.0.0.M3]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) ~[spring-webmvc-5.0.0.M3.jar:5.0.0.M3]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) ~[spring-webmvc-5.0.0.M3.jar:5.0.0.M3]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:964) [spring-webmvc-5.0.0.M3.jar:5.0.0.M3]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:856) [spring-webmvc-5.0.0.M3.jar:5.0.0.M3]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:841) [spring-webmvc-5.0.0.M3.jar:5.0.0.M3]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) [spring-web-5.0.0.M3.jar:5.0.0.M3]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.0.M3.jar:5.0.0.M3]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) [tomcat-embed-core-7.0.47.jar:7.0.47]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_101]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_101]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_101]

1 个答案:

答案 0 :(得分:1)

我发现FilterRule都是私有的内部类。这就是为什么杰克逊无法创建它们的实例。尝试将它们设为公共嵌套类,即将它们声明为public static类,或将它们移动到单独的源文件中。

我还在堆栈跟踪中注意到,您的字节数组在开头包含单引号,在结尾处包含另一个引号。你应该删除它们,第一个字符应该是一个左括号,最后一个字符应该是一个右括号。否则,readValue会将其视为字符串。