I am new to Ktor and am currently working on a project where I want to use blobs to store user's avatar images. Now there seems to be no decent documentation on how to achieve this.
As there is no default serializer for ExposedBlob I thought I could try to do this with the same approach I use for LocalDate serialization:
@Serializable
data class ExposedUser(
// other fields
@Serializable(with = ExposedBlobSerializer::class)
val avatarImage: ExposedBlob,
// other fiels
)
This is my ExposedBlobSerializer:
class ExposedBlobSerializer : KSerializer<ExposedBlob> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("ExposedBlob", PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: ExposedBlob) {
val bytes = value.bytes
encoder.encodeString(Base64.getEncoder().encodeToString(bytes))
}
override fun deserialize(decoder: Decoder): ExposedBlob {
val base64String = decoder.decodeString()
val bytes = Base64.getDecoder().decode(base64String)
return ExposedBlob(bytes)
}
}
So far I can store images into the database, but reading them (e.g. via GET-Request) throws this error:
DEBUG ktor.application - Unhandled: GET - /users. Exception class java.io.IOException: mark/reset not supported
java.io.IOException: mark/reset not supported
at java.base/java.io.InputStream.reset(InputStream.java:733)
at java.base/java.io.FilterInputStream.reset(FilterInputStream.java:234)
at org.jetbrains.exposed.sql.statements.api.ExposedBlob.getBytes(ExposedBlob.kt:8)
...
How do I resolve this? Or should I try using a different approach? Or in general: How to serialize / de-serialize Blob Images for network transfer (get / post requests)? I am thankful for every bit of information, especially documentation or tutorials if you guys know some. Thanks <3
For anyone interested in this, the issue was this line in ExposedBlobSerializer:
val bytes = value.bytes
which apparently reads a single byte. Use this instead:
val bytes = value.inputStream.readAllBytes()