假设我们定义了如下的枚举类,包含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 {
@Override
public void serialize(Result value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeNumber(value.getCode());
}
}
/**
* 反序列化,将JSON转为Java对象,用于接收前端参数
*/
public static class ResultDeSerializer extends JsonDeserializer {
@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才生效。
序列化其他自定义对象也是同理