Java ObjectMapper writeValueAsString更改bytebuffer pos
我试图通过使用ObjectMapper记录响应,将复杂对象序列化为包含bytebuffer的字符串。 这会更改bytebuffer中的光标位置,并简单地破坏响应 我正在使用的代码段:Java ObjectMapper writeValueAsString更改bytebuffer pos,java,Java,我试图通过使用ObjectMapper记录响应,将复杂对象序列化为包含bytebuffer的字符串。 这会更改bytebuffer中的光标位置,并简单地破坏响应 我正在使用的代码段: import org.codehaus.jackson.map.ObjectMapper; private static final ObjectMapper MAPPER = new ObjectMapper(); public static String serializeToString(final Ob
import org.codehaus.jackson.map.ObjectMapper;
private static final ObjectMapper MAPPER = new ObjectMapper();
public static String serializeToString(final Object obj) {
Preconditions.checkArgument(obj != null, "Object to be serialized is null");
try {
final String str = MAPPER.writeValueAsString(obj);
if (Strings.isNullOrEmpty(str)) {
log.warn("Serialized to null/empty string");
}
return str;
} catch (final JsonGenerationException e) {
throw new IllegalArgumentException("Json generation exception occured in de-serializing obj", e);
} catch (final JsonMappingException e) {
throw new IllegalArgumentException("Json mapping exception occured in de-serializing obj", e);
} catch (final IOException e) {
throw new IllegalArgumentException("IO exception occured in de-serializing obj", e);
}
}
我向上面的方法传递了一个包含bytebuffer的复杂对象。
我在调用上述方法之前和之后打印了bytebuffer
public static void main(final String[] args) throws SecurityException, NoSuchMethodException {
final String x =
"Random data i am using for this test for byte buffer. Random data i am using for this test for byte buffer";
final byte[] byteArr = x.getBytes();
final ByteBuffer bb = ByteBuffer.wrap(byteArr);
System.out.println("before bytebuffer :" + bb);
String stringData = SerializerUtil.serializeToString(bb); // In real i am passing a complex structure having
// bytebuffer inside
System.out.println(stringData);
System.out.println("after bytebuffer :" + bb);
}
输出:
before bytebuffer :java.nio.HeapByteBuffer[pos=0 lim=106 cap=106]
{"short":21089,"char":"\u6e64","int":1869422692,"long":7022344510808023405,"float":2.0790493E-19,"double":6.687717052371733E223,"direct":false,"readOnly":false}
after bytebuffer :java.nio.HeapByteBuffer[pos=28 lim=106 cap=106]
(pos=0到pos=28)位置的这种变化只会破坏发送的响应。我们有没有办法在不影响byteBuffer的情况下将这个复杂对象转换为字符串
非常感谢您的帮助。显然,您不想将
ByteBuffer
属性序列化为另一个结构化类,而只想将内容序列化为字符串。一种方法是在方法上使用@JsonProperty
注释来告诉映射器使用该方法,而不是尝试直接序列化字段。假设您有这样一个bean:
class Stuff {
private ByteBuffer data;
public Stuff() {
}
public Stuff(ByteBuffer data) {
super();
this.data = data;
}
public ByteBuffer getData() {
return data;
}
public void setData(ByteBuffer data) {
this.data = data;
}
@JsonProperty(value = "data")
public String convertData() {
return new String(data.array());
}
@JsonProperty("data")
public void convertData(String s) {
data = ByteBuffer.wrap(s.getBytes());
}
}
映射程序现在将使用convertData方法来序列化和反序列化ByteBuffer数据属性,您仍然可以使用普通的JavaBean属性方法
更新:
由于序列化类无法更改,这里有一个使用som advanced JACKSON stuff的替代方法。首先,创建自定义序列化程序和反序列化程序:
static class ByteBufferSerializer extends JsonSerializer<ByteBuffer> {
@Override
public void serialize(ByteBuffer value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
jgen.writeString(new String(value.array()));
}
}
static class ByteBufferDeserializer extends JsonDeserializer<ByteBuffer> {
@Override
public ByteBuffer deserialize(JsonParser jp,
DeserializationContext context) throws IOException,
JsonProcessingException {
return ByteBuffer.wrap(jp.getText().getBytes());
}
}
此外,创建用于配置对象映射器的模块,并添加mixin接口:
static class MyModule extends SimpleModule {
public MyModule() {
super("ByteBuffer wrangling");
}
@Override
public void setupModule(SetupContext context) {
context.setMixInAnnotations(Stuff.class, Mixin.class);
}
}
最后,向映射器注册模块:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new MyModule());
瞧,小菜一碟!:-) 感谢您的回复,但我的复杂响应对象是WSDL生成的,因此无法在ByteBuffer数据周围添加此JSON属性。WSDL中的ByteBuffer?是的,好吧,这是“创新”,如果没有别的。基本上我们称之为“blob”,但它是作为byteBuffer生成的,用于更平滑的数据传输。非常感谢,这完全符合我的要求。一些如何使用context.setMixinNotations(Stuff.class、Mixin.class);不适合我。我正在使用以下SimpleModule.addSerializer(ByteBuffer.class,新的ByteBufferSerializer());谢谢:)
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new MyModule());