我正在尝试将用户上传的图像存储在我的应用程序中,该应用程序由scala和play framework 2.2.x编写 我在heroku中部署了我的应用程序。 Heroku不允许我将文件保存在文件系统中。 所以我试图将我的文件存储在数据库中。
这是我用来存储图像的代码:
def updateImage(id: Long, image: Array[Byte]) = {
val selected = getById(id)
DB.withConnection {
implicit c =>
SQL("update subcategory set image={image} where id = {id}").on('id -> id, 'image -> image).executeUpdate()
}
selected }
这是我用来检索我的图片的代码:
def getImageById(id: Long): Array[Byte] = DB.withConnection {
implicit c =>
val all = SQL("select image from subcategory where id = {id}").on('id -> id)().map {
case Row(image: Array[Byte]) => image
case Row(Some(image: Array[Byte])) => image
case Row(image: java.sql.Blob )=> image.getBytes(0 , image.length().toInt)
}
all.head
}
问题是:当我使用H2数据库和blob列时,我得到“匹配错误”异常。 当我使用Postgresql和bytea列时,我没有错误,但是当我检索图像时,它是十六进制格式,并且缺少数组开头的一些字节。
答案 0 :(得分:0)
根据PostgreSQL documentation,bytea
将数组的长度存储在数组开头的四个字节中。当您读取行时会删除它们,因此当您将Scala中的数据与数据库中的数据进行比较时,它们似乎“丢失”了。
如果您希望Web浏览器正确显示图像,则必须将响应的内容类型设置为适当的值,否则它不知道它正在接收图像数据。 Ok.sendFile
帮助程序为您完成。否则你将不得不手工完成:
def getPicture = Action {
SimpleResult(
header = ResponseHeader(200),
body = Enumerator(pictureByteArray))
.as(pictureContentType)
}
在上面的示例中,pictureByteArray
是包含数据库中图片数据的Array[Byte]
,pictureContentType
是包含相应内容类型的字符串(例如image/jpeg
})。
Play documentation中已经很好地解释了这一点。