Je teste des services RESTful et, lorsque j'exécute, j'obtiens des exceptions bien que les jars suivants se trouvent dans mon chemin de classe (WEB-INF/lib), je n'utilise pas Maven et la version de JDK est 1.5. D'autres questions concernant ce problème n'ont pas aidé à résoudre le problème.
Extrait de code
@GET
@Produces("application/json")
//@Produces({MediaType.APPLICATION_JSON}) tried this, didn't work either
public List<Emp> getEmployees() {
List<Emp> empList = myDAO.getAllEmployees();
log.info("size " + empList.size());
return empList;
}
@XmlRootElement
public class Emp {
......
web.xml
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>com.Sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.Sun.jersey.config.property.packages</param-name>
<param-value>test.employees</param-value>
</init-param>
<init-param>
<param-name>com.Sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Liste des pots
jersey-server-1.2.jar
jersey-core-1.2.jar
jsr311-api-1.1.jar
asm-3.1.jar
jaxb-api-2.0.jar
jaxb-impl-2.0.jar
jackson-xc-1.2.0.jar
jackson-jaxrs-1.2.0.jar
jackson-mapper-asl-1.2.0.jar
jackson-core-asl-1.2.0.jar
jettison-1.2.jar
jersey-client-1.2.jar
jersey-servlet-1.10.jar
jersey-json-1.8.jar
Pile d'exception
SEVERE: A message body writer for Java class Java.util.ArrayList,
and Java type Java.util.List<test.Emp>,
and MIME media type application/json was not found
Nov 21, 2013 11:47:26 AM com.Sun.jersey.spi.container.ContainerResponse traceException
SEVERE: Mapped exception to response: 500 (Internal Server Error)
javax.ws.rs.WebApplicationException
at javax.ws.rs.WebApplicationException.<init>(WebApplicationException.Java:97)
at javax.ws.rs.WebApplicationException.<init>(WebApplicationException.Java:55)
at com.Sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.Java:267)
at com.Sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.Java:1035)
at com.Sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.Java:947)
at com.Sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.Java:939)
at com.Sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.Java:399)
at com.Sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.Java:478)
at com.Sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.Java:663)
at javax.servlet.http.HttpServlet.service(HttpServlet.Java:856)
at com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.Java:719)
at com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.Java:376)
at com.evermind.server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.Java:870)
at com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.Java:451)
at com.evermind.server.http.HttpRequestHandler.serveOneRequest(HttpRequestHandler.Java:218)
at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.Java:119)
at com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler.Java:112)
at Oracle.oc4j.network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.Java:260)
at Oracle.oc4j.network.ServerSocketAcceptHandler.procClientSocket(ServerSocketAcceptHandler.Java:230)
at Oracle.oc4j.network.ServerSocketAcceptHandler.access$800(ServerSocketAcceptHandler.Java:33)
at Oracle.oc4j.network.ServerSocketAcceptHandler$AcceptHandlerHorse.run(ServerSocketAcceptHandler.Java:831)
at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.Java:303)
at Java.lang.Thread.run(Thread.Java:595)
Comment puis-je résoudre ce problème?
Assurez-vous de ne pas avoir plusieurs versions de Jersey dans votre projet. Dans la liste que vous avez fournie, il y a des modules de 3 versions différentes (1.2, 1.10, 1.8). Pour certains modules, Jersey vérifie que la version d'un module est la même que la version du noyau. Si ce n'est pas le cas, les fournisseurs du module (tels que MessageBodyReaders, MessageBodyWriters) ne sont pas enregistrés dans le runtime. Cela peut être un problème dans votre configuration - json vs core (1.8 vs 1.2).
Le problème peut être de savoir comment vous essayez de renvoyer votre résultat. J'ai vu d'autres personnes écrire leur code de couche de service de cette façon également, mais Jersey offre un moyen de le faire proprement et prend en charge les sorties JSON, XML et HTML que vous devez uniquement spécifier à l'aide de votre annotation @Produces . C'est ce que je fais:
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.Response;
@GET
@Produces( MediaType.APPLICATION_JSON )
public Response getEmployees()
{
List< Emp > matched;
GenericEntity< List< Emp > > entity;
matched = myDAO.getAllEmployees();
entity = new GenericEntity< List< Emp > >( matched ) { };
return Response.ok( entity ).build();
}
J'utilise les bibliothèques Jersey suivantes:
Vous ne pouvez pas définir la réponse Xml
comme List<Emp>
, car la JAXB
est incapable d'identifier le @XmlRootElement
par rapport à la définition de classe Java.util.List
ou Java.util.ArrayList
.
Idéalement, vous devriez avoir un élément parent/racine pour votre collection d'éléments enfants.
Créez une classe supplémentaire en tant que Employees
to contient la collection d'objets Emp
comme ci-dessous et essayez-la.
@GET
@Produces("application/json")
public Employees getEmployees() {
List<Emp> empList = myDAO.getAllEmployees();
log.info("size " + empList.size());
Employees employees = new Employees();
employees.setEmployeeList(empList);
return employees;
}
@XmlRootElement(name = "Employees")
public class Employees {
List<Emp> employeeList;
//setters and getters goes here
}
@XmlRootElement()
class Emp {
//fields here
}
S'il vous plaît essayez cette approche, cela fonctionnera.
Ajoutez ceci à votre pom.xml. Résolu mon problème.
<dependency>
<groupId>com.Sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.owlike</groupId>
<artifactId>genson</artifactId>
<version>0.99</version>
</dependency>
Spécifiez @XmlRootElement(name = "yourclass")
sur la classe que vous voulez transmettre en sortie. Cela a résolu le problème pour moi lorsque je reçois cette exception.
Vous devez déclarer dans le servlet container
du maillot le param comme suit:
'com.Sun.jersey.api.json.POJOMappingFeature' like this:
<servlet>
<servlet-name>myServices</servlet-name>
<servlet-class>com.Sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.Sun.jersey.config.property.packages</param-name>
<param-value>services</param-value>
</init-param>
<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>
J'ai eu le même problème.
Le problème est qu’il sait comment le convertir au format xml avec l’indication @XmlRootElement
mais il ne sait pas comment le convertir au format JSON.
Donc, pour que tout soit converti en JSON avec la même annotation XML (c'est-à-dire @XmlRootElement
), nous pouvons ajouter
jersey-media-moxy-<whatever version>.jar
ou pour les utilisateurs maven
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
Il devrait également avoir un constructeur sans argument
vérifiez que votre classe de pojo ne soit pas terminée JAXBinding si non fait, marquez votre pojo avec @XmlRootElement