我有以下模型类:
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 =&#34;其原始值&#34;
下一步,我打算读取生成的字符串并为每个字段/ nestedField生成任意数据,然后使用来自Apache的PropertyUtils反序列化它,例如:
PropertyUtils.setProperty(requestObject, "requestType", "random type");
PropertyUtils.setProperty(requestObject, "body.content", "random content");
//...
非常感谢! 安德烈
答案 0 :(得分:0)
如何覆盖toString()
默认方法来读取和输出成员变量作为文本。您可以使用super
来引用您的SuperClass及其成员。
PS:您的班级中没有默认构造函数!如果你有你的参数列表的构造函数,建议在你的类中包含你的无参数默认构造函数!特别是在您实现与序列化/反序列化相关的一些逻辑的情况下!
答案 1 :(得分:0)
您可以使用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]