我如何告诉groovy/grails不要尝试;重新编码;二进制数据?(修订标题)

我如何告诉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

我有一个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 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()
}