我如何告诉groovy/grails不要尝试;重新编码;二进制数据?(修订标题)
我有一个groovy/grails应用程序需要提供图像服务 它在我的开发设备上运行良好,图像返回正确。下面是返回的JPEG的开始,如od-cx所示我如何告诉groovy/grails不要尝试;重新编码;二进制数据?(修订标题),grails,groovy,jpeg,Grails,Groovy,Jpeg,我有一个groovy/grails应用程序需要提供图像服务 它在我的开发设备上运行良好,图像返回正确。下面是返回的JPEG的开始,如od-cx所示 0000000 377 330 377 340 \0 020 J F I F \0 001 001 001 001 , d8ff e0ff 1000 464a 4649 0100 0101 2c01 但在生产箱上,前面有一些垃圾,1000之前的d8ff e
0000000 377 330 377 340 \0 020 J F I F \0 001 001 001 001 ,
d8ff e0ff 1000 464a 4649 0100 0101 2c01
但在生产箱上,前面有一些垃圾,1000之前的d8ff e0ff不见了
0000000 � ** ** � ** ** � ** ** � ** ** \0 020 J F
bfef efbd bdbf bfef efbd bdbf 1000 464a
0000020 I F \0 001 001 001 \0 H \0 H \0 \0 � ** ** �
4649 0100 0101 4800 4800 0000 bfef efbd
这是完全相同的代码。我只是把战争转移到另一台机器上运行。(Java不是应该只写一次,到处运行吗?)
有什么想法吗?“编码”问题
将代码发送到响应,如下所示:
response.contentType = "image/jpeg"; response.outputStream << out;
response.contentType=“image/jpeg”;response.outputStream
“编码”问题
当然。序列“bfef efbd bdbf bfef efbd bdbf”实际上是U+FFFD替换字符代码点的(小端)UTF-8的4个重复。因此,在某种程度上,二进制数据被解释为UTF-8字符数据,当然它不是有效的UTF-8
几乎可以肯定,您的产品盒使用UTF-8作为平台默认编码,而开发盒使用双射ISO-8859编码
但这里的问题不是使用平台默认编码。问题是二进制数据被转换为字符数据并返回。这几乎肯定是你的代码的错误。如何读取图像/创建并填写out
变量
编辑:
看看代码,似乎没有任何明显的错误。但是我对那些移位运算符以及Groovy的类型处理和隐式转换有点怀疑,它们与OutputStream
的重载leftShift()
方法有关。要找出问题所在,请尝试查看ByteArrayOutputStream的内容,以及直接从应用服务器读取第一个字节,以查看到底哪里出了问题
或者问题可能更进一步——IIRC,groovy使用sitemesh提供模块化布局。也许这就是罪魁祸首,试图将控制器的输出解析为HTML。不过,我不知道如何关闭它。我已经修好了
非常感谢Michael Borgwardt,他为我指明了正确的方向
我改变了这一点:
if (request.method == 'HEAD')
{ render( text : "", contentType : "image/jpeg" ); }
else {
response.contentType = "image/jpeg"; response.outputStream << out;
}
if(request.method==“HEAD”)
{呈现(文本:,内容类型:,图像/jpeg”);}
否则{
response.contentType=“image/jpeg”;response.outputStream谢谢,Michael!我将更新问题,提供更多的代码片段,以便您可以看到我在做什么。只有当contentType为text/html时,Sitemesh才会干扰。请参阅web app/web-INF/Sitemesh.xml来配置contentType Sitemesh的作用。我写了一个小“dump”打印流的前8个字节的操作:def b=out.toByteArray()render sprintf(“%02x、%02x、%02x、%02x、%02x、%02x、%02x\n”、b[0]、b[1]、b[2]、b[3]、b[4]、b[5]、b[6]、b[7])它们是JPEG头的前8个字节。科林:我认为这不是sitemesh。它看起来被配置为只解析内容类型为“text/html”的页面。我知道我为我的图像设置的内容类型已被处理,因为firebug将内容类型显示为image/jpegAh,因此看起来过载的操作符确实是罪魁祸首。显然,由于out变量没有声明类型,编译器决定使用leftShift()版本,该版本接受对象参数并对其调用toString(),对于ByteArrayOutputStream,该版本使用平台默认编码。因此,另一种解决方法是声明变量的类型。再次感谢您,Michael!现在一切都有了意义。我想我将是非Groovy的,并且为我知道的类型声明类型。这会使我免于麻烦
response.setCharacterEncoding("ISO-8859-1");
if (request.method == 'HEAD')
{ render( text : "", contentType : "image/jpeg" ); }
else {
response.contentType = "image/jpeg;charset=ISO-8859-1"; response.outputStream << out;
}
if (request.method == 'HEAD')
{ render( text : "", contentType : "image/jpeg" ); }
else {
response.contentType = "image/jpeg"; response.outputStream << out;
}
if (request.method == 'HEAD')
{ render( text : "", contentType : "image/jpeg" ); }
else {
response.contentType = "image/jpeg"; response.outputStream << out.toByteArray()
}