這將是一個很長的帖子
好吧,我將發佈兩種解決方案 - 使用和不使用AJAX。如果我正確理解你,你想提交一個參數的表單並啓動文件下載,保留在同一頁面上以便能夠輸入不同的參數並重新提交表單。
請求/響應處理(無Ajax)。
在我的意見中,我建議你使用另一個servlet,但你可以通過處理表格onSubmit
方法來避免這種情況。我會假設你知道如何設置outputStream來響應,並會隱藏這個實現。
首先,你在Java有一個頁面或面板採用了形式:
public class HomePage extends WebPage {
/*input text of the input field. (your ID).*/
private String input;
....
/*initialization method, called from constructor(or place this in constructor).*/
private void init()
{
/*Form with overrided onSubmit method. Has Void generic, because doesn't map any object as a model.*/
Form<Void> form = new Form<Void>("form")
{
@Override
protected void onSubmit() {
/*This is the case. You can get request and response from RequestCycle, but you have to cast them (response at least) to WebRequest/WebResponse, to access required methods.*/
/*----------------------------------------------------*/
WebRequest req = (WebRequest)RequestCycle.get().getRequest();
WebResponse resp = (WebResponse)RequestCycle.get().getResponse();
/* Get request parameter. Id of the parameter is equals to text field id. Also you can check to null or emptyness of the parameter here. */
String idParameter = req.getPostParameters().getParameterValue("input").toString();
...
/* Creating file or your implementation of the stream */
File file = ...;
/* Use proper content type for each file. */
resp.setContentType("application/pdf");
resp.addHeader("Content-Disposition", "attachment; filename=" + fileName);
resp.setContentLength((int) file.length());
FileInputStream fileInputStream = ...
...
/* Write file to response */
while ((bytes = fileInputStream.read()) != -1) {
responseOutputStream.write(bytes);
}
...
/*That's all.*/
}
};
/* Add TextField to form and set PropertyModel for this field.*/
form.add(new TextField<String>("input", new PropertyModel<String>(this, "input")));
/* Don't forget to add form itself */
add (form);
}
}
在HTML:
...
<!-- You can also specify target="_blank" parameter for form-->
<form wicket:id="form">
<input type="text" wicket:id="input" />
</form>
...
你甚至不需要提交按鈕,可以在文本輸入後按Enter鍵。就這樣。
Ajax處理。
首先,您需要實現AJAXDownload類。這是非常普遍的類,我想知道爲什麼它不包含在一個標準的wicket庫中。它的實現你可以看看here。沒有太多的代碼。
好了,現在,使用相同的頁面類,只是在Java更新init方法:
private void init() {
final AJAXDownload download = new AJAXDownload() {
@Override
protected IResourceStream getResourceStream() {
/*Implementing resource according to input ID*/
return createResourceStream(input);
}
};
add (download);
/*Now, we don't override form, but use AjaxButton instead*/
Form<Void> form = new Form<Void>("form");
form.add(new TextField<String>("input", new PropertyModel<String>(this, "input")));
/*Every button has onSubmit method. And AjaxButton has it's implementation with AjaxRequestTarget instance, which allows to update any component via ajax.*/
form.add(new AjaxButton("submit", Model.of("Submit"), form) {
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
/*Initiate download according to AJAXDownload api*/
download.initiate(target);
}
});
add(form);
}
/*Method to implement wicket IResourceStream*/
private IResourceStream createResourceStream(String input) {
return new FileResourceStream(new File(...));
}
請注意,您也可以覆蓋AJAXDownload
類getFileName
方法。
更新。忘了補充HTML變化:
<form wicket:id="form">
<input type="text" wicket:id="input" />
<input type="submit" wicket:id="submit" />
</form>
我已經通過檢票6.17測試每一個實現,它的工作。希望它能幫助你。
並告訴我,如果這不是你想要的。
我懷疑這是不是真的可行的,因爲一個HTTP請求只能(正常),後跟一個響應,這應該是表單頁面或下載。然而,你可能會做的事情是用頁面進行響應,但頁面中的Javascript會觸發下載。 – biziclop 2014-09-23 17:37:46
不明白爲什麼不使用ajax?實現AJAXDownload並將AjaxButton設置爲表單的提交按鈕。它不會響應另一個頁面,並允許您根據表單輸入無限更改要下載的文件。或者我錯過了什麼? – 2014-09-23 18:14:44
我真的需要Ajax嗎?如果我使用純Java-Servlets,則只使用servletResponse.getOutputStream()並將該文件直接寫入響應中。原始網站保留。我如何使用Wicket做到這一點? – shylynx 2014-09-24 08:08:26