Gson反序列化JSON。 java.lang.RuntimeException:无法调用具有根本原因的public com.derp.procedure.model.SkeletonElement(),无参数)

这是我第一次与JSON和Java。 我已经检查了很多像我一样的错误的问题。 但没有发现任何有用的东西。

我明白,我不得不添加参数构造函数。 我已经修好了,但它没有帮助我。 仍然发生相同的错误。 它可以这样工作。 我认为这与我的代码相当复杂的inheritance有关。

错误:

SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/derp] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: Failed to invoke public com.derp.procedure.model.SkeletonElement() with no args] with root cause java.lang.InstantiationException 

堆栈跟踪:

 gru 19, 2014 8:27:50 PM org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/derp] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: Failed to invoke public com.derp.procedure.model.SkeletonElement() with no args] with root cause java.lang.InstantiationException at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48) at java.lang.reflect.Constructor.newInstance(Constructor.java:408) at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:104) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:186) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40) at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81) at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60) at com.google.gson.Gson.fromJson(Gson.java:810) at com.google.gson.Gson.fromJson(Gson.java:775) at com.google.gson.Gson.fromJson(Gson.java:724) at com.derp.procedure.model.SkeletonElement.toObject(SkeletonElement.java:38) at com.derp.procedure.model.Skeleton.setSkeletonElements(Skeleton.java:53) at com.derp.procedure.controller.ProcedureController.elementsAssignmentSubmit(ProcedureController.java:81) at com.derp.procedure.controller.ProcedureController$$FastClassBySpringCGLIB$$35de90ba.invoke() at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:266) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653) at com.derp.procedure.controller.ProcedureController$$EnhancerBySpringCGLIB$$fe2945ed.elementsAssignmentSubmit() at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:879) at javax.servlet.http.HttpServlet.service(HttpServlet.java:647) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:136) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:526) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:655) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:146) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:279) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745) 

我的Java类:

