简体   繁体   English

Java Wicket AjaxLink和RequestHandler-如何?

[英]Java Wicket AjaxLink and RequestHandler - How to?

Usage scenario: The user clicks on a link on a web site do get a dynamically generated PDF in both languages: German and English. 使用方案:用户单击网站上的链接,会获得两种语言(德语和英语)的动态生成的PDF。

This code works. 此代码有效。 generateCouponPdfOnClick creates a ResourceStreamRequestHandler containing a pdf file. generateCouponPdfOnClick创建一个包含pdf文件的ResourceStreamRequestHandler。

Link<Void> generatePdf = new Link<Void>("generatePdf") {
@Override
public void onClick() {
    ResourceStreamRequestHandler requestHandler = generateCouponPdfOnClick(coupon, PDFLanguage.GERMAN);
    getRequestCycle().scheduleRequestHandlerAfterCurrent(requestHandler);
}
};

Now I want to change the code to get a popup (Wicket Modalwindow, here class PdfDialogPage) where the user can select a language (German/English) for the PDF by klicking on one of the two buttons. 现在,我想更改代码以获取一个弹出窗口(Wicket Modalwindow,此处为PdfDialogPage类),用户可以通过单击两个按钮之一来为PDF选择一种语言(德语/英语)。 If the user clicks a button, the ModalWindow should close and the PDF should be build and displayed. 如果用户单击一个按钮,则应该关闭ModalWindow,并且应该构建并显示PDF。

Here is the modified code: The variable pdflanguageanguage contains the selected language and is set by the PdfDialogPage using the PageReferenz 这是修改后的代码:变量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);
};

When I click the link, the modalwindow opens. 当我单击链接时,将打开模态窗口。 I select the language, eg English, and the modalWindow closes while writing "English" to the variable pdflanguageanguage. 我选择语言,例如英语,然后在将“英语”写入变量pdflanguageanguage时关闭modalWindow。 Than nothing more happens ... and the PDF is not generated. 仅此而已...没有生成PDF。 The Wicket Ajax Debug Window tells me the follogwing logs: 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')

I believe that there is a problem between Ajax and "getRequestCycle().scheduleRequestHandlerAfterCurrent(requestHandler);". 我相信Ajax与“ getRequestCycle()。scheduleRequestHandlerAfterCurrent(requestHandler);”之间存在问题。 How do I use these together. 我如何一起使用这些。 So I reduced code to: 所以我将代码简化为:

AjaxLink<Void> generatePdf = new AjaxLink<Void>("generatePdf") {
@Override
public void onClick(final AjaxRequestTarget target) {
ResourceStreamRequestHandler requestHandler = generateCouponPdfOnClick(coupon, PDFLanguage.ENGLISH);
getRequestCycle().scheduleRequestHandlerAfterCurrent(requestHandler);
}
};

When I know click the AjaxLink, nothing happens but I get the same Ajax Log Error Output. 当我知道单击AjaxLink时,什么都没有发生,但是我得到了相同的Ajax日志错误输出。

How do I use AjaxLink together with ResourceStreamRequestHandler? 如何将AjaxLink与ResourceStreamRequestHandler一起使用?

I solved a similar use case like you have in this way. 我以这种方式解决了类似的用例。

You need the Java class AjaxDownload from here 您需要Java类AjaxDownload这里

Alternatively you can use my variation which takes a FileResourceStream as input. 或者,您可以使用将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(){}
}

How to use? 如何使用?

  1. you have to add the AjaxDownload to your Form 您必须将AjaxDownload添加到您的表单中

     form.add(ajaxDownload = new AJAXDownload()); 
  2. in your onSubmit from your AjaxLink you can call: 在AjaxLink的onSubmit中,您可以调用:

     File yourPdfFile = //create your pdf file; final FileResourceStream resourceStream= new FileResourceStream(yourPdfFile); ajaxDownload.initiate(target, resourceStream, "yourPDF.pdf"); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM