5 Replies Latest reply on Apr 19, 2011 5:28 AM by moussa aladin

    Rest service + generic type List

    moussa aladin Newbie

      hello,

      i've a problem with returning List<Address> using rest service in Gatein, my Class Address is a PUJO, i have this error " Not found writer for class java.util.ArrayList and MIME type application/xml" 

       

       

      import javax.ws.rs.*;
      import org.exoplatform.services.rest.resource.ResourceContainer;  
      public class AddressBook implements ResourceContainer{ 
      @GET
          @Path("/list")
          @Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
          public List<Address>  getAdressList() {
              List<Address> addresses = new ArrayList<Address>();
              addresses.add(new Address("Shanghai", "Long Hua Street"));
              addresses.add(new Address("Shanghai", "Dong Quan Street"));
              //return contacts;
      
              return addresses;
              }
      }
      

       

      when i return a string that's work, i mean addresses.toString().

       

      and in web navigator i have this error : "

      HTTP ETAT 500

      javax.servlet.ServletException: javax.ws.rs.WebApplicationException

      org.exoplatform.services.rest.servlet.RestServlet.onService(RestServlet.java:100)

      org.exoplatform.container.web.AbstractHttpServlet.service(AbstractHttpServlet.java:116)

      javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

      org.exoplatform.services.rest.servlet.RestEncodingFilter.doFilter(RestEncodingFilter.java:58)

      org.exoplatform.frameworks.jcr.web.ThreadLocalSessionProviderInitializedFilter.doFilter(ThreadLocalSessionProviderInitializedFilter.java:116)

      org.exoplatform.services.security.web.SetCurrentIdentityFilter.doFilter(SetCurrentIdentityFilter.java:76)

      org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)

      in gateIn log erro

      " Not found writer for class java.util.ArrayList and MIME type application/xml" 

      i try this and i still have the same error message

       

        public Response getContactArray(){
              List<Address> addresses = new ArrayList<Address>();
              addresses.add(new Address("Shanghai", "Long Hua Street"));
              addresses.add(new Address("Shanghai", "Dong Quan Street"));
              GenericEntity entity = new GenericEntity<List<Address>>(addresses) {};
              return Response.ok(entity).build();
          }
      


      any help please

        • 1. Re: Rest service + generic type List
          Nick Scavelli Novice

          The framework has no way of knowing how to write your object to XML.  Please have a look at http://jsr311.java.net/nonav/releases/1.0/javax/ws/rs/ext/MessageBodyWriter.html to give you an idea.  Implement this interface and add it to the container.  You should end up with something like

           

           

          @Provider
          @Produces(MediaType.APPLICATION_XML)
          public class AddressBookMessageBodyWriter implements MessageBodyWriter {
          ....
          
          • 2. Re: Rest service + generic type List
            Nick Scavelli Novice

            Also I'm not sure if adding the above implementation of the MessageBodyWriter would actually register it propely.  I would recommend adding a java.ws.Application implementation to the container and following JAX-RS conventations on registering resources and providers.  This removes any dependencies on the actual rest implementation framework.

             

            For example:

             

             

            public class RestApplication extends Application {

             

               @Override

               public Set<Object> getSingletons()

               {

                  Set<Object> singletons = new HashSet<Object>();

                  singletons.add(new AddressBookMessageBodyWriter());

             

                  return singletons;

               }

             

               @Override

               public Set<Class<?>> getClasses()

               {

                  Set<Class<?>> classes = new HashSet<Class<?>>();

                  classes.add(AddressBook.class);

             

                  return classes;

               }

            }

            • 3. Rest service + generic type List
              moussa aladin Newbie

              hello, i try this but i still have the same problem

               

              javax.ws.rs.ext.Provider

              @javax.ws.rs.Produces("application/xml")

              public class AddressBookWriter implements MessageBodyWriter<ArrayList<Address>>

              {

               

                    public boolean isWriteable(Class<?> type,

                                               Type genericType,

                                               Annotation[] annotations,

                                               MediaType mt)

                    {

                      return Source.class.isAssignableFrom(type);

                    }

               

                    public void writeTo(ArrayList<Address> list,

                                        Class<?> clazz,

                                        Type genericType,

                                        Annotation[] annotations,

                                        MediaType mediatype,

                                        MultivaluedMap<String, Object> httpHeaders,

                                        OutputStream os)

                    throws IOException,WebApplicationException

                    {

                        GenericEntity<ArrayList<Address>> entity = new GenericEntity<ArrayList<Address>>(list) {};

                        Response response = Response.ok(entity).build();

               

                    }

               

                    public long getSize(ArrayList<Address> list,

                                        Class<?> type,

                                        Type genericType,

                                        Annotation[] annotations,

                                        MediaType mt)

                    {

                      return -1;

                    }

                  }

               

               

               

              with this

               

               

              import java.util.HashSet;

              import java.util.Set;

               

              public class MyApplicatio extends javax.ws.rs.core.Application {

                  public Set<Class<?>> getClasses() {

                      Set<Class<?>> classes = new HashSet<Class<?>>();

                      classes.add(AddressBookWriter.class);

                      return classes;

                  }

              }

               

               

               

              any help please

              • 4. Rest service + generic type List
                kien nguyen Newbie

                  You can use simple REST as example:

                   @GET

                   @Path("hello/{name}")

                   @Produces({MediaType.APPLICATION_XML})

                   public String hello(@PathParam("name") String name) {

                     return "<hello>" + name + "</hello>";

                   }

                 

                You need to build yourself XML String from List<Address>.

                Other solution, you can use a auto-mapping annotation such as javax.xml.bind.annotation.XmlRootElement to map class to XML.

                • 5. Rest service + generic type List
                  moussa aladin Newbie

                  hello,

                  i found the solution, indeed, we need a wrapper for collection so,  JSON-bean framework can serialize it to json like this:

                   

                  public class AdresseList {

                      private Collection<Address> address;

                   

                      public AdresseList() {

                      }

                   

                      public AdresseList(Collection<Address> address) {

                          this.address = address;

                      }

                   

                      public Collection<Address> getAddress() {

                          return address;

                      }

                   

                      public void setAddress(Collection<Address> address) {

                          this.address = address;

                      }

                   

                   

                  and

                   

                  public Response getContactArray(){

                          List<Address> addresses = new ArrayList<Address>();

                          addresses.add(new Address("Shanghai", "Long Hua Street"));

                          addresses.add(new Address("Shanghai", "Dong Quan Street"));

                          AdresseList listAd = new AdresseList(addresses);

                          return Response.ok(listAd, "application/json").cacheControl(cc).build();

                      }

                   

                   

                  i will make a complete example in the wiki, thanks for your help