2014-09-29 45 views
-1

在我的應用程序客戶端(REST服務),我嘗試解組「地區」的jyson名單列表,但我得到這個錯誤:錯誤,當我嘗試反序列化列表的形式jyson

org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of java.util.List out of START_OBJECT token 
at [Source: [email protected]; line: 1, column: 1] 
at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:160) 
at org.codehaus.jackson.map.deser.StdDeserializationContext.mappingException(StdDeserializationContext.java:198) 
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:103) 
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:93) 
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:25) 
at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2131) 
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1395) 
at ma.specificationWeb.client.RegionClient.getAllRegions(RegionClient.java:109) 
at ma.specificationWeb.web.RegionAction.index(RegionAction.java:18) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
at java.lang.reflect.Method.invoke(Unknown Source) 
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:450) 
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:289) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:252) 
at org.apache.struts2.interceptor.DeprecationInterceptor.intercept(DeprecationInterceptor.java:41) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:167) 
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265) 
at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68) 
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:254) 
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:254) 
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:252) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171) 
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:139) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:193) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189) 
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) 
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54) 
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:562) 
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77) 
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:409) 
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1044) 
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607) 
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
at java.lang.Thread.run(Unknown Source) 

有我的客戶端:

public List<Region> getAllRegions() { 
    ClientConfig config = new DefaultClientConfig(); 
    config.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, 
      Boolean.TRUE); 

    Client client = Client.create(config); 
    WebResource service = client.resource(REST_URI_REGIONS); 

    ClientResponse response = service.accept(MediaType.APPLICATION_JSON) 
      .get(ClientResponse.class); 
    if (response.getStatus() != 200) { 
     throw new RuntimeException("Failed : HTTP error code : " 
       + response.getStatus()); 
    } 
    String resultat = response.getEntity(String.class); 
    System.out.println(resultat); 
    ObjectMapper objectMapper = new ObjectMapper(); 
    List<Region> regions=null; 
    try { 
     regions = objectMapper.readValue(resultat,List.class); 
    } catch (JsonParseException e) { 
     e.printStackTrace(); 
    } catch (JsonMappingException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return regions; 
} 

而且還有我的豆地區:

@XmlRootElement 
@Entity 
@Table(name="T_REGION") 
@XmlType(propOrder = {"idRegion", "nomRegion"}) 
public class Region implements Serializable{ 
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private Long idRegion; 
@Column(name = "NOM_REGION", nullable = false, length = 30, unique = true) 
private String nomRegion; 
@OneToMany(fetch = FetchType.EAGER,mappedBy = "region", cascade = CascadeType.ALL) 
private List<Province> provinces = new ArrayList<Province>(); 
@OneToMany(fetch = FetchType.EAGER,mappedBy = "region") 
private List<ActualiteRegion> actualites = new ArrayList<ActualiteRegion>(); 

public Long getIdRegion() { 
    return idRegion; 
} 

public void setIdRegion(Long idRegion) { 
    this.idRegion = idRegion; 
} 

public String getNomRegion() { 
    return nomRegion; 
} 

public void setNomRegion(String nomRegion) { 
    this.nomRegion = nomRegion; 
} 

public Region(String nomRegion) { 

    this.nomRegion = nomRegion; 
} 

public Region() { 
} 
@XmlTransient 
public List<Province> getProvinces() { 
    return provinces; 
} 

public void setProvinces(List<Province> provinces) { 
    this.provinces = provinces; 
} 
@XmlTransient 
public List<ActualiteRegion> getActualites() { 
    return actualites; 
} 

public void setActualites(List<ActualiteRegion> actualites) { 
    this.actualites = actualites; 
} 

} 

有方法至極生成列表「地區」。

@GET 
@Produces(MediaType.APPLICATION_JSON) 
public List<Region> getAllRegions() { 
return dao.getAllRegions(); 
} 

當我收到客戶端的JSON列表中,我試圖打印爲控制檯的String,並有wath我:

{ 
"region": [ 
    {"idRegion":"4","nomRegion":"Oriental"}, 
    {"idRegion":"5","nomRegion":"Hoceima Taza Taounat"}, 
    {"idRegion":"6","nomRegion":"Rif"}, 
    {"idRegion":"7","nomRegion":"Rabat"} 
    ] 
} 

有配置,使json對象的自動編組和解組:

<display-name>hbo-go-services</display-name> 
<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
     classpath:applicationContext.xml   
    </param-value> 

</context-param> 

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

<servlet> 
    <servlet-name>servlet-jersey</servlet-name> 
    <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class> 
    <init-param> 
     <param-name>com.sun.jersey.config.property.packages</param-name> 
     <param-value>ma.noyauSolution.metier</param-value> 
    </init-param> 
<!--  intègre jersey avec jackson : --> 
<!-- allow to marshal a java object to a json file and to unmarshal a json file to java object --> 
    <init-param> 
     <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> 
     <param-value>true</param-value> 
    </init-param> 

    <load-on-startup>1</load-on-startup> 
</servlet> 
<servlet-mapping> 
    <servlet-name>servlet-jersey</servlet-name> 
    <url-pattern>/*</url-pattern> 
</servlet-mapping> 
<welcome-file-list> 
    <welcome-file>index.jsp</welcome-file> 
</welcome-file-list> 

</web-app> 

我希望somenone可以幫助我。

+0

你可以發佈你的應用程序上下文的配置和含'getAllRegions'您充分休息服務類?我跟着[這個例子](http://www.mkyong。com/webservices/jax-rs/json-example-jersey-jackson /),但是當我添加一個返回列表的附加服務時無法重現包裝。 – ultimate 2014-10-01 06:48:08

+0

必須有一些額外的配置,告訴傑克遜或JAXB使用[本文檔](https://jersey.java.net/documentation/1.18/json.html#d4e949) – ultimate 2014-10-01 06:53:45

+0

中顯示的根元素我已發佈方法將產生「地區」列表。 – 2014-10-02 23:20:49

回答

0

我保證發送到客戶端的json以「{」開始,它是異常堆棧跟蹤中提到的START_OBJECT標記... 但是反序列化List或Array(不是容器內的容器)需要一個「[」作爲開始標記。 所以,請檢查生成JSON的代碼,如果它產生的是這樣的:

[ 
    { /*attributes of region1*/ }, 
    { /* ... */ }, 
    ... 
] 

編輯:

產生的是代表有1個單屬性的對象的JSON字符串命名爲「區」包含期望的區域列表(List<Region>)。當試圖將這個外部對象反序列化爲一個List時,它會失敗,因爲json解析會期望一個start_array標記(「[」),但會接收一個start_object標記(「{」)。現在有關於如何correcty生產/解析字符串兩種選擇:

  1. 變化的JSON輸出到我上面提到的格式(你的結果的一部分,而不{「區域」:在開始的東西) 。不幸的是,我還沒有與@Produces合作過,我不知道從給定列表中最終生成json的確切位置 - 必須有一些包裝對象創建周圍的{ ... }。但仍有選項2

  2. 創建反序列化的包裝對象: 由於JSON預計的對象(沒有數組),你可以告訴傑克遜解析器使用包裝對象,而不是,例如反序列化定列表

    public class RegionWrapper 
    { 
        public List<Region> region; 
        /* 
        name and type are important here! 
        your json string names the list "region", not "regions" 
        */ 
    } 
    

    然後,而不是閱讀的結果List.class你可以寫

    RegionWrapper wrapper = objectMapper.readValue(resultat,RegionWrapper.class); 
    List<Region> regions = wrapper.region; 
    
+0

你認爲我應該編輯我的bean「Region」的註釋嗎? – 2014-09-29 17:29:40

+0

Region類對我來說看起來不錯。我認爲它是客戶端代碼中的一個錯誤。你可以發佈生成json和簡單消息之前的反序列化的代碼 – ultimate 2014-09-29 17:37:08

+0

在服務器端,有生成json列表的方法,這是一個簡單的@Produces(「應用程序/ json」)我將它發佈在一個新的回答 – 2014-09-29 17:51:07