扩展的通用模型类:

 package com.derp.generic.model; import java.io.IOException; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.MappedSuperclass; import javax.persistence.Transient; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.annotate.JsonMethod; import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; @MappedSuperclass public abstract class GenericModel<T extends GenericModel> { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; public long getId() {return id;} public void setId(long id) {this.id = id;} public GenericModel() { } // a toString method that can be used in any class. // uses reflection to dynamically print java class field // values one line at a time. @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); } public String toJson() { ObjectMapper jsonMapper = new ObjectMapper(); try { return jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsString(this); } catch (JsonGenerationException e) { e.printStackTrace(); return null; } catch (JsonMappingException e) { e.printStackTrace(); return null; } catch (IOException e) { e.printStackTrace(); return null; } } //public GenericModel toObject(String jsonObject) { //Suggested by stackOverflowComunity at: //https://stackoverflow.com/questions/27532206/java-create-list-of-objects-from-json-string-with-jackson public  T toObject(String jsonObject) { ObjectMapper jsonMapper = new ObjectMapper(); try { //GenericModel t = jsonMapper.readValue(jsonObject, GenericModel.class); T t = (T) jsonMapper.readValue(jsonObject, GenericModel.class); //return t; return t; } catch (JsonGenerationException e) { e.printStackTrace(); return null; } catch (JsonMappingException e) { e.printStackTrace(); return null; } catch (IOException e) { e.printStackTrace(); return null; } } } 

扩展generics模型的通用层次类:

 package com.derp.generic.model; import java.io.IOException; import java.util.LinkedList; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.FetchType; import javax.persistence.ManyToOne; import javax.persistence.MappedSuperclass; import javax.persistence.OneToMany; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; @MappedSuperclass public abstract class GenericHierarchicalModel<T extends GenericHierarchicalModel> extends GenericModel { private String name; @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) private T parent; @OneToMany(mappedBy = "parent") private List children; public String getName() {return name;} public void setName(String name) {this.name = name;} public T getParent() {return parent;} public void setParent(T parent) {this.parent = parent;} public List getChildren() {return children;} public void setChildren(List children) {this.children = children;} public GenericHierarchicalModel() { super(); } @Override public String toJson() { return "{\"title\":\"" + this.name + "\", \"id\":\"" + this.getId() + "\", \"children\": [" + listToJson(this.getChildren()) + "]}"; } public String listToJson(List children) { String json = ""; for(int i=0; i<children.size(); i++) { json = json + children.get(i).toJson(); if(children.size()!=i+1) { json = json + ", "; } } return json; } // @Override // public GenericHierarchicalModel toObject(String jsonObject) { // int start = 0; // '(' position in string // int end = 0; // ')' position in string // for(int i = 0; i < jsonObject.length(); i++) { // if(jsonObject.charAt(i) == '{') // Looking for '{' position in string // start = i; // else if(jsonObject.charAt(i) == '}') // Looking for '}' position in string // end = i; // } // String number = jsonObject.substring(start+1, end); // you take value between start and end // System.out.println(number); // return null; // } } 

模型类,我想从json对象列表中反序列化:

 package com.derp.procedure.model; import java.io.IOException; import java.util.List; import javax.persistence.DiscriminatorColumn; import javax.persistence.Entity; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.Table; import javax.persistence.Transient; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import com.derp.generic.model.GenericHierarchicalModel; import com.derp.generic.model.GenericModel; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; @Entity @Table(name="procedure__SkeletonElement") @Inheritance(strategy=InheritanceType.JOINED) @DiscriminatorColumn(name="type") public abstract class SkeletonElement extends GenericHierarchicalModel { @Transient public String getDecriminatorValue() { return this.getClass().getSimpleName(); } @Override public String toJson() { return "{\"title\":\"" + this.getName() + "\", \"id\":\"" + this.getId() + "\", \"type\":\"" + this.getDecriminatorValue() + "\", \"children\": [" + listToJson(this.getChildren()) + "]}"; } public List toObject(String jsonObject) { Gson gson = new Gson(); // Or use new GsonBuilder().create(); //SkeletonElement[] target2 = gson.fromJson(jsonObject, SkeletonElement[].class); List target2 = gson.fromJson(jsonObject, new TypeToken<List>(){}.getType()); return target2; } public SkeletonElement() { super(); } } 

而包含我想要反序列化回java对象列表的对象集合的类:

 package com.derp.procedure.model; import java.util.LinkedList; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.ManyToMany; import javax.persistence.Table; import com.derp.generic.model.GenericDictionaryModel; @Entity @Table(name="procedure__Skeleton") public class Skeleton extends GenericDictionaryModel { @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) private List skeletonElements; public void setSkeletonElements(List skeletonElements) {this.skeletonElements = skeletonElements;} public List getSkeletonElements() {return skeletonElements;} public List getSkeletonParentsElements() { List skeletonParentsElements = new LinkedList(); for(int i=0; i<this.skeletonElements.size(); i++) { if(this.skeletonElements.get(i).getParent()==null) { skeletonParentsElements.add(this.getSkeletonElements().get(i)); } } return skeletonParentsElements; } public Skeleton(String name) { super(name); } public Skeleton() { // TODO Auto-generated constructor stub } public String getSkeletonElementsJsonTree() { String jsonTreeString ="["; List skeletonParentsElements = getSkeletonParentsElements(); for(int i=0; i<skeletonParentsElements.size(); i++) { jsonTreeString = jsonTreeString + skeletonParentsElements.get(i).toJson(); if((1+i) != skeletonParentsElements.size()) { jsonTreeString = jsonTreeString + ","; } } return jsonTreeString + "]"; } public void setSkeletonElements(String skeletonElementsJson) { this.skeletonElements.get(0).toObject(skeletonElementsJson); } } 

至少我的JSON字符串,我不会反序列化:

 [ { "name": "Title1", "id": "1", "type": "SkeletonJobElement", "parent_id": "null", "children": [ { "name": "Title11", "id": "2", "type": "SkeletonJobElement", "parent_id": "1", "children": [ { "name": "Title111", "id": "5", "type": "SkeletonFileElement", "parent_id": "2", "children": [] }, { "name": "Title112", "id": "6", "type": "SkeletonFileElement", "parent_id": "2", "children": [] } ] } ] }, { "name": "Title2", "id": "3", "type": "SkeletonJobElement", "parent_id": "null", "children": [ { "name": "Title21", "id": "4", "type": "SkeletonJobElement", "parent_id": "3", "children": [] } ] } ] 

我知道这是很多代码来分析,但请帮我弄明白。 我为这个星期奋斗了这么久。

com.derp.procedure.model.SkeletonElement是一个抽象类。 使这个类具体删除抽象修饰符。

如果你使用Kotlin,也从abstract类转换为open类,将解决问题。