JAX WS RS en utilisant Jersey - retour collection, carte etc

Je suis en utilisant Jersey 2.3

Mon WS point de terminaison de la classe :

@Path("/employees")
public class EmployeeWSEndpoint {

    @Context
    Request request;

    @GET
    @Path("/allEmployees")
    @Produces(MediaType.APPLICATION_JSON)
    public List<Employee> getAllEmployees() {

        System.out.println("In EmployeeWSEndpoint.getAllEmployees()");

        EmployeeService employeeService = new EmployeeServiceImpl();
        return employeeService.getAllEmployees();
    }

    @GET
    @Path("/allDept")
    @Produces(MediaType.APPLICATION_JSON)
    public List<String> getAllDept() {

        System.out.println("In EmployeeWSEndpoint.getAllDept()");

        List<String> deptNames = new ArrayList<>();
        deptNames.add("CoE");
        deptNames.add("iLabs");

        return deptNames;
    }

    @GET
    @Path("/allDeptPOJO")
    @Produces(MediaType.APPLICATION_JSON)
    public TempPOJO getAllDeptPOJO() {

        System.out.println("In EmployeeWSEndpoint.getAllDeptPOJO");

        TempPOJO tempPOJO = new TempPOJO();

        return tempPOJO;
    }
}

Employé POJO :

public class Employee {

    private int id;
    private String firstName;
    private String middleName;
    private String lastName;
    private Date dob;
    private int deptId;

    public Employee() {

    }

    public Employee(String firstName, String middleName, String lastName,
            Date dob, int deptId) {
        this.firstName = firstName;
        this.middleName = middleName;
        this.lastName = lastName;
        this.dob = dob;
        this.deptId = deptId;
    }

    public Employee(int id, String firstName, String middleName,
            String lastName, Date dob, int deptId) {
        this.id = id;
        this.firstName = firstName;
        this.middleName = middleName;
        this.lastName = lastName;
        this.dob = dob;
        this.deptId = deptId;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getMiddleName() {
        return middleName;
    }

    public void setMiddleName(String middleName) {
        this.middleName = middleName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Date getDob() {
        return dob;
    }

    public void setDob(Date dob) {
        this.dob = dob;
    }

    public int getDeptId() {
        return deptId;
    }

    public void setDeptId(int deptId) {
        this.deptId = deptId;
    }

    @Override
    public String toString() {
        return firstName + " " + middleName + " " + " " + lastName;
    }
}

Temporaire POJO :

public class TempPOJO {

    private List<String> deptNames;

    public List<String> getDeptNames() {

        deptNames = new ArrayList<>();
        deptNames.add("CoE");
        deptNames.add("iLabs");

        return deptNames;
    }

    public void setDeptNames(List<String> deptNames) {
        this.deptNames = deptNames;
    }

}

Liste les sortie(s) pour les différentes méthodes :

allEmployees

[{"deptId":1,"dob":"1978-06-19","firstName":"Garfield","id":0,"lastName":"Arbuckle","middleName":"John"},{"deptId":1,"dob":"1946-07-07","firstName":"John","id":0,"lastName":"Rambo","middleName":"R"}]

/allDept

In EmployeeWSEndpoint.getAllDept()
Oct 01, 2013 3:31:08 PM org.glassfish.jersey.server.ServerRuntime$Responder mapException
WARNING: WebApplicationException cause:
javax.xml.bind.MarshalException
 - with linked exception:
[Exception [EclipseLink-25003] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: An error occurred marshalling the object
Internal Exception: Exception [EclipseLink-25007] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor for class java.lang.String was not found in the project.  For JAXB, if the JAXBContext was bootstrapped using TypeMappingInfo[] you must call a marshal method that accepts TypeMappingInfo as an input parameter.]
    at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:403)
    at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.writeTo(MOXyJsonProvider.java:808)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:243)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:230)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:149)
    at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:103)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:149)
    at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:88)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:149)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1139)
    at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:562)
    at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:357)
    at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:347)
    at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:258)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    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:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:318)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:235)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:983)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:359)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    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:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: Exception [EclipseLink-25003] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: An error occurred marshalling the object
Internal Exception: Exception [EclipseLink-25007] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor for class java.lang.String was not found in the project.  For JAXB, if the JAXBContext was bootstrapped using TypeMappingInfo[] you must call a marshal method that accepts TypeMappingInfo as an input parameter.
    at org.eclipse.persistence.exceptions.XMLMarshalException.marshalException(XMLMarshalException.java:97)
    at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:911)
    at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:848)
    at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:401)
    ... 41 more
Caused by: Exception [EclipseLink-25007] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor for class java.lang.String was not found in the project.  For JAXB, if the JAXBContext was bootstrapped using TypeMappingInfo[] you must call a marshal method that accepts TypeMappingInfo as an input parameter.
    at org.eclipse.persistence.exceptions.XMLMarshalException.descriptorNotFoundInProject(XMLMarshalException.java:139)
    at org.eclipse.persistence.internal.oxm.Context$ContextState.getSession(Context.java:143)
    at org.eclipse.persistence.oxm.XMLContext$XMLContextState.getSession(XMLContext.java:787)
    at org.eclipse.persistence.oxm.XMLContext$XMLContextState.getSession(XMLContext.java:1)
    at org.eclipse.persistence.internal.oxm.Context.getSession(Context.java:451)
    at org.eclipse.persistence.oxm.XMLContext.getSession(XMLContext.java:356)
    at org.eclipse.persistence.oxm.XMLContext.getSession(XMLContext.java:1)
    at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:568)
    at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:1096)
    at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:869)
    ... 43 more

/allDeptPOJO

{"deptNames":["CoE","iLabs"]}

J'ai quelques requêtes :

  1. Je suppose que depuis Jersey 2.3, annotation 'XmlRootElement" n'est pas nécessaire pour Pojo - je ne l'ai pas fait, pourtant, les appels de travail. S'il vous plaît confirmer
  2. Dans le cas d'une Liste d'un pojo(Employé) ou d'un pojo avoir une Liste, la réponse est bonne mais pour la Liste, Carte, etc. il échoue(en gros, pour les types Java) - pourquoi est-ce donc? Si cela fonctionne pour les Employés, pourquoi ne pas travailler pour les types Java? Est-il nécessaire d'écrire un XmlAdapter?

Note : je veux la réponse en JSON dans la plupart des cas.

La modification de la web.xml pour utiliser Jackson :

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>Jersey</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>Jersey REST Service</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>com.ws.jaxrs.jersey</param-value>
        </init-param>
        <init-param>
            <param-name>jersey.config.disableMoxyJson.server</param-name>
            <param-value>true</param-value>
        </init-param>

        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>com.ws.jaxrs.jersey;org.codehaus.jackson.jaxrs</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Jersey REST Service</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>


</web-app>

Je suis l'exception suivante :

In EmployeeWSEndpoint.getAllDept()
Nov 07, 2013 10:04:12 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [Jersey REST Service] in context with path [/Jersey] threw exception [org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=application/json, type=class java.util.ArrayList, genericType=java.util.List<java.lang.String>.] with root cause
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=application/json, type=class java.util.ArrayList, genericType=java.util.List<java.lang.String>.
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:227)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:149)
    at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:103)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:149)
    at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:88)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:149)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1139)
    at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:562)
    at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:357)
    at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:347)
    at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:258)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    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:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:318)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:235)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:983)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:359)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

source d'informationauteur Kaliyug Antagonist | 2013-10-01