【问题标题】:Spring Boot Rest API Enumerate some Java typesSpring Boot Rest API 枚举一些 Java 类型
【发布时间】:2020-11-15 13:05:21
【问题描述】:

我正在构建 Spring Boot webflux REST API 功能,该功能需要处理包含少量 Java 类型(例如,让我们考虑 String、Integer、Double)信息的数据作为 JSON 请求/响应的一部分。表示 Java 类型的属性也必须在 mongodb 中是可持久的(一旦 JSON 可以使用此类属性,这应该不是问题)。我有以下模型类和类型枚举,REST API 使用它来序列化/反序列化 JSON 消息。

@Getter
@ToString
@EqualsAndHashCode(exclude = "id")
@Document(collection = "core_scheme")
@JsonDeserialize(builder = SchemeModel.Builder.class)
@Builder(builderClassName = "Builder", toBuilder = true, setterPrefix = "with")
public class SchemeModel {

    @Id
    private final String id;

    @Field(name = "userId") private final String userId;
    @Field(name = "date") private final String creationDate;
    @Field(name = "properties") private final Map<String, SchemeTypes> properties;
}
public enum SchemeTypes {
    INTEGER, STRING, DOUBLE
}

序列化和反序列化工作得很好。现在的问题是,当我想解析存储在 Map&lt;String, SchemeTypes&gt; properties 映射中的真实 Java 类型时,我需要进行类似于此的映射(只是抽象而不是真实代码):

SchemeTypes.INTEGER => Java Integer class  
SchemeTypes.STRING => Java String class  
SchemeTypes.DOUBLE => Java Double class  

有没有更简单的方法来表示存储在模型类中并在序列化/反序列化 JSON 文件中使用的 Java 类型,所以我可以直接使用它来推断 Java 类型,而无需额外验证它是有效的 Java 类型。例如,如果在提到的枚举中枚举的类型与真正的 Java 类型具有完全相同的命名,我可以在没有任何映射的情况下执行以下操作:

public void deduceClass(SchemeTypes type) {
    Class myClass = Class.forName(type.toString());
}

请注意,我正在寻找一种开箱即用的解决方案(我不必验证用户提供的类型)。如果这样的解决方案更难像提到的映射那样实现,我会坚持使用映射。

【问题讨论】:

    标签: java json spring-boot rest


    【解决方案1】:

    如果你没有保存这个实体,我可以说你实际上可以直接将 SchemeTypes 映射到相应的类中,如下所示

    public enum SchemeTypes {
        INTEGER(Integer.class), STRING(String.class), DOUBLE(Double.class);
    
        private final Class clazz;
    
        private SchemeTypes(Class clazz){
           this.clazz = clazz;
        }
        
        public Class getClazz(){
           return clazz;
        }
    }
    

    但是当你保存它时,它可能会导致一些反序列化问题。 也许您可以不直接保存 SchemaType 实例,而只保存枚举的名称来克服这个问题,如下所示

    private final Map<String, String> properties;
    

    并在此类上使用静态方法找到相应的 clazz 值,如下所示

    public static Class findClazzFor(String schemeTypeName){
           return SchemeTypes.valueOf(schemeTypeName).getClazz();
        }
    

    尽管如此,我认为最简洁的解决方案是将 SchemeType 类实例映射保留为一对一映射。并按照上面的 getClazz 方法检索提供的 schemeType 对应的类。

    【讨论】:

    • 是的,你发布的那个枚举正是我想要实现的。我知道我看到了一些我只是想不起来的东西。我会做一些测试,如果 enum Like that is persistable by spring in mongodb。因为我使用的是 webflux,所以没有像 Hibernate 这样的技术,但是如果这样的枚举是可序列化/可反序列化的,我认为这是因为基本枚举是并且你只是为每个枚举指定类型(那是应该解析类型的 java 代码)这应该工作.请随意根据 Spring Rest API 将问题作为不常见的问题进行投票。
    • 我可以验证您建议的 Enum 工作是否正常,可以由 Jackson 序列化/反序列化,并且可以通过 spring boot 在 mongodb 中持久化。因此,这是对我的问题的有效答案,并且由于此类 Enum 不需要映射到相应的 Java 类(感谢直接存储在 Enum 中的 Java 类信息),因此我将此答案标记为已接受。
    猜你喜欢
    • 1970-01-01
    • 2023-02-19
    • 1970-01-01
    • 2021-03-05
    • 2019-07-14
    • 2019-10-07
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    相关资源
    最近更新 更多