【问题标题】:Characters not displaying properly with Struts2 file download使用 Struts2 文件下载无法正确显示字符
【发布时间】:2014-04-02 16:52:42
【问题描述】:

我正在使用 Struts2 文件下载从 AS400 服务器下载文件。我正在下载的文件具有 CCSID 37(ebcdic),当它下载到 PC 时它不显示任何内容,只是垃圾字符。当我在 AS400 服务器上显示它时,它显示得很好。请建议! 感谢您的帮助!

jsp形式:

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>File Download</title>
</head>
<body>
<s:form action="/execFileDownload">
<s:textfield key="serverFiletobeDownload" label="Server File"/>
<s:submit value="Download"/>
</s:form>
</body>
</html>

struts.xml

<struts>
    <constant name="struts.multipart.maxSize" value="2000000000" />
    <package name="default"  extends="struts-default">
    <action name="execFileDownload" class="utils.action.FileDownloadAction">
            <result name="success" type="stream">
                <param name="contentType">application/octet-stream</param>
                <param name="inputName">inputStream</param>
                <param name="contentDisposition">attachment;filename="${fileName}"</param>
                <param name="bufferSize">4096</param>

            </result>
    </action>
<struts> 

动作类:

public class FileDownloadAction extends ActionSupport {
    private static final long serialVersionUID = 1L;
    private InputStream inputStream;
    private long contentLength;
    private String fileName;
    public InputStream getInputStream() {
        return inputStream;
    }

    public long getContentLength() {
        return contentLength;
    }

    public String getFileName() {
        return fileName;
    }

    private String serverFiletobeDownload;

    public String getServerFiletobeDownload() {
        return serverFiletobeDownload;
    }

    public void setServerFiletobeDownload(String serverFiletobeDownload) {
        this.serverFiletobeDownload = serverFiletobeDownload;
    }

    public String execute() throws FileNotFoundException {
        File fileToDownload = new File(serverFiletobeDownload.trim());
        inputStream = new FileInputStream(fileToDownload);
        fileName = fileToDownload.getName();
        contentLength = fileToDownload.length();
        return SUCCESS;
    }
}

【问题讨论】:

  • 您是否检查了各个字符字段是否为 ccsid 37?
  • 我正在尝试复制 ifs 文件文本、pdf 等
  • 啊,是的。如果我阅读了您的代码,我可以看到这一点。
  • 如何“在 AS400 服务器上显示”?这可能会导致更多问题。
  • IFS 中的 PDF 的 CCSID 不应为 37。5348 或 1252 会更有意义。一个普通的 .TXT 可能有 37 的 CCSID。但您的下载过程必须翻译它。对于 .TXT 文件,系统可以配置为从某些接口自动翻译。但我不知道STRUTS 使用的是什么。我的猜测是它正在进行二进制下载。最好的解决方案是首先将文件输出为 ASCII。

标签: java jsp encoding struts2 ibm-midrange


【解决方案1】:

页面 contentType 和 meta contentType 标签实际上并不进行任何转换。他们只是简单地向客户端声明 HTTP 响应的预期编码。由您决定以适当的编码翻译/格式化输出。

我假设 /execFileDownload 正确返回 EBCDIC。尝试在浏览器中点击 /execFileDownload.do。这将返回您的操作决定流式传输的任何字节。您还应该考虑在该操作中设置适当的标题。 (同样,这只是声明您的代码已经在使用哪种编码!)

// declare EBCDIC encoding. be sure to do this before calling response.getWriter()
response.setCharacterEncoding("Cp1047");

response.setContentType("text/plain;charset=Cp1047");

如果你这样做,然后点击 /execFileDownload.do,支持的浏览器应该正确显示文本。 Internet Explorer 有效。火狐没有。 Chrome/其他人不知道。

我根本不明白 JSP 文件的用途。在您的示例中,没有人负责将字节从 EBCDIC 转换为 ASCII。在 Struts 或 Java 中没有自动执行此操作的内置功能。

cmets 中建议将其转换为“正常”字符编码,例如 cp819/iso-8859-1,这是一个好主意。这将为您提供更多渲染选项并支持多种浏览器。

需要帮助转换字节流?请参阅question 18170601 了解一下。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 1970-01-01
    • 2014-08-23
    • 2011-08-09
    • 2013-06-05
    • 1970-01-01
    相关资源
    最近更新 更多