前端传给后端,或者是后端与后端之间的调用,基本使用Json;比如说有一个消息类型,包含文本、图片、卡片,而卡片下又有其它的卡片类型,这样的话就需要有一个标识来区分消息类型,并且每一个消息类型都需要不同的转换;
可以使用 gson 中的 JsonDeserializer 来实现自定义发序列化;
依赖
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
</dependency>
创建 自定义的 GsonBuilder 对象
disableHtmlEscaping:特殊字符的转义,会把escapeHtmlChars 设置为false。默认为true;可以理解为 如果你的Json需要传html代码就需要设置为false;
true:会将html中的字符例如< >这样的字符处理转义掉;
false:不会转义;
registerTypeAdapter:注册自定义适配器
public class MsgGsonBuilder {
public static final GsonBuilder INSTANCE = new GsonBuilder();
static {
INSTANCE.disableHtmlEscaping();
INSTANCE.registerTypeAdapter(Msg.class, new MsgAdapter());
}
public static Gson create() {
return INSTANCE.create();
}
}
创建主类 Msg
以msgType 属性作为标识,区分消息类型;
以及需要传递的其他参数;
JsonInclude.Include.NON_NULL:当类中的属性为null时,不会返回给前端;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Msg implements Serializable {
private static final long serialVersionUID = 8767141819701121212L;
@SerializedName("userId")
protected String userId;
@SerializedName("msgType")
protected String msgType;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getMsgType() {
return msgType;
}
public void setMsgType(String msgType) {
this.msgType = msgType;
}
public static Msg fromJson(String json) {
return MsgGsonBuilder.create().fromJson(json, Msg.class);
}
public String toJsonStr() {
return MsgGsonBuilder.create().toJson(this);
}
}
文本消息
public class TextMsg extends Msg{
private Text text;
public TextMsg() {
super();
super.msgType = MsgConsts.MSG_TEXT;
}
public TextMsg(Text text) {
super();
super.msgType = MsgConsts.MSG_TEXT;
this.text = text;
}
public Text getText() {
return text;
}
public TextMsg setText(Text text) {
this.text = text;
return this;
}
}
public class Text implements Serializable {
private static final long serialVersionUID = 5085189527874814188L;
private String content;
public Text(String content) {
super();
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
图片消息
public class ImageMsg extends Msg{
private Image image;
public ImageMsg() {
super();
super.msgType = MsgConsts.MSG_IMAGE;
}
public ImageMsg(Image image) {
super();
super.msgType = MsgConsts.MSG_IMAGE;
this.image = image;
}
public Image getImage() {
return image;
}
public ImageMsg setImage(Image image) {
this.image = image;
return this;
}
}
public class Image implements Serializable {
private static final long serialVersionUID = 4033747019826925556L;
private String imageId;
public Image(String imageId) {
super();
this.imageId = imageId;
}
public String getImageId() {
return imageId;
}
public void setImageId(String imageId) {
this.imageId = imageId;
}
}
未定义消息
public class NotDefinedMsg extends Msg{
private String jsonStr;
public static NotDefinedMsg fromjson(String json) {
return MsgGsonBuilder.create().fromJson(json, NotDefinedMsg.class);
}
public String getJsonStr() {
return jsonStr;
}
public void setJsonStr(String jsonStr) {
this.jsonStr = jsonStr;
}
}
卡片消息
定义卡片消息的主类,通过card这个参数来区分卡片类型
public class CardMsg extends Msg{
@SerializedName("card")
protected String card;
public CardMsg() {
super();
super.msgType = MsgConsts.MSG_CARD;
}
public String getCard() {
return card;
}
public CardMsg setCard(String card) {
this.card = card;
return this;
}
public static CardMsg fromjson(String json) {
return MsgGsonBuilder.create().fromJson(json, CardMsg.class);
}
}
订单卡片类型
public class OrderCardMsg extends CardMsg{
private OrderCard orderCard;
public OrderCardMsg(OrderCard orderCard) {
super();
this.orderCard = orderCard;
super.card = MsgConsts.MSG_ORDER_CARD;
}
public OrderCard getOrderCard() {
return orderCard;
}
public void setOrderCard(OrderCard orderCard) {
this.orderCard = orderCard;
}
public static OrderCardMsg fromjson(String json) {
return MsgGsonBuilder.create().fromJson(json, OrderCardMsg.class);
}
}
public class OrderCard implements Serializable {
private static final long serialVersionUID = -7298664220334795699L;
private String orderId;
public OrderCard() {
super();
}
public OrderCard(String orderId) {
super();
this.orderId = orderId;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
}
最后定义适配器,实现 JsonDeserializer
public class MsgAdapter implements JsonDeserializer<Msg> {
@Override
public Msg deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
JsonObject jo = json.getAsJsonObject();
Gson gson = new GsonBuilder().create();
String msgType = jo.get("msgType").getAsString();
switch (msgType){
case MsgConsts.MSG_TEXT:
// 文本消息
return gson.fromJson(json, TextMsg.class);
case MsgConsts.MSG_IMAGE:
// 图片消息
return gson.fromJson(json, ImageMsg.class);
case MsgConsts.MSG_CARD:
// 卡片消息
String card = jo.get("card").getAsString();
switch (card){
case MsgConsts.MSG_ORDER_CARD:
return gson.fromJson(json, OrderCardMsg.class);
default:
// 未定义消息
NotDefinedMsg msg = gson.fromJson(json, NotDefinedMsg.class);
msg.setJsonStr(json.toString());
return msg;
}
default:
// 未定义消息
NotDefinedMsg msg = gson.fromJson(json, NotDefinedMsg.class);
msg.setJsonStr(json.toString());
return msg;
}
}
}
测试
卡片消息
除了以上的消息类型外,还有文本、语音、视频、事件,而事件又包含其它的事件类型等等;通过这种自定义的方式,在后端解析json的时候只需要使用 Msg.fromJson(json) 就可以,就不需要每种消息类型都使用不同的方式解析;