获取 MismatchedInputException:在将 JSON 解析为结果对象时无法反序列化对象的实例
Getting MismatchedInputException: Cannot deserialize instance of Object while parsing JSON to result object
我想将具有配置属性的 XML 文件解析为 JSON,然后将此 JSON 转换为最终结果对象。
我的 class 看起来像:
@SpringBootApplication
public class AdvancedApplication {
public static void main(String[] args) {
SpringApplication.run(AdvancedApplication.class, args);
XmlMapper xmlMapper = new XmlMapper();
try {
List XMLEntries = xmlMapper
.readValue(new ClassPathResource("configuration.xml")
.getFile(), List.class);
ObjectMapper mapper = new ObjectMapper();
String jsonConfig = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(XMLEntries);
JsonNode parent = new ObjectMapper().readTree(jsonConfig);
String content = parent.path("serverport").asText();
System.out.println(content);
System.out.println(jsonConfig);
} catch (IOException e) {
e.printStackTrace();
}
}
}
第一种情况:
List XMLEntries = xmlMapper
.readValue(new ClassPathResource("configuration.xml")
.getFile(), List.class);
以上方法将 JSON 包装在列表中,结果如下:
[ {
"serverport" : "9966"
}, {
"clientport" : "9999",
"serverHost" : "localhost"
} ]
但在这种情况下,我无法读取以下行的值:
String content = parent.path("serverport").asText();
因为内容是空的。
最后,我决定以这种特殊方式将我的 JSON 转换为结果对象配置:
Config configObject = mapper.readValue(jsonConfig, Config.class);
但不幸的是,我收到如下异常:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.javase.advanced.config.Config` out of START_ARRAY token
at [Source: (String)"[ {
"serverport" : "9966"
}, {
"clientport" : "9999",
"serverHost" : "localhost"
} ]"; line: 1, column: 1]
我的 configuration.xml 文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<server serverport="9966"/>
<client clientport="9999">
<serverHost>localhost</serverHost>
</client>
</config>
配置class如下:
@NoArgsConstructor
@Getter
@AllArgsConstructor
@ToString
public class Config {
private Server server;
private Client client;
}
Server.class
@AllArgsConstructor
@Getter
@NoArgsConstructor
public class Server {
@JsonProperty("serverport")
private String serverPort;
}
Config.class
@Getter
@NoArgsConstructor
public class Client {
@JsonProperty("serverHost")
private String serverHost;
@JsonProperty("clientport")
private String clientPort;
}
我想要实现的是将 configuration.xml 文件解析为 JSON 并将其转换为 Config 对象以创建配置 class 以供进一步使用。
编辑:
在 @pvpkiran
建议之后,我尝试了如下方法:
Config configValue = xmlMapper.readValue(new ClassPathResource("configuration.xml")
.getFile(), Config.class);
但毕竟我收到了这样的错误:
org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "serverport" (Class com.javase.advanced.server.Server), not marked as ignorable
at [Source: C:\Users\mzawadzki\Desktop\advanced\target\classes\configuration.xml; line: 3, column: 30] (through reference chain: com.javase.advanced.config.Config["server"]->com.javase.advanced.server.Server["serverport"])
编辑 2:
修改后我的 classes 看起来像:
Client.class
@Getter
@NoArgsConstructor
public class Client {
@JacksonXmlProperty(localName = "clientport")
private String clientPort;
@JacksonXmlProperty(localName = "serverHost")
private String serverHost;
}
Server.class
@AllArgsConstructor
@Getter
@NoArgsConstructor
public class Server {
@JacksonXmlProperty(localName = "serverport")
private String serverPort;
}
我为我的配置创建了一个包装器 class 想摆脱 [
和 ]
的发生。
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
@JacksonXmlRootElement(localName = "config")
public class ConfigWrapper {
private Config[] configurations;
}
现在我的配置 class 看起来像:
@NoArgsConstructor
@Getter
@AllArgsConstructor
@ToString
public class Config {
@JacksonXmlProperty(localName = "serverport")
private Server server;
@JacksonXmlProperty(localName = "client")
private Client client;
}
但同样没有解决问题,毕竟我收到异常:
org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "server" (Class com.javase.advanced.config.ConfigWrapper), not marked as ignorable
at [Source: (through reference chain: com.javase.advanced.config.ConfigWrapper["server"])
如果能提供有关如何实现目标并消除此异常的建议,我将不胜感激。
这应该有效。您可以使用 JAXB 进行解组。请阅读有关 JAXB 的内容。还要注意如何使用 XmlElement
和 XmlAttribute
。
String xmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<config>\n" +
" <server serverport=\"9966\"/>\n" +
" <client clientport=\"9999\">\n" +
" <serverHost>localhost</serverHost>\n" +
" </client>\n" +
"</config>";
JAXBContext jaxbContext;
try
{
jaxbContext = JAXBContext.newInstance(Config.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Config config = (Config) jaxbUnmarshaller.unmarshal(new StringReader(xmlString));
System.out.println(config);
}catch (JAXBException e){
e.printStackTrace();
}
Config class 会像这样
@XmlRootElement(name = "config")
@XmlAccessorType(XmlAccessType.PROPERTY)
public class Config {
public Server server;
public Client client;
public Config() {
}
public Server getServer() {
return server;
}
public void setServer(Server server) {
this.server = server;
}
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
}
服务器class
public class Server {
@XmlAttribute(name = "serverport")
public String serverPort;
}
客户class
public class Client {
@XmlAttribute(name = "clientport")
public String clientPort;
@XmlElement
public String serverHost;
}
pvpkiran
的解决方案解决了一个问题,但我无法忍受 Jackson 无法将 XML 解析为单个对象的事实。调查带来了理想的效果,最终证明我在我的 pom.XML 中有两个相似的依赖关系,如 jackson-databind
和 jackson-xml-databind
。原来他们之间有冲突。注释掉 jackson-xml-databind
后一切正常。
现在我的 类 看起来像:
Client.class
@Getter
@NoArgsConstructor
@Setter
public class Client {
@JacksonXmlProperty(localName = "clientport")
private String clientPort;
@JacksonXmlProperty(localName = "serverHost")
private String serverHost;
}
Server.class
@AllArgsConstructor
@Getter
@NoArgsConstructor
@Setter
public class Server {
@JacksonXmlProperty(localName = "serverport")
private String serverPort;
}
Config.class
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@JacksonXmlRootElement(localName = "config")
public class Config {
private Server server;
private Client client;
}
再次感谢您的承诺。
我想将具有配置属性的 XML 文件解析为 JSON,然后将此 JSON 转换为最终结果对象。
我的 class 看起来像:
@SpringBootApplication
public class AdvancedApplication {
public static void main(String[] args) {
SpringApplication.run(AdvancedApplication.class, args);
XmlMapper xmlMapper = new XmlMapper();
try {
List XMLEntries = xmlMapper
.readValue(new ClassPathResource("configuration.xml")
.getFile(), List.class);
ObjectMapper mapper = new ObjectMapper();
String jsonConfig = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(XMLEntries);
JsonNode parent = new ObjectMapper().readTree(jsonConfig);
String content = parent.path("serverport").asText();
System.out.println(content);
System.out.println(jsonConfig);
} catch (IOException e) {
e.printStackTrace();
}
}
}
第一种情况:
List XMLEntries = xmlMapper
.readValue(new ClassPathResource("configuration.xml")
.getFile(), List.class);
以上方法将 JSON 包装在列表中,结果如下:
[ {
"serverport" : "9966"
}, {
"clientport" : "9999",
"serverHost" : "localhost"
} ]
但在这种情况下,我无法读取以下行的值:
String content = parent.path("serverport").asText();
因为内容是空的。
最后,我决定以这种特殊方式将我的 JSON 转换为结果对象配置:
Config configObject = mapper.readValue(jsonConfig, Config.class);
但不幸的是,我收到如下异常:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.javase.advanced.config.Config` out of START_ARRAY token
at [Source: (String)"[ {
"serverport" : "9966"
}, {
"clientport" : "9999",
"serverHost" : "localhost"
} ]"; line: 1, column: 1]
我的 configuration.xml 文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<server serverport="9966"/>
<client clientport="9999">
<serverHost>localhost</serverHost>
</client>
</config>
配置class如下:
@NoArgsConstructor
@Getter
@AllArgsConstructor
@ToString
public class Config {
private Server server;
private Client client;
}
Server.class
@AllArgsConstructor
@Getter
@NoArgsConstructor
public class Server {
@JsonProperty("serverport")
private String serverPort;
}
Config.class
@Getter
@NoArgsConstructor
public class Client {
@JsonProperty("serverHost")
private String serverHost;
@JsonProperty("clientport")
private String clientPort;
}
我想要实现的是将 configuration.xml 文件解析为 JSON 并将其转换为 Config 对象以创建配置 class 以供进一步使用。
编辑:
在 @pvpkiran
建议之后,我尝试了如下方法:
Config configValue = xmlMapper.readValue(new ClassPathResource("configuration.xml")
.getFile(), Config.class);
但毕竟我收到了这样的错误:
org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "serverport" (Class com.javase.advanced.server.Server), not marked as ignorable
at [Source: C:\Users\mzawadzki\Desktop\advanced\target\classes\configuration.xml; line: 3, column: 30] (through reference chain: com.javase.advanced.config.Config["server"]->com.javase.advanced.server.Server["serverport"])
编辑 2:
修改后我的 classes 看起来像:
Client.class
@Getter
@NoArgsConstructor
public class Client {
@JacksonXmlProperty(localName = "clientport")
private String clientPort;
@JacksonXmlProperty(localName = "serverHost")
private String serverHost;
}
Server.class
@AllArgsConstructor
@Getter
@NoArgsConstructor
public class Server {
@JacksonXmlProperty(localName = "serverport")
private String serverPort;
}
我为我的配置创建了一个包装器 class 想摆脱 [
和 ]
的发生。
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
@JacksonXmlRootElement(localName = "config")
public class ConfigWrapper {
private Config[] configurations;
}
现在我的配置 class 看起来像:
@NoArgsConstructor
@Getter
@AllArgsConstructor
@ToString
public class Config {
@JacksonXmlProperty(localName = "serverport")
private Server server;
@JacksonXmlProperty(localName = "client")
private Client client;
}
但同样没有解决问题,毕竟我收到异常:
org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "server" (Class com.javase.advanced.config.ConfigWrapper), not marked as ignorable
at [Source: (through reference chain: com.javase.advanced.config.ConfigWrapper["server"])
如果能提供有关如何实现目标并消除此异常的建议,我将不胜感激。
这应该有效。您可以使用 JAXB 进行解组。请阅读有关 JAXB 的内容。还要注意如何使用 XmlElement
和 XmlAttribute
。
String xmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<config>\n" +
" <server serverport=\"9966\"/>\n" +
" <client clientport=\"9999\">\n" +
" <serverHost>localhost</serverHost>\n" +
" </client>\n" +
"</config>";
JAXBContext jaxbContext;
try
{
jaxbContext = JAXBContext.newInstance(Config.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Config config = (Config) jaxbUnmarshaller.unmarshal(new StringReader(xmlString));
System.out.println(config);
}catch (JAXBException e){
e.printStackTrace();
}
Config class 会像这样
@XmlRootElement(name = "config")
@XmlAccessorType(XmlAccessType.PROPERTY)
public class Config {
public Server server;
public Client client;
public Config() {
}
public Server getServer() {
return server;
}
public void setServer(Server server) {
this.server = server;
}
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
}
服务器class
public class Server {
@XmlAttribute(name = "serverport")
public String serverPort;
}
客户class
public class Client {
@XmlAttribute(name = "clientport")
public String clientPort;
@XmlElement
public String serverHost;
}
pvpkiran
的解决方案解决了一个问题,但我无法忍受 Jackson 无法将 XML 解析为单个对象的事实。调查带来了理想的效果,最终证明我在我的 pom.XML 中有两个相似的依赖关系,如 jackson-databind
和 jackson-xml-databind
。原来他们之间有冲突。注释掉 jackson-xml-databind
后一切正常。
现在我的 类 看起来像:
Client.class
@Getter
@NoArgsConstructor
@Setter
public class Client {
@JacksonXmlProperty(localName = "clientport")
private String clientPort;
@JacksonXmlProperty(localName = "serverHost")
private String serverHost;
}
Server.class
@AllArgsConstructor
@Getter
@NoArgsConstructor
@Setter
public class Server {
@JacksonXmlProperty(localName = "serverport")
private String serverPort;
}
Config.class
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@JacksonXmlRootElement(localName = "config")
public class Config {
private Server server;
private Client client;
}
再次感谢您的承诺。