2013-03-25 25 views
13

Im sử dụng Jersey để xây dựng một Dịch vụ REST và muốn trả lại một Collection<String> làm XML.Một trình soạn thảo nội dung thư cho lớp Java java.util.ArrayList ... và kiểu văn bản MIME text/xml không được tìm thấy

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

nhưng những nỗ lực của tôi thất bại với các ngoại lệ sau đây:

javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: Một nhà văn nội dung thư cho Java lớp java.util .ArrayList và lớp Java loại java.util.ArrayList và loại văn bản MIME text/xml không được tìm thấy

và tất cả kết quả cho ngoại lệ mà tôi tìm thấy qua google xử lý văn bản trả về/json thay vì văn bản/xml như trong tình huống của tôi.

Có ai có thể giúp tôi không? Tôi nghĩ, nếu tôi sử dụng một Response, đó sẽ là yếu tố tôi gốc trong XML và bộ sưu tập của tôi một danh sách các yếu tố chuỗi trong nó ..

Trả lời

11

LƯU Ý: Mặc dù câu trả lời này hoạt động, anar's answer là tốt hơn.

Bạn nên cố gắng sử dụng lớp chú thích JAXB để giải quyết vấn đề của mình. Bạn có thể thay đổi phương thức của mình thành điều này:

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

Sau đó tạo một lớp chú thích JAXB cho nhóm của bạn. Tôi đã bao gồm một lớp học được tạo cho bạn, sử dụng quy trình được mô tả trong this answer. Dưới đây là một ví dụ về các tài liệu mà nó sẽ tạo ra:

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

Và đây là lớp được tạo ra:

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

Có còn cách nào khác? Tôi nghĩ Response sẽ thực hiện công việc cho những gì bạn đã tạo ra nhóm Groups.-> cung cấp một container cho danh sách một hành động như là phần tử gốc – lrxw

+0

Tối thiểu, một cái gì đó cần phải cho Jersey biết tên của phần tử XML gốc. Có vẻ như bạn có thể sử dụng [trình bao bọc chung và JAXB] (http://stackoverflow.com/a/1603484/1818625) hoặc [thư viện 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 ..có thể bạn giải quyết vấn đề này không ?? – user2416728

40

Sử dụng

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

Thực thể wrapper Generic hoạt động để nhận được đầu ra khi sử dụng Trình tạo câu trả lời.

Reference

+0

Làm việc tuyệt vời cho LinkedList - cảm ơn! – remrick

+0

thật đáng buồn là liên kết mà bạn đã tham chiếu ở đây hiện đã chết, nhưng sẽ thực sự hữu ích – Toadfish

+1

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

0

Điều duy nhất mà làm việc cho tôi cho đến nay là để tạo ra đối tượng Wrapper của riêng tôi.

Đừng quên @XmlRootElement chú thích để giải thích JAXB làm thế nào để phân tích nó.

Lưu ý rằng điều này sẽ làm việc cho bất kỳ loại đối tượng nào - trong ví dụ này tôi đã sử dụng ArrayList của chuỗi.

ví dụ:

Đối tượng Wrapper sẽ trông như thế này:

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

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

Và phương pháp REST của sẽ giống như thế này:

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