2014-11-23 12 views
9

Sto provando a implementare una piccola API REST utilizzando Jersey come framework, in linea di principio il codice ha funzionato bene ma quando provo a fare un 'GET' di un hash tavolo, ottengo il seguente errore:Errore Jersey: MessageBodyReader non trovato per tipo di supporto = application/jap

nov 23, 2014 4:27:40 PM org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor aroundReadFrom 
GRAVE: MessageBodyReader not found for media type=application/json, type=interface java.util.Map, genericType=java.util.Map<upf.dad.proyecto.New, upf.dad.proyecto.Term>. 
1440 [DefaultQuartzScheduler_Worker-3] ERROR org.quartz.core.JobRunShell - Job DEFAULT.testJob3 threw an unhandled Exception: 
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=interface java.util.Map, genericType=java.util.Map<upf.dad.proyecto.New, upf.dad.proyecto.Term>. 
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:230) 
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:154) 
    at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124) 
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:851) 
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:810) 
) 
    at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:313) 
    at upf.dad.proyecto.HotTopicDetector.News(HotTopicDetector.java:110) 
    at upf.dad.proyecto.ScheduledTestJob3.execute(ScheduledTestJob3.java:11) 
1440 [DefaultQuartzScheduler_Worker-3] ERROR org.quartz.core.ErrorLogger - Job (DEFAULT.testJob3 threw an exception. 
org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=interface java.util.Map, genericType=java.util.Map<upf.dad.proyecto.New, upf.dad.proyecto.Term>.] 
    at org.quartz.core.JobRunShell.run(JobRunShell.java:213) 
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) 
Caused by: org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=interface java.util.Map, genericType=java.util.Map<upf.dad.proyecto.New, upf.dad.proyecto.Term>. 
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:230) 
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:154) 
    at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124) 
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:851) 
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:810) 
    at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:368) 
    at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:846) 
    at org.glassfish.jersey.client.JerseyInvocation.access$600(JerseyInvocation.java:91) 
    at org.glassfish.jersey.client.JerseyInvocation$3.call(JerseyInvocation.java:705) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297) 
    at org.glassfish.jersey.internal.Errors.process(Errors.java:228) 
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:424) 
    at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:701) 
    at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:417) 
    at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:313) 
    at upf.dad.proyecto.HotTopicDetector.News(HotTopicDetector.java:110) 
    at upf.dad.proyecto.ScheduledTestJob3.execute(ScheduledTestJob3.java:11) 
    at org.quartz.core.JobRunShell.run(JobRunShell.java:202) 
    ... 1 more 

questa è la linea problematica:

Client client = ClientBuilder.newClient(); 

    WebTarget targetGetAllNews = client.target("http://localhost:15000").path("news/getAllNews"); 


    Map<New, Term> NewsAll = targetGetAllNews.request(
      MediaType.APPLICATION_JSON_TYPE).get(new GenericType<Map<New, Term>>(){}); 

e questo è come ho implementato il servizio:

@GET 
@Path("/getAllNews") 
@Produces(MediaType.APPLICATION_JSON) 
public Map<New, Term> getAllNews() { 
    return NewsCrawler.getNewAndTerm(); 
} 

pom.xml (dipendenze) Maven configurazione lato

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
<modelVersion>4.0.0</modelVersion> 
<groupId>upf.dad.proyecto</groupId> 
<artifactId>JAXRS-proyecto</artifactId> 
<version>0.0.1-SNAPSHOT</version> 
<dependencies> 
<!-- Rome RSS and Atom utilities @ http://rometools.github.io/rome/ -->   
<dependency> 
     <groupId>rome</groupId> 
     <artifactId>rome</artifactId>    
     <version>1.0</version> 
</dependency> 

<!-- jsoup HTML parser library @ http://jsoup.org/ -->   
<dependency>    
     <groupId>org.jsoup</groupId>    
     <artifactId>jsoup</artifactId>    
     <version>1.8.1</version>    
