开发者

Tapestry: Redirect-after-post messing my StreamResponse in onSuccess()

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 Csv开发者_Python百科StreamResponse 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>


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.


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);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