我已经定义了一个自定义编解码器,将教程作为参考 - https://docs.datastax.com/en/latest-java-driver/java-driver/reference/customCodecs.html。这是我的编解码器要求: -
package org.questqa.server.database.codecs;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import org.questqa.server.database.fetchers.UserInfoFetcher;
import org.questqa.server.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import com.datastax.driver.core.DataType;
import com.datastax.driver.core.ProtocolVersion;
import com.datastax.driver.core.TypeCodec;
import com.datastax.driver.core.exceptions.InvalidTypeException;
public class UserCodec extends TypeCodec<User>
{
@Autowired
UserInfoFetcher userFetcher;
public UserCodec(DataType cqlType, Class<User> javaClass)
{
super(cqlType, javaClass);
}
@Override
public User deserialize(ByteBuffer buffer, ProtocolVersion arg1) `throws InvalidTypeException {`
// TODO Auto-generated method stub
System.out.println("Executing deserialize");
User user = new User();
try {
System.out.println("Size of ByteBuffer: " + `buffer.array().length);`
String userId = new String(buffer.array(), "UTF-8");
System.out.println("User id to set: " + userId);
System.out.println("Setting user id...");
user.setUserId(userId);
System.out.println("User id set: " + user.getUserId());
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return user;
}
@Override
public String format(User user) throws InvalidTypeException
{
System.out.println("Executing format");
return user.getUserId();
}
@Override
public User parse(String userId) throws InvalidTypeException
{
// TODO Auto-generated method stub
System.out.println("Executing parse");
User user = new User();
user.setUserId(userId);
return user;
}
@Override
public ByteBuffer serialize(User user, ProtocolVersion arg1) throws `InvalidTypeException {`
// TODO Auto-generated method stub
System.out.println("Executing serialize");
ByteBuffer buffer = null;
System.out.println("Userid to serialize: " + user.getUserId());
try {
buffer = ByteBuffer.wrap(user.getUserId().getBytes("UTF-8"));
String bufferStr = new String(buffer.array(), "UTF-8");
System.out.println("ByteBuffer to be returned: \nLength: " + `buffer.array().length +`
"\nValue: " + bufferStr);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return buffer;
}
}
基本上,在serialize方法中,我正在尝试提取userId字符串(使用user.getUserId()),然后将其作为用户ID字符串存储在我的cassandra表中。在反序列化中,我只是将给定的ByteBuffer实例转换为字符串并返回它。 这在序列化时对字符串,集合和列表完全正常(即,如果我有一个Set,则编解码器对集合的每个单独元素执行serialize()并将相应的字符串存储在我的casandra表中)。但是,在对cassandra中的set字段进行反序列化时,deserialize方法会在ByteBuffer对象中发送整个集合。通过分析ByteBuffer对象,我可以看到各个元素都在那里。请注意,对集合的每个元素执行反序列化。因此,如果集合有5个元素,则反序列化执行5次,但每次,而不是发送ByteBuffer中的特定元素,它会发送整个集合。 所以,我不明白为什么这样做,谷歌没有太大的帮助。任何建议/解决方案都是最受欢迎的,因为我已经坚持了很长一段时间。
谢谢!
答案 0 :(得分:2)
AbstractCollectionCodec
是SetCodec
和ListCodec
用于序列化/反序列化集合的内容。在反序列化时,它们传递位于元素开始位置的整个ByteBuffer
(ByteBuffer.position()
),并将单个元素(ByteBuffer.limit()
)的末尾限制为基础元素编解码器(在此情况1}})。
当您致电UserCodec
时,您将获得buffer.array()
的整个支持数组,无论其位置或限制如何。
对你来说更好的方法是使用Bytes.getArray(ByteBuffer)
为ByteBuffer
和limit
之间的数据返回一个字节数组,即:
position
由于您只是将@Override
public User deserialize(ByteBuffer buffer, ProtocolVersion arg1) `throws InvalidTypeException {`
// TODO Auto-generated method stub
System.out.println("Executing deserialize");
User user = new User();
try {
byte[] data = Bytes.toArray(buffer);
System.out.println("Size of ByteBuffer: " + data.length);
String userId = new String(data, "UTF-8");
System.out.println("User id to set: " + userId);
System.out.println("Setting user id...");
user.setUserId(userId);
System.out.println("User id set: " + user.getUserId());
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return user;
}
实例存储在C *中作为表示其User
的字符串,您可以做的是从extras模块创建一个MappingCodec
的实例,映射getUserId()
,即:
User <-> String (UserId)
您可以详细了解import com.datastax.driver.core.TypeCodec;
import com.datastax.driver.extras.codecs.MappingCodec;
public class UserCodec extends MappingCodec<User, String> {
public UserCodec() {
super(TypeCodec.varchar(), User.class);
}
@Override
protected User deserialize(String userId) {
return new User(userId);
}
@Override
protected String serialize(User user) {
return user.getUserId();
}
}
on the docs site。