Norbert Dopjera
Norbert Dopjera

Reputation: 751

Spring Boot Rest API Enumerate some Java types

I am building Spring Boot webflux REST API functionality that needs to work with data containing few Java type's (let's consider String, Integer, Double for example) information as part of JSON request/responses. Attribute representing Java type must be persistable inside mongodb as well (should not be problem once JSON can work with such attribute). I have following model class and type enumeration which is used by REST API to serialize/deserialize JSON message's.

@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
}

Serialization and deserialization work's well. Now the problem is that when i want to resolve real Java type's stored inside Map<String, SchemeTypes> properties map i need to do mapping similar to this (just abstraction not real code):

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

Is there any more simple way to represent Java type's stored inside model class and used within serialized/deserialized JSON file's so i can directly use it to deduce Java type without additional validation that it's valid Java type. For example if type's enumarated inside mentioned enum would have exactly same naming as real Java type's i could do following without any mapping:

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

Note that i am looking for a solution which would work out of the box (i don't have to validate type's provided by user). If such solution would be harder to implement as mentioned mapping i will stick with mapping.

Upvotes: 0

Views: 110

Answers (1)

cool
cool

Reputation: 1786

If you weren't saving this entity I could say you can actually directly map the SchemeTypes into corresponding class like following

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;
    }
}

But as you are saving this it could cause some issue to deserialize. Maybe you can save not the SchemaType instance directly but just the name of enum to overcome this like following

private final Map<String, String> properties;

and find the corresponding clazz value with a static method on this class like following

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

Nevertheless I think cleanest solution would be keeping the SchemeType class instance mapping somewhere as a one-to-one map. And retrieve the corresponding class for provided schemeType as in the getClazz method above.

Upvotes: 1

Related Questions