Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用GSON和Hibernate存储任意数据_Java_Json_Hibernate_Gson - Fatal编程技术网

Java 使用GSON和Hibernate存储任意数据

Java 使用GSON和Hibernate存储任意数据,java,json,hibernate,gson,Java,Json,Hibernate,Gson,我想保留一些只与客户端相关的数据。我喜欢故意忽略数据库规范化,因为数据在服务器端非常无用 我可以通过让客户机将数据转换为JSON并在请求中发送的JSON中包含字符串来完成这一点。然而,我更喜欢更干净更优雅的解决方案 我想要的是: 给定 和一个输入 { someString: "The answer", someInt: 43, clientData: { x: [1, 1, 2, 3, 5, 8, 13], y: [1,

我想保留一些只与客户端相关的数据。我喜欢故意忽略数据库规范化,因为数据在服务器端非常无用

我可以通过让客户机将数据转换为JSON并在请求中发送的JSON中包含字符串来完成这一点。然而,我更喜欢更干净更优雅的解决方案

我想要的是: 给定

和一个输入

{
    someString: "The answer",
    someInt: 43,
    clientData: {
        x: [1, 1, 2, 3, 5, 8, 13],
        y: [1, 1, 2, 6, 24, 120],
        tonsOfComplicatedStuff: {stuff: stuff}
    }
}

将压缩为JSON的
clientData
存储在一列中。注意,我不想为MyEntity编写适配器,因为有很多列。我需要一个单列适配器。列类型不必是字符串(
Serializable
或其他任何东西,因为服务器根本不在乎)。

Gson支持
@JsonAdapter
注释,允许指定JSON(反)序列化器、类型适配器,甚至类型适配器工厂。而且该注释看起来是注释
MyEntity
中的
clientData
字段的一个很好的候选者:

最终类MyEntity{
字符串;字符串;
int-someInt;
@高球
@JsonAdapter(PackedJsonTypeAdapterFactory.class)
字符串clientData;
}
类型适配器工厂可能如下所示:

最终类包djsonTypeAdapterFactory
实现TypeAdapterFactory{
//Gson可以自己实例化它
私有包djsonTypeAdapterFactory(){
}
@凌驾
公共类型适配器创建(最终Gson Gson、最终TypeToken TypeToken){
@抑制警告(“未选中”)
最终类型适配器TypeAdapter=(TypeAdapter)新的PackedJsonTypeAdapter(gson);
返回类型适配器;
}
私有静态最终类PackedJsonTypeAdapter
扩展类型适配器{
私人最终Gson Gson;
专用PackedJsonTypeAdapter(最终Gson Gson){
this.gson=gson;
}
@凌驾
public void write(最终JsonWriter out,最终字符串json){
最终的JsonElement=gson.fromJson(json,JsonElement.class);
toJson(jsonElement,out);
}
@凌驾
公共字符串读取(中的最终JsonReader){
final JsonElement JsonElement=gson.fromJson(in,JsonElement.class);
返回jsonElement!=null?jsonElement.toString():null;
}
}
}
请注意,此转换器策略是作为类型适配器工厂实现的,因为这是访问我所知的
Gson
实例的唯一方法,而且
JsonSerializer
/
JsonDeserializer
似乎无法通过序列化上下文进行良好的解析。这里的另一个陷阱是,这个实现是基于树的,需要将JSON树完全存储在内存中。理论上,可以有一个很好的面向流的实现,比如说
gson.fromJson(jsonReader)->jsonReader
,或者一个
jsonReader
->
Reader
装饰器被重定向到
StringWriter
,但我很长一段时间都找不到任何替代方案

publicstaticvoidmain(最终字符串…args){
最终Gson Gson=新Gson();
out.println(“反序列化:”);
最后一个字符串incomingJson=“{someString:\'theanswer\”,somesint:43,clientData:{x:[1,1,2,3,5,8,13],y:[1,1,2,6,24120],tonsoffomplexeddstuff:{stuff:stuff}”;
final MyEntity MyEntity=gson.fromJson(incomingJson,MyEntity.class);
out.println(“\t”+myEntity.someString);
out.println(“\t”+myEntity.someInt);
out.println(“\t”+myEntity.clientData);
out.println(“序列化:”);
最终字符串outgoingJson=gson.toJson(myEntity);
out.println(“\t”+outgoingJson);
out.println(“相等检查”);
out.println(“\t”+areEqual(gson,incomingJson,outgoingJson));
}
私有静态布尔值areEqual(最终Gson Gson、最终字符串incomingJson、最终字符串outgoingJson){
final JsonElement incoming=gson.fromJson(incomingJson,JsonElement.class);
final JsonElement outgoing=gson.fromJson(outgoingJson,JsonElement.class);
返回传入。等于(传出);
}
输出:

deserialization:  
    The answer  
    43  
    {"x":[1,1,2,3,5,8,13],"y":[1,1,2,6,24,120],"tonsOfComplicatedStuff":{"stuff":"stuff"}}  
serialization:  
    {"someString":"The answer","someInt":43,"clientData":{"x":[1,1,2,3,5,8,13],"y":[1,1,2,6,24,120],"tonsOfComplicatedStuff":{"stuff":"stuff"}}}  
equality check:  
    true  
不过,我不知道它是否能很好地与Hibernate配合使用


编辑 尽管JSON压缩字符串被收集到内存中,但由于各种原因,流式传输可能更便宜,并且可以节省一些内存。流式传输的另一个优点是,这样的JSON打包类型适配器不再需要类型适配器工厂,
Gson
实例因此保持JSON流的原样,但是仍然进行一些规范化,如
{stuff:stuff}
->
{“stuff”:“stuff”}
。例如:

@JsonAdapter(PackedJsonStreamTypeAdapter.class)
字符串clientData;
final class PackedJsonStreamTypeAdapter
扩展类型适配器{
私有PackedJsonStreamTypeAdapter(){
}
@凌驾
public void write(最终JsonWriter out,最终字符串json)
抛出IOException{
@抑制警告(“资源”)
最终读取器=新的StringReader(json);
writeNormalizedJsonStream(新JsonReader(reader),输出);
}
@凌驾
公共字符串读取(中的最终JsonReader)
抛出IOException{
@抑制警告(“资源”)
最终编写器=新的StringWriter();
writeNormalizedJsonStream(in,新JsonWriter(writer));
返回writer.toString();
}
}
final类JsonStreams{
私有JsonStreams(){
}
静态void writernomalizedjsonstream(最终JsonReader读取器,最终JsonWriter写入器)
抛出IOException{
writeNormalizedJsonStream(读者、作者、真实);
}
@抑制警告(“资源”)
静态void writernomalizedjsonstream(最终JsonReader读取器、最终JsonWriter写入器、最终布尔isLenient)
抛出IOException{
智力水平=0;
for(JsonToken-token=reader.peek();
deserialization:  
    The answer  
    43  
    {"x":[1,1,2,3,5,8,13],"y":[1,1,2,6,24,120],"tonsOfComplicatedStuff":{"stuff":"stuff"}}  
serialization:  
    {"someString":"The answer","someInt":43,"clientData":{"x":[1,1,2,3,5,8,13],"y":[1,1,2,6,24,120],"tonsOfComplicatedStuff":{"stuff":"stuff"}}}  
equality check:  
    true