我有以下模型类:
package com.ab.model;
import java.util.List;
public class Request {
public Request(String requestType, Body body, List<String> emails) {
this.requestType = requestType;
this.body =body;
this.emails = emails;
}
private String requestType;
private Body body;
private List<String> emails;
public String getRequestType() {
return requestType;
}
public void setRequestType(String requestType) {
this.requestType = requestType;
}
public Body getBody() {
return body;
}
public void setBody(Body body) {
this.body = body;
}
public List<String> getEmails() {
return emails;
}
public void setEmails(List<String> emails) {
this.emails = emails;
}
}
class Body {
private String content;
private List<Header> headers;
public Body(String content, List<Header> headers) {
this.content = content;
this.headers = headers;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public List<Header> getHeaders() {
return headers;
}
public void setHeaders(List<Header> headers) {
this.headers = headers;
}
}
class Header {
private String headerName;
public Header (String headerName) {
this.headerName = headerName;
}
public String getHeaderName() {
return headerName;
}
public void setHeaderName(String headerName) {
this.headerName = headerName;
}
}
和Request类的以下实例:
Request request = new Request(
"get",
new Body("abcdefg",
Arrays.asList(new Header("header_one"))),
Arrays.asList("a@a.com", "b@b.com"));
你知道有什么库或算法可以将请求对象序列化成以下字符串吗?
requestType = "get"
body.content = "abcdefg"
body.headers[0].headerName = "header_one"
emails[0] = "a@a.com"
emails[1] = "b@b.com"
我知道我可以序列化它为json, xml等,但这些不适合我的用例。基本上,我需要这样的序列化:field.nestedField.reallyNestedField = "它的原始值"
作为下一步,我计划读取生成的字符串并为每个字段/nestedField生成任意数据,然后使用Apache的PropertyUtils将其反序列化,例如:
PropertyUtils.setProperty(requestObject, "requestType", "random type");
PropertyUtils.setProperty(requestObject, "body.content", "random content");
//...
多谢!安德烈。
重写您的toString()
默认方法来读取和输出您的成员变量作为文本。你可以使用super
来引用你的超类和它的成员。
PS:你的类中没有默认构造函数!如果你有带参数列表的构造函数,建议在你的类中包含无参数默认构造函数!特别是在实现一些与序列化/反序列化相关的逻辑的情况下!
可以使用Commons PropertyUtils
对类/对象属性进行迭代和递归。
根据实现的复杂程度,您可能需要对原语/包装器/集合类型进行一些类型检查(下面利用Commons ClassUtils
)。
public static List<String> getPropertyDescriptorPaths(Class<?> clazz) {
return getPropertyDescriptorPaths("", clazz);
}
private static List<String> getPropertyDescriptorPaths(String prefix, Class<?> clazz) {
List<String> paths = new ArrayList<>();
PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(clazz);
for (PropertyDescriptor pd : descriptors) {
if (isSimpleType(pd.getPropertyType())) {
paths.add(prefix + pd.getName());
} else if (!pd.getName().equals("class")) {
paths.addAll(getPropertyDescriptorPaths(pd.getName() + ".", pd.getPropertyType()));
}
}
return paths;
}
private static boolean isSimpleType(Class<?> clazz) {
return ClassUtils.isPrimitiveOrWrapper(clazz) || clazz.equals(String.class) || isCollectionOrArray(clazz);
}
private static boolean isCollectionOrArray(Class<?> clazz) {
return isCollection(clazz) || clazz.isArray();
}
private static final List<Class<?>> COLLECTION_TYPES = Arrays.asList(new Class<?>[] { List.class, Map.class, Set.class });
private static boolean isCollection(Class<?> clazz) {
for (Class<?> eachClass : COLLECTION_TYPES) {
if (eachClass.isAssignableFrom(clazz)) {
return true;
}
}
return false;
}
比较属性名和class
的条件是因为每个对象都有一个getClass()
方法,我们不关心这个。
在你的类中使用这个,我们得到结果:
System.out.println(getPropertyDescriptorPaths(Request.class));
// [emails, requestType, body.headers, body.content]