2013-03-25 14 views
13

Im przy użyciu usługi Jersey do zbudowania usługi REST i chcesz zwrócić Collection<String> jako XML.Nagrywarka treści wiadomości dla klasy Java java.util.ArrayList ... i MIME Media tekst/xml nie został znaleziony

@GET 
@Produces(MediaType.TEXT_XML) 
@Path("/directgroups") 
public Response getDirectGroupsForUser(@PathParam("userId") String userId) { 
    try { 
     Collection<String> result = service.getDirectGroupsForUser(userId, null, true); 

//  return result; //first try 
//  return result.toArray(new String[0]); //second try 
     return Response.ok().type(MediaType.TEXT_XML).entity(result).build(); //third try 
    } catch (UserServiceException e) { 
     LOGGER.error(e); 
     throw new RuntimeException(e.getMessage()); 
    } 
} 

ale moje próby nie powiodą się z następującym wyjątkiem:

javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: Pisarz treść wiadomości dla klasy Java java.util .ArrayList i typu Java klasa java.util.ArrayList i MIME typ mediów text/xml nie został znaleziony

i wszystkie wyniki do tego wyjątku znalazłem przez google czynienia z powracającym text/json zamiast text/xml jak w mojej sytuacji.

Czy ktoś może mi pomóc? Pomyślałem, że jeśli użyłbym odpowiedzi, byłby to mój element główny w XML i mojej kolekcji lista elementów łańcuchowych w nim ..

Odpowiedz

11

UWAGA: Chociaż ta odpowiedź działa, anar's answer jest lepsza.

Powinieneś spróbować użyć klasy adnotowanej JAXB, aby rozwiązać problem. Możesz zmienić swoją metodę na:

@GET 
@Produces(MediaType.TEXT_XML) 
@Path("/directgroups") 
public Groups getDirectGroupsForUser(@PathParam("userId") String userId) { 
    try { 

     Groups groups = new Groups(); 
     groups.getGroup().addAll(service.getDirectGroupsForUser(userId, null, true)); 
     return groups; 
    } catch (UserServiceException e) { 
     LOGGER.error(e); 
     throw new RuntimeException(e.getMessage()); 
    } 
} 

Następnie utwórz grupę adnotacji JAXB dla grup. Zawarłem dla ciebie wygenerowaną klasę, używając procesu opisanego w this answer. Oto przykład z dokumentów, które będzie produkować:

<groups> 
    <group>Group1</group> 
    </group>Group2</group> 
</groups> 

I tu jest generowany klasa:

package example; 

import java.util.ArrayList; 
import java.util.List; 
import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlType; 


/** 
* <p>Java class for anonymous complex type. 
* 
* <p>The following schema fragment specifies the expected content contained within this class. 
* 
* <pre> 
* &lt;complexType> 
* &lt;complexContent> 
*  &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> 
*  &lt;sequence> 
*   &lt;element ref="{}group" maxOccurs="unbounded"/> 
*  &lt;/sequence> 
*  &lt;/restriction> 
* &lt;/complexContent> 
* &lt;/complexType> 
* </pre> 
* 
* 
*/ 
@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "", propOrder = { 
    "group" 
}) 
@XmlRootElement(name = "groups") 
public class Groups { 

    @XmlElement(required = true) 
    protected List<String> group; 

    /** 
    * Gets the value of the group property. 
    * 
    * <p> 
    * This accessor method returns a reference to the live list, 
    * not a snapshot. Therefore any modification you make to the 
    * returned list will be present inside the JAXB object. 
    * This is why there is not a <CODE>set</CODE> method for the group property. 
    * 
    * <p> 
    * For example, to add a new item, do as follows: 
    * <pre> 
    * getGroup().add(newItem); 
    * </pre> 
    * 
    * 
    * <p> 
    * Objects of the following type(s) are allowed in the list 
    * {@link String } 
    * 
    * 
    */ 
    public List<String> getGroup() { 
     if (group == null) { 
      group = new ArrayList<String>(); 
     } 
     return this.group; 
    } 

} 
+0

Czy nie ma innego sposobu? Myślałem, że Response wykona zadanie za to, co utworzyłeś grupy klasowe.-> udostępnia kontener dla listy akt jako element główny – lrxw

+0

Co najmniej coś musi przekazać Jersey nazwę głównego elementu XML. Wygląda na to, że możesz użyć [opakowania ogólnego i JAXB] (http://stackoverflow.com/a/1603484/1818625) lub [biblioteki XStream] (http://stackoverflow.com/a/8427694/1818625). –

+0

http://stackoverflow.com/questions/17342218/getting-error-a-message-body-writer-for-java-class-java-util-arraylist-listjava ..możesz rozwiązać to? – user2416728

40

Zastosowanie

List<String> list = new ArrayList<String>(); 
GenericEntity<List<String>> entity = new GenericEntity<List<String>>(list) {}; 
Response response = Response.ok(entity).build(); 

Generic jednostka owijarka pracuje, aby uzyskać wyjście podczas korzystania z Kreatora odpowiedzi.

Reference

+0

Pracował świetnie dla LinkedList - dziękuję! – remrick

+0

Niestety, link, do którego się tutaj odwołujesz, jest już martwy, ale byłby naprawdę pomocny – Toadfish

+1

http://docs.oracle.com/javaee/6/api/javax/ws/rs/core/GenericEntity.html – OhadR

0

Jedyną rzeczą, która pracowała dla mnie tak daleko, aby utworzyć własną obiektu opakowania.

Nie zapomnij @XmlRootElement adnotacji wyjaśnić JAXB jak go analizować.

Należy zauważyć, że działa to dla dowolnego typu obiektu - w tym przykładzie użyłem ArrayList of String.

np.

obiektu opakowania powinna wyglądać następująco:

import java.util.ArrayList; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class ArrayListWrapper { 
    public ArrayList<String> myArray = new ArrayList<String>(); 
} 

A metoda Reszta powinna wyglądać następująco:

@GET 
@Produces(MediaType.TEXT_XML) 
@Path("/directgroups") 
public ArrayListWrapper getDirectGroupsForUser(@PathParam("userId") String userId) { 
    try { 
     ArrayListWrapper w = new ArrayListWrapper(); 
     w.myArray = service.getDirectGroupsForUser(userId, null, true); 
     return w; 
    } catch (UserServiceException e) { 
     LOGGER.error(e); 
     throw new RuntimeException(e.getMessage()); 
    } 
} 
Powiązane problemy