wake-up-neo.com

Ein Body-Writer für Nachrichten für die Java-Klasse Java.util.ArrayList ... und den MIME-Medientyp text/xml wurde nicht gefunden

Ich verwende Jersey, um einen REST - Dienst zu erstellen, und möchte einen Collection<String> als XML zurückgeben.

@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());
    }
}

meine Versuche schlagen jedoch mit folgender Ausnahme fehl:

javax.ws.rs.WebApplicationException: com.Sun.jersey.api.MessageException: Ein Body-Writer für Nachrichten für die Java-Klasse Java.util.ArrayList und die Java-Typenklasse Java.util.ArrayList und der MIM-Medientyp text/xml nicht gefunden 

und alle Ergebnisse zu dieser Ausnahme, die ich über Google fand, befassten sich mit der Rückgabe von Text/Json anstelle von Text/XML, wie in meiner Situation.

Kann mir jemand helfen? Ich dachte, wenn ich eine Antwort verwende, wäre dies mein Stammelement in XML und meine Sammlung eine Liste von Zeichenfolgeelementen darin.

15
lrxw

HINWEIS: Obwohl diese Antwort funktioniert, ist anars Antwort besser.

Sie sollten versuchen, eine mit JAXB kommentierte Klasse zu verwenden, um Ihr Problem zu lösen. Sie könnten Ihre Methode dazu ändern:

@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());
    }
}

Erstellen Sie anschließend eine mit JAXB kommentierte Klasse für Ihre Gruppen. Ich habe eine generierte Klasse für Sie eingefügt, indem Sie den in diese Antwort beschriebenen Prozess verwenden. Hier ist ein Beispiel der Dokumente, die erstellt werden sollen:

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

Und hier ist die generierte Klasse:

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;
    }

}
11

Benutzen

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

Der generische Entity-Wrapper dient zum Abrufen der Ausgabe, wenn der Builder für Antworten verwendet wird.

Referenz

43
anar

hinzufügen von @XmlRootElement (name = "Klassenname") zu dem Objekt, das ich zurückgeben möchte, hat mein Problem behoben

0
user3145787

Das einzige, was bisher für mich funktioniert hat, ist mein eigenes Wrapper-Objekt zu erstellen.

Vergessen Sie nicht die Annotation@XmlRootElement, um JAXB zu erklären, wie es zu analysieren ist.

Beachten Sie, dass dies für jeden Objekttyp funktioniert - in diesem Beispiel habe ich ArrayList of String verwendet.

z.B.

Das Wrapper-Objekt sollte folgendermaßen aussehen:

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

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

Und die Methode REST sollte folgendermaßen aussehen:

@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());
    }
}
0
Naor Bar