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);
}
精彩评论