Java Wicket AjaxLink和RequestHandler-如何?
使用场景:用户点击网站上的一个链接,就会得到动态生成的德语和英语两种语言的PDF。
此代码可以工作。GenerateCouponPdfOnClick创建包含PDF文件的ResourceStreamRequestHandler。
Link<Void> generatePdf = new Link<Void>("generatePdf") {
@Override
public void onClick() {
ResourceStreamRequestHandler requestHandler = generateCouponPdfOnClick(coupon, PDFLanguage.GERMAN);
getRequestCycle().scheduleRequestHandlerAfterCurrent(requestHandler);
}
};
现在我想更改代码以获得弹出窗口(Wicket ModalWindow,这里的类为PdfDialogPage),用户可以通过点击两个按钮中的一个来选择PDF的语言(德语/英语)。如果用户单击按钮,则应该关闭ModalWindow,并且应该生成并显示PDF。
以下是修改后的代码:变量pdflanguageanguage包含选定的语言,由PdfDialogPage使用PageReferenz设置
AjaxLink<Void> generatePdf = new AjaxLink<Void>("generatePdf") {
@Override
public void onClick(final AjaxRequestTarget target) {
modalWindow.setPageCreator(() -> {
return new PdfDialogPage(getPage().getPageReference(), modalWindow);
});
modalWindow.setWindowClosedCallback((AjaxRequestTarget target1) -> {
ResourceStreamRequestHandler requestHandler = generateCouponPdfOnClick(coupon, pdflanguageanguage);
getRequestCycle().scheduleRequestHandlerAfterCurrent(requestHandler);
});
modalWindow.show(target);
};
当我单击该链接时,将打开modal窗口。我选择语言,例如英语,在将"English"写入变量pdflanguageanguage时,modalWindow关闭。总比什么都没发生要好。并且不会生成该PDF。Wicket AJAX调试窗口告诉我以下日志:
</head>]]></header-contribution><evaluate><![CDATA[(function(){var settings = {"minWidth":200,"minHeight":200,"className":"w_blue","width":400,"height":100,"resizable":true,"src":"./wicket/page?6","mask":"semi-transparent","autoSize":false,"unloadConfirmation":true,"onClose":function() { Wicket.Ajax.ajax({"u":"./overviewCoupons?5-1.1-panel-modalWindow","c":"modalWindowb0"}); },"onCloseButton":function() { Wicket.Ajax.ajax({"u":"./overviewCoupons?5-1.0-panel-modalWindow","c":"modalWindowb0"});; return false; }};window.setTimeout(function(){
Wicket.Window.create(settings).show();
}, 0);
})();]]></evaluate></ajax-response>
INFO: returned focused element: javascript:;
INFO: returned focused element: javascript:;
INFO: Response processed successfully.
INFO: refocus last focused component not needed/allowed
INFO: focus removed from generatePdf5
INFO: focus set on _wicket_window_3
INFO: focus set on undefined
INFO: focus removed from undefined
ERROR: Wicket.Ajax.Call.failure: Error while parsing response: Error: Invalid XML: %PDF-1.4 %����
1 0 obj
<<
/Creator (Apache FOP Version 2.3)
/Producer (Apache FOP Version 2.3)
/CreationDate (D:20180808160110+02'00')
我认为AJAX和"getRequestCycle().scheduleRequestHandlerAfterCurrent(requestHandler);".之间存在问题我如何将它们一起使用。因此我将代码减少为:
AjaxLink<Void> generatePdf = new AjaxLink<Void>("generatePdf") {
@Override
public void onClick(final AjaxRequestTarget target) {
ResourceStreamRequestHandler requestHandler = generateCouponPdfOnClick(coupon, PDFLanguage.ENGLISH);
getRequestCycle().scheduleRequestHandlerAfterCurrent(requestHandler);
}
};
当我知道单击AjaxLink时,什么也不会发生,但我得到相同的AJAX日志错误输出。
如何将AjaxLink与ResourceStreamRequestHandler一起使用?
解决方案
我用这种方式解决了一个与您类似的用例。
您需要here中的Java类AjaxDownload
或者,您也可以使用My Variant,它接受FileResourceStream
作为输入。
import lombok.extern.slf4j.Slf4j;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.AbstractAjaxBehavior;
import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler;
import org.apache.wicket.request.resource.ContentDisposition;
import org.apache.wicket.util.resource.FileResourceStream;
/**
* @author Sven Meier
* @author Ernesto Reinaldo Barreiro (reiern70@gmail.com)
* @author Jordi Deu-Pons (jordi@jordeu.net)
*/
@Slf4j
public class AJAXDownload extends AbstractAjaxBehavior {
private boolean addAntiCache;
private FileResourceStream fileResourceStream;
private String fileName;
public AJAXDownload() {
this(true);
}
public AJAXDownload(boolean addAntiCache) {
super();
this.addAntiCache = addAntiCache;
}
/**
* Call this method to initiate the download.
*/
public void initiate(AjaxRequestTarget target, FileResourceStream fileResourceStream, String fileName) {
this.fileResourceStream= fileResourceStream;
this.fileName = fileName;
String url = getCallbackUrl().toString();
if (addAntiCache) {
url = url + (url.contains("?") ? "&" : "?");
url = url + "antiCache=" + System.currentTimeMillis();
}
// the timeout is needed to let Wicket release the channel
target.appendJavaScript("setTimeout("window.location.href='" + url + "'", 100);");
}
public void onRequest() {
try{
ResourceStreamRequestHandler handler = new ResourceStreamRequestHandler(fileResourceStream, fileName);
handler.setContentDisposition(ContentDisposition.ATTACHMENT);
getComponent().getRequestCycle().scheduleRequestHandlerAfterCurrent(handler);
} catch (Exception e){
log.error("Error while trying to download", e);
onErrorOccurred();
}
}
protected void onErrorOccurred(){}
}
如何使用?
您必须将AjaxDownload添加到您的表单
form.add(ajaxDownload = new AJAXDownload());
在通过AjaxLink提交的onSubmit中,您可以调用:
File yourPdfFile = //create your pdf file; final FileResourceStream resourceStream= new FileResourceStream(yourPdfFile); ajaxDownload.initiate(target, resourceStream, "yourPDF.pdf");
相关文章