Jersey休息服务不返回XMLresponse

时间:2015-03-02 08:35:48

标签: java xml json jaxb jersey-2.0

我正在使用Jersey构建一个rest API,其中XML and JSON输出是允许的,具体取决于客户端喜欢的格式(使用Accept标头)。服务将以下类作为输出发送看起来像这样

@XmlRootElement
public class ProjectDetails{

    private List<Attachment> attachments;
    private Map<String, List<Attachment>> imageCategory;

    @XmlTransient
    public List<Attachment> getAttachments() {
        return attachments;
    }

    public void setAttachments(List<Attachment> attachments) {
        this.attachments = attachments;
    }

    public Map<String, List<Attachment>> getImageCategory() {
        if(attachments == null || attachments.size() == 0){
            return null;
        }

        Map<String, List<Attachment>> map = new HashMap<String, List<Attachment>>();
        for (Attachment img : attachments){
            String key = img.getCategory();
            if(BaseUtil.hasText(key)){
                List<Attachment> values = map.get(key);
                if (values == null){
                    values = new ArrayList<Attachment>();
                }
                values.add(img);
                map.put(key, values);
            }
        }

        this.imageCategory = map ;
        return imageCategory;
    }

    public void setImageCategory(Map<String, List<Attachment>> imageCategory) {
        this.imageCategory = imageCategory;
    }
}

我不希望attachments field作为输出,因此请将其标记为@XmlTransient,而我希望使用附件字段形成Map并将其作为输出发送。< / p>

如果是JSON格式,我会得到正确的答案。但是在XML的情况下,当我点击服务时,我没有得到任何输出。

我认为它与此Map字段有关,因为如果我删除Map字段并添加一些其他字段(如String),那么我会得到该字段作为响应。

请告诉我如何解决此问题。

更新 经过一些谷歌搜索后,我找到了XmlAdapter解决方案并实现如下

public class MapAdapter extends
        XmlAdapter<MapAdapter.AdaptedMap, Map<String, List<Attachment>>> {

    public static class AdaptedEntry {
        public String key;
        public List<Attachment> value = new ArrayList<Attachment>();
    }

    public static class AdaptedMap {
        List<AdaptedEntry> entries = new ArrayList<AdaptedEntry>();
    }

    @Override
    public AdaptedMap marshal(Map<String, List<Attachment>> map)
            throws Exception {
        AdaptedMap adaptedMap = new AdaptedMap();

        for (Entry<String, List<Attachment>> entry : map.entrySet()) {
            AdaptedEntry adaptedEntry = new AdaptedEntry();
            adaptedEntry.key = entry.getKey();
            adaptedEntry.value = entry.getValue();
            adaptedMap.entries.add(adaptedEntry);
        }
        return adaptedMap;
    }

    @Override
    public Map<String, List<Attachment>> unmarshal(AdaptedMap adaptedMap)
            throws Exception {
        List<AdaptedEntry> adapatedEntries = adaptedMap.entries;
        Map<String, List<Attachment>> map = new HashMap<String, List<Attachment>>(
                adapatedEntries.size());

        for (AdaptedEntry adaptedEntry : adapatedEntries) {
            map.put(adaptedEntry.key, adaptedEntry.value);
        }
        return map;
    }

然后

@XmlJavaTypeAdapter(MapAdapter.class)
    public Map<String, String> getImageCategory() {

但它还没有工作......我错过了什么?

1 个答案:

答案 0 :(得分:2)

我已经使用了你的ProjectDetails类进行了一些改动,它提供了对XML和JSON的响应。你能试试吗?

@XmlRootElement
public class ProjectDetails {
private List<Attachment> attachments;
private Map<String, ArrayList<Attachment>> imageCategory;

@XmlTransient
public List<Attachment> getAttachments() {
    return attachments;
}

public void setAttachments(List<Attachment> attachments) {
    this.attachments = attachments;
}
@XmlJavaTypeAdapter(MapAdapter.class) 
public Map<String, ArrayList<Attachment>> getImageCategory() {
    if(attachments == null || attachments.size() == 0){
        return null;
    }
    Map<String, ArrayList<Attachment>> map = new HashMap<String, ArrayList<Attachment>>();
    for (Attachment img : attachments){
        String key = img.getCategory();
        if(!key.equals("")){
            ArrayList<Attachment> values = map.get(key);
            if (values == null){
                values = new ArrayList<Attachment>();
            }
            values.add(img);
            map.put(key, values);
        }
    }

    this.imageCategory = map ;
    return imageCategory;
}

public void setImageCategory(Map<String, ArrayList<Attachment>> imageCategory) {
    this.imageCategory = imageCategory;
}

}

适配器类可以使用以下

public class MapAdapter extends XmlAdapter<MapElement[], Map<String, ArrayList<Attachment>>>{
public MapElement[] marshal(Map<String, ArrayList<Attachment>> arg0) throws Exception {
    MapElement[] mapElements = new MapElement[arg0.size()];
    int i = 0;
    for (Map.Entry<String, ArrayList<Attachment>> entry : arg0.entrySet()){
        mapElements[i++] = new MapElement(entry.getKey(), entry.getValue());
    }
    return mapElements;
}

public Map<String, ArrayList<Attachment>> unmarshal(MapElement[] arg0) throws Exception {
    Map<String, ArrayList<Attachment>> r = new HashMap<String, ArrayList<Attachment>>();
    for (MapElement mapelement : arg0)
        r.put(mapelement.key, mapelement.value);
    return r;
}

}

我也改变了MapElement

public class MapElement {
@XmlElement
public String key;
@XmlElement
public ArrayList<Attachment> value;

private MapElement() {
}

public MapElement(String key, ArrayList<Attachment> value) {
    this.key = key;
    this.value = value;
}
}

Attachement类应该有getter setter方法

public class Attachment {
public String getCategory() {
    return category;
}
public void setCategory(String category) {
    this.category = category;
}
private String category;
public Attachment(String cat){
    this.category = cat;
}

}