关于java:Spring-Boot如何处理前后端枚举值的序列化

6次阅读

共计 2816 个字符,预计需要花费 8 分钟才能阅读完成。

假如咱们定义了如下的枚举类,蕴含 code 和 msg 两个属性。

package cn.bugkit.serialization.components;

import java.security.InvalidParameterException;

/**
 * @author bugkit
 * @since 2022.2.25
 */
public enum Result {SUCCESS(0,"SUCCESS"),
    FAIL(-1,"FAIL");

    int code;
    String msg;

    Result(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public int getCode() {return code;}

    public void setCode(int code) {this.code = code;}

    public String getMsg() {return msg;}

    public void setMsg(String msg) {this.msg = msg;}

    public static Result valueOf(int code){Result[] values = values();
        for (Result result : values) {if (result.getCode() == code) {return result;}
        }
        throw new InvalidParameterException("Invalid Code");
    }
}

Spring Boot Jackson 枚举值默认是通枚举常量的名字来序列化和反序列化的。

假如当初前端要求前后端的通信通过 code 属性进行。咱们应该怎么做呢?

那就要用到 Spring Boot 提供的 @JsonComponent 注解了。

上面咱们一起看看残缺的实例吧。

首先是 controller, 提供了入参 (反序列化) 和后果返回 (序列化) 的例子。

/**
 * @author bugkit
 * @since 2022.2.25
 */
@RestController
public class EnumController {

    /**
     * 入参的 result 字段是 -1 - fail,后果是 0 - success
     * @param response
     * @return
     */
    @PostMapping("test")
    public HttpResponse testSerialize(@RequestBody HttpResponse response) {System.out.println(response);
        return new HttpResponse(Result.SUCCESS, null);
    }

}

上面咱们看看 HttpResponse, 蕴含属性 result 和数据 data

/**
 * @author bugkit
 * @since 2022.2.25
 */
public class HttpResponse {

    private Result result;
    private Object data;


    public HttpResponse(Result result, Object data) {
        this.result = result;
        this.data = data;
    }

    public Result getResult() {return result;}

    public void setResult(Result result) {this.result = result;}

    public Object getData() {return data;}

    public void setData(Object data) {this.data = data;}

    @Override
    public String toString() {
        return "HttpResponse{" +
                "result=" + result +
                ", data=" + data +
                '}';
    }
}

最初再看看要害的中央,标注 Result 所应用的序列化和反序列化类

/**
 * @author bugkit
 * @since 2022.2.25
 */
@JsonComponent
public class WenSerialization {

    /**
     * 序列化,行将 Java 对象转为 JSON,用于将 Java 对象转为前端所需的后果,此处只传输 Result 的 code 字段
     */
    public static class ResultSerializer extends JsonSerializer<Result> {

        @Override
        public void serialize(Result value, JsonGenerator gen, SerializerProvider serializers) throws IOException {gen.writeNumber(value.getCode());
        }
    }

    /**
     * 反序列化,将 JSON 转为 Java 对象,用于接管前端参数
     */
    public static class ResultDeSerializer extends JsonDeserializer<Result> {

        @Override
        public Result deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {ObjectCodec codec = p.getCodec();
            JsonNode treeNode = codec.readTree(p);
            int code = treeNode.intValue();
            return Result.valueOf(code);
        }
    }
}

最初咱们来看看测试后果:

入参

{
    "result": -1,
    "data": "data"
}

控制台打印

2022-02-25 10:16:57.583  INFO 1324 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-02-25 10:16:57.584  INFO 1324 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2022-02-25 10:16:57.584  INFO 1324 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
HttpResponse{result=FAIL, data=data}

返回后果

{
    "result": 0,
    "data": null
}

留神:该形式只针对应用了 spring boot 自带的 jackson 才失效。

序列化其余自定义对象也是同理

代码地址:https://github.com/bennetty74…

正文完
 0