使用GSON在JSON中序列化BufferedImages似乎存在问题。我正在使用Derby来存储图像。当我查询数据库时,我构建了一个包含一些文本字段和一个BufferedImage字段的JavaBean。然后我使用GSON将JavaBean转换为JSON,这就是发生异常的地方。
异常消息如下:
java.lang.IllegalArgumentException:class sun.awt.image.ByteInterleavedRaster声明了多个名为maxX的JSON字段
我确实在GSON java.lang.IllegalArgumentException: class 'xx' declares multiple JSON fields named 'XX' AND StackOverflowError和class A declares multiple JSON fields
找到了类似的问题但问题在于Java附带的awt库。如果我可以访问AWT源代码,我可以按照其他stackoverflow答案中提供的答案,但我该怎么做?
答案 0 :(得分:2)
您必须知道并非每个类都被设计为(反)序列化,特别是如果(反)序列化基于目标类二进制结构。你的方法至少有以下几点:
sun.awt.image.ByteInterleavedRaster
类字段在另一个JVM / JRE上不一定相同,因此您可以被供应商锁定; 考虑以下简单类:
final class ImageHolder {
final RenderedImage image;
ImageHolder(final RenderedImage image) {
this.image = image;
}
}
现在你必须创建一个类型适配器来告诉Gson如何存储和恢复特定的类型实例:
final class RenderedImageTypeAdapter
extends TypeAdapter<RenderedImage> {
private static final TypeAdapter<RenderedImage> renderedImageTypeAdapter = new RenderedImageTypeAdapter().nullSafe();
private RenderedImageTypeAdapter() {
}
static TypeAdapter<RenderedImage> getRenderedImageTypeAdapter() {
return renderedImageTypeAdapter;
}
@Override
@SuppressWarnings("resource")
public void write(final JsonWriter out, final RenderedImage image)
throws IOException {
// Intermediate buffer
final ByteArrayOutputStream output = new ByteArrayOutputStream();
// By the way, how to pick up the target image format? BMP takes more space, PNG takes more time, JPEG is lossy...
ImageIO.write(image, "PNG", output);
// Not sure about this, but converting to base64 is more JSON-friendly
final Base64.Encoder encoder = Base64.getEncoder();
// toByteArray() returns a copy, not the original array (x2 more memory)
// + creating a string requires more memory to create the String internal buffer (x3 more memory)
final String imageBase64 = encoder.encodeToString(output.toByteArray());
out.value(imageBase64);
}
@Override
public RenderedImage read(final JsonReader in)
throws IOException {
// The same in reverse order
final String imageBase64 = in.nextString();
final Base64.Decoder decoder = Base64.getDecoder();
final byte[] input = decoder.decode(imageBase64);
return ImageIO.read(new ByteArrayInputStream(input));
}
}
请注意,Gson目前还没有很好地支持字节转换,但如果修复,将来可能会somewhat better。
使用示例:
private static final Gson gson = new GsonBuilder()
.registerTypeHierarchyAdapter(RenderedImage.class, getRenderedImageTypeAdapter())
.create();
public static void main(final String... args)
throws IOException {
try ( final InputStream inputStream = getPackageResourceInputStream(Q43301580.class, "sample.png") ) {
final RenderedImage image = ImageIO.read(inputStream);
final ImageHolder before = new ImageHolder(image);
final String json = gson.toJson(before);
System.out.println(json);
final ImageHolder after = gson.fromJson(json, ImageHolder.class);
...
}
}
示例输出(内部有真正的小(32x32)PNG文件):
{&#34;图像&#34;:&#34; iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADgklEQVR42t2XXUiTYRTHpxj4kSKShhgYGSihZGIXXYhU5J2BhBIhCH5cCF6oiWhG0k1BpHghgRgoJHiloBKEqFQ3frDNuemaOqdu0 + n8mFM3Nzf37z1n + JZUEPlOoQdetvd5L87vOed / Ph4ZznnJzsqQz + UFZ + M5HwBrezuUFy9CERoKY3U1jtzuwAFY29pgGxgQ350aDVSXLmFfLud9eVAQTHV1gQNYKi + HMiwM9uFhft / o6MBcTg6fWp + XB93duzhyOOA7POSwyAIR64UnTxhi9 + tXfhQhIdBlZ2P2wQM2Tmv11StY3rwJjAYIQl9QAGVUFPZGRzF7 / z7kwcGw9ffzt80PHzAZE4ODuTnpAQ50OjgmJ3HkcmE + N5chdr98wfzDh5DLZPyo4uOx + / mz9Bqg + B8b0d6 + zSecFeJPInSo1XAbjXAKvxR / yUW4Pz7uV / vEBJ9OffUqNNev49BiYeGp4uLg0usDUwdIUNNpaTDV1op7rqUljvNKYyMLb7G4GIdWa2AAbH19LDIy8vNaefmSBRiQUkynMtXUYLGkBO7lZWx2dTEEnVjURFnZL1CSASyWlmL6xg1okpIwdeUK3CYTNjo7WYCGoiLOeU1yMtxmc2AA1NeuscA829uYTk1lEIJYf / eOIcgzP6tdEgAyRicjtatiY8V9EhdDpKTw / 7XmZoYgGEkBzEITIQDzs2dsYPX1a / EbuZq8YG5o8GeG8E2dmIgjp / P0AJxGgku1GRnYVyh479jVdFrRE + vrXGqPl3dvTxoPeO12aDMz2aBDqRT315qa / TRV / wTgsdmw1d3NJVSMs + BmOqlYhARXL1dUSA / gWljg9FKGh / u72tgYQ1BqEcjvqtqpAHY + fcLOx4 / + durzcTOxvH3LXY1qOUFQ / CnVyAszN2 + eGK1OBWCur4cyIgIrL17 4Xb + 1hdl79xiERioqOFRSKf3sQ0MclvXWVmk8sN3b6 + 9UBsMvQwWtb3fuwD4ywpkwlZDAojNWVUk3lhsrK7Hw + PHJ + AudzKnVwrOzwwYP5ud50JhJT5cs9iLAxvv3UFy4wLVdn58P1eXLP4YKIfWor09GR0MZGYm1lhbpLyYUZ / Pz55i5dQu6rCwYnz4FhYXmNjJKKbYmiHG7p + fsb0aGwkIsC2PWuVzNaJ5j1Q8Oni0AVTkKCbmffs / 8cuoVlK9 / 9IjHrP / qdvyn9R0SEM4flWsmCwAAAABJRU5ErkJggg \ u003d \ u003d&#34;}
我认为太多缺陷,我强烈建议您尽可能重新设计二进制文件存储并按原样存储二进制内容。