超类的Json4s序列化
Json4s serialisation of superclass
我在为 Json4s 编写自定义序列化程序来处理以下情况时遇到问题。我有案例 类:
trait Condition
case class BasicExpression (field:String, operator:String, value:String) extends Condition
case class BooleanExpression (val leftExpr: Condition, val logicalOperator:String,
val rightExpr: Condition) extends Condition
我希望能够读取 BasicExpression
和 BooleanExpression
的 JSON,例如:
var jsonStringBasic:String = """ {"field":"name","operator":"=","value":"adam"}""";
var jsonStringBoolean:String = """{"leftExpr":{"leftExpr":{"field":"field1", "operator":"=", "value":"value1"}, "logicalOperator":"AND", "rightExpr":{"field":"field2","operator":">","value":"500"}}, "logicalOperator":"AND", "rightExpr": {"field":"field3","operator":"<","value":"10000"}}""";
var jValueBasic:JValue = parse(jsonStringBasic, false);
var readCBasic = jValueBasic.extract[Condition];
我了解自定义序列化程序如何读取 BasicExpression
,我可以使用 SimpleTypeHints
,但最好不要为每个文件都膨胀 JSON Condition
。我也可以尝试 extract[BooleanExpression]
,如果失败则尝试 extract[BasicExpression]
,但这看起来很难看。是否可以编写自定义序列化程序来处理 BooleanCondition
本身将递归包含另一个 Condition
这样我可以 extract[Condition]
?
为了更好地解析 JSON 你可以试试这个 :
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class GsonUtils {
public static String defaultDateTimeFormat = "yyyy-MM-dd'T'HH:mm:ssZ";
private static GsonBuilder gsonBuilder = new GsonBuilder().setDateFormat(defaultDateTimeFormat);
/***
* Creates a GSON instance from the builder with the default date/time format
*
* @return the GSON instance
*/
public static Gson createGson() {
// Create with default params
gsonBuilder = gsonBuilder.setDateFormat(defaultDateTimeFormat);
return gsonBuilder.create();
}
/***
* Creates a GSON instance from the builder specifying custom date/time format
*
* @return the GSON instance
*/
public static Gson createGson(String dateTimeFormat) {
// Create with the specified dateTimeFormat
gsonBuilder = gsonBuilder.setDateFormat(dateTimeFormat);
return gsonBuilder.create();
}
}
并像这样使用它
var String = """ {"field":"name","operator":"=","value":"adam"}""";
Type collectionType = new TypeToken<YOUR_CLASS>() {}.getType();
YOUR_CLASS iii= GsonUtils.createGson().fromJson(jsonStringBasic, collectionType);
设法使 CustomSerializer 正常工作,以便它可以递归调用自身,在 BooleanExpression 的情况下,如下所示:
class ConditionSerialiser extends CustomSerializer[Condition]( format => (
{
def deserialiseCondition:PartialFunction[JValue, Condition]= {
case JObject(List(JField("field", JString(field)), JField("operator", JString(operator)), JField("value", JString(value)))) => BasicStringExpression(field, operator, value)
case JObject(List(JField("field", JString(field)), JField("operator", JString(operator)), JField("value", JInt(value)))) => BasicNumericExpression(field, operator, value.doubleValue)
case JObject(List(JField("field", JString(field)), JField("operator", JString(operator)), JField("value", JDouble(value)))) => BasicNumericExpression(field, operator, value)
case JObject(List(JField("leftExpr", leftExpr), JField("logicalOperator", JString(logicalOperator)), JField("rightExpr", rightExpr))) => BooleanExpression(deserialiseCondition(leftExpr), logicalOperator, deserialiseCondition(rightExpr))
}
deserialiseCondition
},
{
case bse: BasicStringExpression => JObject(List(JField("field", JString(bse.field)), JField("operator", JString(bse.operator)), JField("value", JString(bse.value))))
}
))
我在为 Json4s 编写自定义序列化程序来处理以下情况时遇到问题。我有案例 类:
trait Condition
case class BasicExpression (field:String, operator:String, value:String) extends Condition
case class BooleanExpression (val leftExpr: Condition, val logicalOperator:String,
val rightExpr: Condition) extends Condition
我希望能够读取 BasicExpression
和 BooleanExpression
的 JSON,例如:
var jsonStringBasic:String = """ {"field":"name","operator":"=","value":"adam"}""";
var jsonStringBoolean:String = """{"leftExpr":{"leftExpr":{"field":"field1", "operator":"=", "value":"value1"}, "logicalOperator":"AND", "rightExpr":{"field":"field2","operator":">","value":"500"}}, "logicalOperator":"AND", "rightExpr": {"field":"field3","operator":"<","value":"10000"}}""";
var jValueBasic:JValue = parse(jsonStringBasic, false);
var readCBasic = jValueBasic.extract[Condition];
我了解自定义序列化程序如何读取 BasicExpression
,我可以使用 SimpleTypeHints
,但最好不要为每个文件都膨胀 JSON Condition
。我也可以尝试 extract[BooleanExpression]
,如果失败则尝试 extract[BasicExpression]
,但这看起来很难看。是否可以编写自定义序列化程序来处理 BooleanCondition
本身将递归包含另一个 Condition
这样我可以 extract[Condition]
?
为了更好地解析 JSON 你可以试试这个 :
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class GsonUtils {
public static String defaultDateTimeFormat = "yyyy-MM-dd'T'HH:mm:ssZ";
private static GsonBuilder gsonBuilder = new GsonBuilder().setDateFormat(defaultDateTimeFormat);
/***
* Creates a GSON instance from the builder with the default date/time format
*
* @return the GSON instance
*/
public static Gson createGson() {
// Create with default params
gsonBuilder = gsonBuilder.setDateFormat(defaultDateTimeFormat);
return gsonBuilder.create();
}
/***
* Creates a GSON instance from the builder specifying custom date/time format
*
* @return the GSON instance
*/
public static Gson createGson(String dateTimeFormat) {
// Create with the specified dateTimeFormat
gsonBuilder = gsonBuilder.setDateFormat(dateTimeFormat);
return gsonBuilder.create();
}
}
并像这样使用它
var String = """ {"field":"name","operator":"=","value":"adam"}""";
Type collectionType = new TypeToken<YOUR_CLASS>() {}.getType();
YOUR_CLASS iii= GsonUtils.createGson().fromJson(jsonStringBasic, collectionType);
设法使 CustomSerializer 正常工作,以便它可以递归调用自身,在 BooleanExpression 的情况下,如下所示:
class ConditionSerialiser extends CustomSerializer[Condition]( format => (
{
def deserialiseCondition:PartialFunction[JValue, Condition]= {
case JObject(List(JField("field", JString(field)), JField("operator", JString(operator)), JField("value", JString(value)))) => BasicStringExpression(field, operator, value)
case JObject(List(JField("field", JString(field)), JField("operator", JString(operator)), JField("value", JInt(value)))) => BasicNumericExpression(field, operator, value.doubleValue)
case JObject(List(JField("field", JString(field)), JField("operator", JString(operator)), JField("value", JDouble(value)))) => BasicNumericExpression(field, operator, value)
case JObject(List(JField("leftExpr", leftExpr), JField("logicalOperator", JString(logicalOperator)), JField("rightExpr", rightExpr))) => BooleanExpression(deserialiseCondition(leftExpr), logicalOperator, deserialiseCondition(rightExpr))
}
deserialiseCondition
},
{
case bse: BasicStringExpression => JObject(List(JField("field", JString(bse.field)), JField("operator", JString(bse.operator)), JField("value", JString(bse.value))))
}
))