我已经将我的 Play2+Scala 应用程序连接到Sendgrid Parse Api并且我在解码和编码电子邮件的内容方面非常努力。
由于电子邮件可能采用不同的编码,Sendgrid 为我们提供了 JSON 对象字符集:
{"to":"UTF-8","cc":"UTF-8","subject":"UTF-8","from":"UTF-8","text":"iso-8859-1","html":"iso-8859-1"}
在我的测试用例"text"
中,"Med Vänliga Hälsningar Jakobs Webshop"
如果我从多部分请求中提取并打印出来:
Logger.info(request.body.dataParts.get("text").get)
我得到:
Med V?nliga H?lsningar Jakobs Webshop
好的,使用来自 Sendgrid 的给定信息,让我们修复字符串,使其为UTF-8。
def parseMail = Action(parse.multipartFormData) {
request => {
val inputBuffer = request.body.dataParts.get("text").map {
v => ByteBuffer.wrap(v.head.getBytes())
}
val fromCharset = Charset.forName("ISO-8859-1")
val toCharset = Charset.forName("UTF-8")
val data = fromCharset.decode(inputBuffer.get)
Logger.info(""+data)
val outputBuffer = toCharset.encode(data)
val text = new String(outputBuffer.array())
// Save stuff to MongoDB instance
}
这导致:
Med V�nliga H�lsningar Jakobs Webshop
所以这很奇怪。这应该有效。我想知道正文解析器和数据部分处理程序中实际发生了什么 parse.multipartFormData
:
def handleDataPart: PartHandler[Part] = {
case headers @ PartInfoMatcher(partName) if !FileInfoMatcher.unapply(headers).isDefined =>
Traversable.takeUpTo[Array[Byte]](DEFAULT_MAX_TEXT_LENGTH)
.transform(Iteratee.consume[Array[Byte]]().map(bytes => DataPart(partName, new String(bytes, "utf-8")))(play.core.Execution.internalContext))
.flatMap { data =>
Cont({
case Input.El(_) => Done(MaxDataPartSizeExceeded(partName), Input.Empty)
case in => Done(data, in)
})
}(play.core.Execution.internalContext)
}
使用数据时,会使用编码 utf-8 创建一个新字符串:
.transform(Iteratee.consume[Array[Byte]]().map(bytes => DataPart(partName, new String(bytes, "utf-8")))(play.core.Execution.internalContext))
这是否意味着我的ISO-8859-1编码字符串文本在解析时使用 utf-8 编码?如果是这样,我应该如何创建我的解析器来解码,然后根据提供的 JSON 对象字符集对我的参数进行编码?显然我做错了什么,但我无法弄清楚!