Tapestry:在 onSuccess() 中发布后重定向弄乱了我的 StreamResponse

发布于 2024-12-03 05:52:45 字数 1579 浏览 4 评论 0原文

在表单发布中,用户上传文件,我读取该文件,对其进行处理并发回 CSV(StreamResponse)。我在传回结果时遇到问题。在 Firebug 中,我看到帖子响应为“302 暂时移动”,并且我的页面再次重新加载,但没有显示流回文件。我认为 Tapestry 的重定向后使页面重新加载,而不是流回我发送的文件。这是正在发生的事情吗?我该如何克服这个问题?将不胜感激任何帮助!

这是我的代码:(

将其缩减为主要部分)

@Log 
StreamResponse onSuccess() throws IOException {
    File tmpFile = File.createTempFile(urlFile.getFileName(), null); 
    BufferedWriter br = new BufferedWriter(new FileWriter(tmpFile)); 
    br.append("something to test\nAnother line to test"); 
    br.flush(); 
    br.close(); 
    return new CsvStreamResponse(new FileInputStream(tmpFile.getAbsolutePath()), "results_file"); 
} 

public class CsvStreamResponse implements StreamResponse { 
    private InputStream is; 
    private String filename; 

    public CsvStreamResponse(InputStream is, String filename) { 
        this.is = is; 
        this.filename = filename; 
    } 

    public String getContentType() { 
        return "text/csv"; 
    } 

    public InputStream getStream() throws IOException { 
        return is; 
    } 

    public void prepareResponse(Response response) { 
        response.setHeader("Content-Disposition", "attachment; filename=" + filename + ".csv"); 
    } 
} 

我的 TML

<form t:type="form" t:id="analysis">
    <t:upload t:id="urlFile" class="marginRight" validate="required"/>
    <t:submit class="marginRight white button medium" value="${message:button.upload}" t:id="upload"/>
</form>

In a form post the user uploads a file, I read the file, process it and send back a CSV (StreamResponse). I am facing a problem streaming back the results. In Firebug I see the post response as '302 Moved Temporarily' and my page reloads again without showing the streamed back file. I think tapestry's redirect-after-post is making the page reload instead of streaming back the file i send. Is this what is happening? How do i overcome this? Would appreciate any help!

Here is my code:

(cut it down just to the main part)

@Log 
StreamResponse onSuccess() throws IOException {
    File tmpFile = File.createTempFile(urlFile.getFileName(), null); 
    BufferedWriter br = new BufferedWriter(new FileWriter(tmpFile)); 
    br.append("something to test\nAnother line to test"); 
    br.flush(); 
    br.close(); 
    return new CsvStreamResponse(new FileInputStream(tmpFile.getAbsolutePath()), "results_file"); 
} 

public class CsvStreamResponse implements StreamResponse { 
    private InputStream is; 
    private String filename; 

    public CsvStreamResponse(InputStream is, String filename) { 
        this.is = is; 
        this.filename = filename; 
    } 

    public String getContentType() { 
        return "text/csv"; 
    } 

    public InputStream getStream() throws IOException { 
        return is; 
    } 

    public void prepareResponse(Response response) { 
        response.setHeader("Content-Disposition", "attachment; filename=" + filename + ".csv"); 
    } 
} 

My TML

<form t:type="form" t:id="analysis">
    <t:upload t:id="urlFile" class="marginRight" validate="required"/>
    <t:submit class="marginRight white button medium" value="${message:button.upload}" t:id="upload"/>
</form>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

铁憨憨 2024-12-10 05:52:45

我以前从未遇到过从表单处理程序返回 StreamResponse 的情况。如果你问我的话,这是一个非常有效的情况,所以这应该是可能的。查看 API,您会注意到 Response 有一个 setStatus(int sc) 方法。我还没有测试过它,但如果您将 prepareResponse() 方法更改为以下内容,它应该可以工作:

public void prepareResponse(Response response) { 
    response.setStatus(HttpServletResponse.SC_OK);
    response.setHeader("Content-Disposition", "attachment; filename=" + filename + ".csv"); 
}

免责声明:我自己还没有尝试过。

I've never encountered this before where you return a StreamResponse from a form handler. A very valid situation if you ask me so it should be possible. Checking out the API you'll notice that Response has a setStatus(int sc) method. I have not tested it but if you alter your prepareResponse() method to the following, it should work:

public void prepareResponse(Response response) { 
    response.setStatus(HttpServletResponse.SC_OK);
    response.setHeader("Content-Disposition", "attachment; filename=" + filename + ".csv"); 
}

disclaimer: I have not tried this myself.

你又不是我 2024-12-10 05:52:45

Tapestry 将在发布后重定向,因此在发布时返回 StreamResponse 不是一个好主意。返回一个触发事件的Link。当 Tapestry 重定向到事件 URL 时,您可以返回 StremResponse

@Inject
private ComponentResources resources;

Link onSuccess() {
    String fileName = urlFile.getFileName();
    return resources.createEventLink("doCsv", fileName);
}

StreamResponse onDoCsv(String fileName) {
    return new CsvStreamResponse(fileName);
}

Tapestry will redirect after post so returning a StreamResponse on post is not a good idea. Return a Link which fires an event. When tapestry redirects to the event URL, then you can return the StremResponse.

@Inject
private ComponentResources resources;

Link onSuccess() {
    String fileName = urlFile.getFileName();
    return resources.createEventLink("doCsv", fileName);
}

StreamResponse onDoCsv(String fileName) {
    return new CsvStreamResponse(fileName);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文