“This is the third day of my participation in the First Challenge 2022, for more details: First Challenge 2022”.
The introduction
Hello, this is Anyin.
Following on from the previous article, we “gracefully” implement the front end dictionary enumeration value echo, when the database query returns a code value, we can serialize in Spring MVC according to the annotation information, Automatically convert the code value into an object containing text and code value and return it to the front end, so that the front end can conveniently get the corresponding text value for page rendering.
This is in the query scenario, but what about in the edit or add scenario?
In edit or add scenarios, the front end will give the back end a code value, and the back end will receive the enumeration value as a String, then convert it into the corresponding enumeration object in the business code, and finally perform the corresponding business operation. The logic of the transformation is as follows:
public static SexEnum get(String code){
for(SexEnum item : values()) {
if(code.equals(item.getCode())){
returnitem; }}// Return the default or throw an exception
return SexEnum.MAN;
}
Copy the code
There are two problems with this:
- This transformation method is required for all enumeration objects passed by the front end
- Enumeration values passed by the front end could not be verified for correctness
Train of thought
There are different solutions to the above two problems. For example, in question 1, we can abstract the get method by inheriting the parent class and make all the enumerated classes inherit the parent class. Question 2: You can verify that the enumeration values are correct by using annotations +AOP.
Of course, let’s share another solution here. In the previous article we solved this problem by serialization, so we will solve this problem by deserialization. When deserializing the JSON string, we take the Class object of the current enumeration field, match the value to the enumeration object, and return it.
implementation
The overall code is pretty simple. We implement a StringAsDictDeserializer class that inherits JsonDeserializer. Its generic type is BaseEnum, which is the abstract interface through which we define all enumerated objects. Finally, the ContextualDeserializer interface is required to obtain the Class object of the current enumeration field.
The code is as follows:
@Slf4j
@JacksonStdImpl
public class StringAsDictDeserializer extends JsonDeserializer<BaseEnum> implements ContextualDeserializer {
public StringAsDictDeserializer(a){}
privateClass<? > clazz;public StringAsDictDeserializer(Class
clazz){
this.clazz = clazz;
}
@Override
public BaseEnum deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
// The value passed by the front end
String value = p.getValueAsString();
// Get the corresponding enumeration object through traversal
BaseEnum type = Arrays.stream(clazz.getEnumConstants()).map(t -> (BaseEnum) t)
.filter(t -> Objects.equals(t.getCode(), value))
.findAny().orElse(null);
if(type == null) {throw new DictSerializerException("value is error, not found enum type");
}
return type;
}
@Override
publicJsonDeserializer<? > createContextual(DeserializationContext ctxt, BeanProperty property)throws JsonMappingException {
// Custom deserializerClass<? > typeClazz = property.getType().getRawClass();return newStringAsDictDeserializer(typeClazz); }}Copy the code
Note @jacksonStdimpl. The createContextual method of ContextualDeserializer interface only applies if you add it, and only then can you get the BeanProperty object. To get the Class object of the target enumeration Class.
test
Next, let’s test our code. In the Controller receiving entity class, we add the corresponding annotation configuration as follows:
@Data
public static class TestForm{
@JsonDeserialize(using = StringAsDictDeserializer.class)
private SexEnum sex;
@JsonDeserialize(using = StringAsDictDeserializer.class)
private StatusEnum status;
}
Copy the code
Request parameters using Postman:
Console print result:
The last
Above, we implement the backend to receive dictionary enumeration values, have you learned?
Anyin Cloud