【发布时间】:2011-08-03 11:29:32
【问题描述】:
我正在使用 Grails 1.3.7。我有一些使用内置 base64Encode 函数和 base64Decode 函数的代码。在我编码一些二进制数据然后解码结果字符串并将其写入新文件的简单测试用例中,这一切都很好。在这种情况下,文件是相同的。
但后来我编写了一个 Web 服务,它将 base64 编码的数据作为 POST 调用中的参数。虽然 base64 数据的长度与我传递给函数的字符串相同,但 base64 数据的内容正在修改中。我花了几天时间对此进行调试,最后编写了一个测试控制器,该控制器将 base64 中的数据传递给 post,并使用正确的 base64 编码数据获取本地文件的名称,如下所示:
data=AAA-base-64-data...&testFilename=/name/of/file/with/base64data
在测试函数中,我将传入数据参数中的每个字节与测试文件中的相应字节进行了比较。我发现输入数据参数中的每个“+”字符都被替换为“”(空格,序数 ascii 32)。嗯?什么可以做到这一点?
为了确保我是正确的,我添加了一行内容:
data = data.replaceAll(' ', '+')
果然数据解码完全正确。我尝试使用任意长的二进制文件,现在每次都可以使用。但是我一生都无法弄清楚如何修改帖子中的数据参数以将 ord(43) 字符转换为 ord(32)?我知道加号是 base64 规范中两个与平台相关的字符之一,但鉴于我现在在同一台机器上进行编码和解码,我非常困惑是什么原因造成的。当然我有一个“修复”,因为我可以让它工作,但我对我不理解的“修复”感到紧张。
代码太大,无法在此处发布,但我得到的 base64 编码如下:
def inputFile = new File(inputFilename)
def rawData = inputFile.getBytes()
def encoded = rawData.encodeBase64().toString()
然后,我将该编码字符串写入新文件,以便以后可以使用它进行测试。如果我重新加载该文件,我会得到相同的 rawData:
def encodedFile = new File(encodedFilename)
String encoded = encodedFile.getText()
byte[] rawData = encoded.decodeBase64()
所以一切都很好。现在假设我采用“编码”变量并将其添加到 POST 函数的参数中,如下所示:
String queryString = "data=$encoded"
String url = "http://localhost:8080/some_web_service"
def results = urlPost(url, queryString)
def urlPost(String urlString, String queryString) {
def url = new URL(urlString)
def connection = url.openConnection()
connection.setRequestMethod("POST")
connection.doOutput = true
def writer = new OutputStreamWriter(connection.outputStream)
writer.write(queryString)
writer.flush()
writer.close()
connection.connect()
return (connection.responseCode == 200) ? connection.content.text : "error $connection.responseCode, $connection.responseMessage"
}
在 Web 服务端,在控制器中,我得到如下参数:
String data = params?.data
println "incoming data parameter has length of ${data.size()}" //confirm right size
//unless I run the following line, the data does not decode to the same source
data = data.replaceAll(' ', '+')
//as long as I replace spaces with plus, this decodes correctly, why?
byte[] bytedata = data.decodeBase64()
抱歉,长篇大论,但我真的很想了解为什么我必须执行“用加号替换空格”才能正确解码。在请求参数中使用加号是否有问题?
【问题讨论】:
标签: html grails encoding groovy base64