</dependency> 
    <dependency> 
     <groupId>org.quartz-scheduler</groupId> 
     <artifactId>quartz</artifactId> 
     <version>2.2.1</version> 
    </dependency> 
    <dependency> 
     <groupId>org.slf4j</groupId> 
     <artifactId>slf4j-simple</artifactId> 
     <version>1.6.1</version> 
    </dependency> 
    <dependency> 
     <groupId>org.twitter4j</groupId> 
     <artifactId>twitter4j-core</artifactId> 
     <version>4.0.2</version> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.containers</groupId> 
     <artifactId>jersey-container-servlet</artifactId> 
     <version>2.12</version> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.containers</groupId> 
     <artifactId>jersey-container-jdk-http</artifactId> 
     <version>2.12</version> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.media</groupId> 
     <artifactId>jersey-media-moxy</artifactId> 
     <version>2.12</version> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.core</groupId> 
     <artifactId>jersey-client</artifactId> 
     <version>2.12</version> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.media</groupId> 
     <artifactId>jersey-media-json-jackson</artifactId> 
     <version>2.13</version> 
    </dependency> 
</dependencies> 
</project> 

Server:

public class NewsCrawlerRestServer { 

public static void main(String[] args) throws IOException { 

    URI baseUri = UriBuilder.fromUri("http://localhost/").port(15000).build(); 
    ResourceConfig config = new ResourceConfig(NewsCrawlerServices.class, HotTopicDetectorServices.class); 
    config.register(JacksonFeature.class); 
    HttpServer server = JdkHttpServerFactory.createHttpServer(baseUri, config); 
    System.out.println("Server started..."); 

    } 
} 

Errore durante la registrazione di Jackson nel client:

org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: javax.ws.rs.ProcessingException: Error reading entity from input stream.] 
     at org.quartz.core.JobRunShell.run(JobRunShell.java:213) 
     at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) 
    Caused by: javax.ws.rs.ProcessingException: Error reading entity from input stream. 
     at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:866) 
     at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:810) 
     at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:368) 
     at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:846) 
     at org.glassfish.jersey.client.JerseyInvocation.access$600(JerseyInvocation.java:91) 
     at org.glassfish.jersey.client.JerseyInvocation$3.call(JerseyInvocation.java:705) 
     at org.glassfish.jersey.internal.Errors.process(Errors.java:315) 
     at org.glassfish.jersey.internal.Errors.process(Errors.java:297) 
     at org.glassfish.jersey.internal.Errors.process(Errors.java:228) 
     at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:424) 
     at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:701) 
     at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:417) 
     at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:313) 
     at upf.dad.proyecto.HotTopicDetector.News(HotTopicDetector.java:112) 
     at upf.dad.proyecto.ScheduledTestJob3.execute(ScheduledTestJob3.java:11) 
     at org.quartz.core.JobRunShell.run(JobRunShell.java:202) 
     ... 1 more 
    Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class upf.dad.proyecto.New] 
     at com.fasterxml.jackson.databind.deser.DeserializerCache._handleUnknownKeyDeserializer(DeserializerCache.java:580) 
     at com.fasterxml.jackson.databind.deser.DeserializerCache.findKeyDeserializer(DeserializerCache.java:170) 
     at com.fasterxml.jackson.databind.DeserializationContext.findKeyDeserializer(DeserializationContext.java:404) 
     at com.fasterxml.jackson.databind.deser.std.MapDeserializer.createContextual(MapDeserializer.java:232) 
     at com.fasterxml.jackson.databind.DeserializationContext.handleSecondaryContextualization(DeserializationContext.java:572) 
     at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:386) 
     at com.fasterxml.jackson.databind.ObjectReader._findRootDeserializer(ObjectReader.java:1380) 
     at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1228) 
     at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:677) 
     at com.fasterxml.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:777) 
     at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:264) 
     at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:234) 
     at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:154) 
     at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124) 
     at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:851) 

Nuova Classe:

package upf.dad.proyecto; 

import java.util.Date; 

