java - Jersey 休息服务未返回 XML 响应

标签 java xml json jaxb jersey-2.0

我正在使用 Jersey 构建一个 REST API,其中允许 XML 和 JSON 输出,具体取决于客户端喜欢的格式(使用 Accept header )该服务将以下类作为输出发送,如下所示

@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字段并将其作为输出发送。

如果是 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() {

但它仍然不起作用......我错过了什么吗?

最佳答案

我使用了您的 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;
}

}

您可以使用以下 Adapter 类

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

Attachment 类应该有 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;
}

}

关于java - Jersey 休息服务未返回 XML 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28805494/

相关文章:

java - I/O "check if file name specified"args != 2 件事

javascript - 通过 JQuery $.post 将 JavaScript 数组传递给 PHP

ios - 无法将数据转换为字典

java - A* 寻路问题处理(Java)

java - 在 jasper 报告中设置报告区域的大小

java - 如何在 Java 中快速截取屏幕截图?

css - 如何在 Ruby 中验证 XHTML、ATOM 和 CSS?

python - 似乎无法删除 "ns0:"命名空间声明

java - JAXB 解码树结构

javascript - 按字母顺序对JSON排序(最后为空值)