我有一些内存数据结构,我从XML文件加载,并希望公开简化的API,而不将XML或任何数据结构用户绑定到实现细节。我使用Jackson进行XML解组。
正如您在代码中看到的那样,Profile
类包含User
的实例,但直接公开User
字段的getter / setter。我不想拥有setUser(User)/ getUser(),因为我希望从公共API中隐藏该实现细节。
Profile.java:
package com.example.data;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "profile")
public class Profile {
private User user;
private String email;
@XmlElement(name = "userID")
public String getUserID() {
return user.getUserID();
}
@XmlElement(name = "userID")
public void setUserID(String userID) {
user.setUserID(userID);
}
@XmlElement(name = "password")
public String getPassword() {
return user.getPassword();
}
@XmlElement(name = "password")
public void setPassword(String password) {
user.setPassword(password);
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
User.java:
package com.example.data;
public class User {
public String userID;
public String password;
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
正如您所看到的,我尝试在getter和setter上添加@XmlElement JAXB注释,但没有成功。我也试过@JacksonXmlProperty,但也没有运气。
我也不想将<userID>
和<password>
包裹在<user>
标记中;我希望XMl平坦,如下所示。
是profile.xml:
<?xml version="1.0" encoding="UTF-8"?>
<profile>
<userID>bob</userID>
<password>letmein</password>
<email>bob@example.com</email>
</profile>
JacksonXMLExample.java:
package com.example;
import java.io.File;
import java.io.IOException;
import com.example.data.Profile;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
public class JacksonXMLExample {
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
File file = new File("src/main/resources/profile.xml");
ObjectMapper mapper = new XmlMapper();
JaxbAnnotationModule module = new JaxbAnnotationModule();
mapper.registerModule(module);
Profile profile = mapper.readValue(file, Profile.class);
System.out.println(profile);
}
}
的pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>JacksonXMLExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-xml-provider</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>2.7.4</version>
</dependency>
</dependencies>
</project>
当我尝试执行上面的代码时,我得到以下异常:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: N/A
at [Source: src\main\resources\profile.xml; line: 3, column: 13] (through reference chain: com.example.data.Profile["userID"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:262)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty._throwAsIOE(SettableBeanProperty.java:537)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty._throwAsIOE(SettableBeanProperty.java:518)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:99)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:260)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3807)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2691)
at com.example.JacksonXMLExample.main(JacksonXMLExample.java:21)
Caused by: java.lang.NullPointerException
at com.example.data.Profile.setUserID(Profile.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:97)
... 5 more
如何使用由其他POJO组成的复杂POJO而不必在相应的XML中镜像该结构或向该类用户公开实现细节?
答案 0 :(得分:1)
当我准备发布我的问题时,当我意识到我需要的只是初始化Profile.java中的user
字段时,我有一个facepalm时刻:
private User user = new User();
这是必要的,因为当然,您不能将方法调用委托给尚未初始化的成员。