public class New { 

private String tittle; 
private String description; 
private Date date; 
private String link; 

public New(){ 

} 

public New(String t, String d, Date date, String l){ 
    this.tittle = t; 
    this.description = d; 
    this.date = date; 
    this.link = l; 
} 

public String getTittle() { 
    return tittle; 
} 

public void setTittle(String tittle) { 
    this.tittle = tittle; 
} 

public String getDescription() { 
    return description; 
} 

public void setDescription(String description) { 
    this.description = description; 
} 

public Date getDate() { 
    return date; 
} 

public void setDate(Date date) { 
    this.date = date; 
} 

public String getLink() { 
    return link; 
} 

public void setLink(String link) { 
    this.link = link; 
} 

@Override 
public String toString() { 
    return "New [tittle=" + tittle + ", description=" + description 
      + ", date=" + date + ", link=" + link + "]"; 
} 


} 

Term:

package upf.dad.proyecto; 

public class Term { 

private String word; 

public Term(){ 

} 

public Term(String word){ 
    this.word = word; 

} 

public String getWord(){ 
    return word; 
} 

public void setWord(String _word){ 
    word = _word; 
} 

@Override 
public String toString() { 
    return "Termino =" + word + "]"; 
} 
} 

qualcuno può aiutarmi per favore a restituire la mappa?

+0

So che questo è un problema lato client, ma puoi mostrare la configurazione dell'applicazione server –

risposta

6

Vedo che ci sono due diverse dipendenze fornitore jersey-media-moxy e jersey-media-json-jackson. Ho sempre avuto un problema con Maps con MOXy. Immagino che non giochino bene. Sembra che sarà necessario utilizzare un adattatore per renderlo piacevole, come visto here from Blaise Doughan.

Detto questo, ho richiesto (nei commenti sopra) di vedere la configurazione lato server, dato che MOXy si autoconfigurerà e avrà la precedenza su jersey-media-json-jackson. Perché, non ne sono sicuro, è proprio quello che ho sempre vissuto. Quindi sono curioso di come il lato server non ha fallito prima ancora che la risposta tornasse al client. A meno che non si configura il JacksonFeature con l'applicazione server, in cui si dovrebbe averlo configurato anche con il client. (Questo è solo il caso, perché hai anche la dipendenza MOXy).

In ogni caso, se non si desidera passare attraverso gli adattatori di creazione dei problemi, come si vede nel link sopra, basta sbarazzarsi della dipendenza jersey-media-moxy. jersey-media-json-jackson lo configurerà automaticamente. Dovresti semplicemente usare l'uno o l'altro.


Per inciso:

@Path("/getAllNews"). I segmenti del percorso dovrebbero essere nomi, a meno che non si tratti di risorse del controller, che normalmente eseguono alcune azioni, diverse dalle normali operazioni CRUD (ad esempio /register). Il metodo HTTP è già costituito dal verbo a cui deve essere eseguita ogni azione CRUD.

  • C Reate - POST
  • R etriecve - GET
  • U pdate = PUT
  • D elete - DELETE

Solo alcuni semantica da considerare :-)


UPDATE

Il problema è con la chiave New. Jackson non sa come deserializzare questo. Dato che sei disposto a cambiare la chiave e il tipo di valore, basta cambiare il toString restituire il name nella classe Term e dovrebbe essere ok.

+0

Grazie per la tua risposta, ho aggiornato il post con le informazioni richieste. Come puoi vedere, per restituire la mappa io uso Jackson come provider JSON aggiungendo la dipendenza al file pom.xml e registrandolo nell'oggetto ResourceConfig prima di avviare HttpServer ma ancora non funziona ... – Gera

+0

Prova a registrarlo con il client inoltre, poiché il problema è sul lato client (poiché il problema è con il client), ad esempio 'client.register (...)'. Dato che hai ancora MOXy, il client potrebbe essere implicitamente registrato con MOXy. –

+0

grazie per l'aiuto, ancora una volta ho aggiornato il post con l'errore che ottengo quando registro il client ... ho pensato di usare anche l'adattatore, ma non so come implementarlo. – Gera

Problemi correlati