繁体   English   中英

如何将java对象序列化为field.path = field.value

[英]How to serialize java objects as field.path = field.value

我有以下模型类:

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 = 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 = "its original value"

作为下一步,我计划读取生成的字符串并为每个字段/nestedField 生成任意数据,然后使用 Apache 的 PropertyUtils 将其反序列化,例如:

PropertyUtils.setProperty(requestObject, "requestType", "random type");
PropertyUtils.setProperty(requestObject, "body.content", "random content");
//...

非常感谢! 安德烈

如何覆盖您的toString()默认方法以将您的成员变量作为文本读取和输出。 您可以使用super来引用您的 SuperClass 及其成员。

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]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM