java 解组 à 的错误转换

java unmarshal wrong conversion of à

我尝试使用以下代码解组字符串:

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAnyAttribute;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.namespace.QName;

import org.apache.commons.lang.StringEscapeUtils;

import org.apache.commons.io.IOUtils;
import org.xml.sax.InputSource;

@XmlRootElement(name="Grid")
public class Marshal {

@XmlAttribute(name="Reload", required = false)
public int reload;

@XmlElementWrapper(name="Changes")
@XmlElement(name="I")
public List<XmlAttributeHolder> rowList = new ArrayList<XmlAttributeHolder>();

public static void main(String[] args) {
    try {
        JAXBContext jc = JAXBContext.newInstance(Marshal.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        // à€
        String xmlString = "<Grid><IO/><Changes><I id=\"0\" Changed=\"1\" STT=\"à&amp;#8364;\"/></Changes></Grid>";
        InputStream inputStream = IOUtils.toInputStream(xmlString);
        InputSource is = new InputSource(inputStream);
        is.setEncoding("ISO-8859-1");
        Marshal obj = (Marshal) unmarshaller.unmarshal(is);
        System.out.println(xmlString);
        for (int i=0;i<obj.rowList.size();i++) {
            XmlAttributeHolder xah = obj.rowList.get(i);
            System.out.println(xah.getAttrMap());
            for (String formValue:xah.getAttrMap().values()) {
                System.out.println(StringEscapeUtils.unescapeXml(formValue));
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static class XmlAttributeHolder {
    @XmlAnyAttribute
    public Map<QName, String> attrMap = new HashMap<QName, String>();

    public void addAttribute(String name, String value) {
        attrMap.put(QName.valueOf(name), value);
    }

    public String getAttribute(String name) {
        return attrMap.get(QName.valueOf(name));
    }

    public Map<QName, String> getAttrMap() {
        return attrMap;
    }
}

}

我尝试 运行 Java 1.6 windows 中的这段代码并给出正确答案:

0
1
à€

当我在 IBM java 1.6 CentOS 中尝试 运行 这段代码时,给出了错误的答案:

0
1
à €

为什么解组指令不能正确转换 à(甚至 èéìòù...)?

如果您的输入实际上是 String,我建议将其直接传递给 Unmarshaller,包裹在 StringReader 中,而不是尝试生成 InputStream从中。它不太容易出错。

试试这个(见下面的代码片段)。这样您就不必担心您的代码是否指定了正确的编码或是否为该编码正确地进行了字符到字节的转换。

String xmlString = "<Grid><IO/><Changes><I id=\"0\" Changed=\"1\" STT=\"à&amp;#8364;\"/></Changes></Grid>";
InputSource is = new InputSource(new StringReader(xmlString));
Marshal obj = (Marshal) unmarshaller.unmarshal(is);