JAXB Unmarshalling json with unknown field have special character throwing DOM exception invalid character error while try to map XMLAnyElement

JAXB Unmarshalling json with unknown field having special character throwing DOM exception invalid character error while trying to map XMLAnyElement

我正在从具有特殊字符 # 的字段的 Web 服务中检索 json。例如 i#d.

示例 json 文件:

student : {
        "name" : "xyz",
        "randomfield" : null,
        "address" : {
                 "door number" : "2/3/45A",
                 "street" : "arundalpet",
                 "city"   : "newyork"
              }
        "i#d" : "some value"
    }

我的实体是

@XmlAccessorType(XmlAccessType.FIELD)
public class Student {

    @XmlElement(name = "name")
    private String name;
    
    @XmlElement(name ="address")
    private Address address;

    // add a catch all value
    @XmlAnyElement(lax = true)
    private Object[] unknown;

    .... getters and setters of name and address

}

这里我添加了未知字段来捕获所有不需要映射到我们字段的未知字段。添加这个的原因是:如果 Address 没有被映射,例如:randomfield 是具有 null 的未知字段。因此,为了避免这种情况,我使用 XmlAnyElement.

处理了未知字段

如果我删除实体中的未知字段,我不会收到任何错误,但地址为空。

所以,我需要这个未知字段处理和特殊字符处理来使用 JAXB 解组 json。

有人可以帮我吗?

我尝试了一种解决方法,您应该可以 unmarshal 使用它。我认为没有使用 JAXB/Moxy 的直接方法。以下是代码:

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Unmarshaller;
import org.eclipse.persistence.internal.oxm.ByteArraySource;
import org.eclipse.persistence.jaxb.JAXBContextProperties;

import javax.xml.transform.TransformerException;
import javax.xml.transform.stream.StreamSource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

public class UnmarshallingJSON {
    public static void main(String[] args) throws JAXBException, TransformerException, IOException {
        final InputStream inputStream = com.newJAXB.UnmarshallingJSON.class.getClassLoader().getResourceAsStream("student.json");
        final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

        Map<String, Object> properties = new HashMap<String, Object>(2);
        properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
        properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
        final JAXBContext jc = JAXBContext.newInstance(new Class[]{Student.class}, properties);
        final Unmarshaller unmarshaller = jc.createUnmarshaller();


        String temp = "";
        StringBuffer textFileContent = new StringBuffer();
        while ((temp = bufferedReader.readLine()) != null) {
            if (temp.contains("i#d")) {
                temp = temp.replaceAll("#", "");
                textFileContent.append(temp);
            } else {
                textFileContent.append(temp);
            }
        }
        bufferedReader.close();

        StreamSource streams = new ByteArraySource(textFileContent.toString().getBytes());
        Student student = unmarshaller.unmarshal(streams, Student.class).getValue();
        System.out.println(student);
    }
}

以下是Student

import jakarta.xml.bind.annotation.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.util.List;

@XmlRootElement(name = "Student")
@XmlType(name = "Student", propOrder = {"name", "address", "unknown"})
@XmlAccessorType(XmlAccessType.FIELD)
@ToString
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {

    private String name;
    private Address address;

    @XmlAnyElement(lax = true)
    private List<Object> unknown;
}


@Data
@XmlAccessorType(XmlAccessType.FIELD)
class Address {
    private String street;
    private String city;
}

以下是JSON

{
  "randomID": null,
  "name": "MyName",
  "address": {
    "street": "123Street",
    "city": "MyCity"
  },
  "i#d": "some value"
}