升级到SpringBoot 2.6和Wicket 9.8后,文件下载不再工作

thigvfpy  于 2022-12-13  发布在  Spring
关注(0)|答案(1)|浏览(109)

所以,我把一个应用程序从SpringBoot 2.1升级到2.6,Wicket 8.6升级到9.8,现在除了下载csv文件之外,一切都很好。这个文件被创建了,但是它不能被下载,我不知道该去哪里找,所以我将分享downloadbutton的类,下载本身和pom.xml。也许有人有办法。
pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.xyz.uof</groupId>
    <artifactId>uof</artifactId>
    <version>${revision}</version>
    <packaging>pom</packaging>

    <name>uof</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.4</version>
    </parent>

    <modules>
        <module>uof-app</module>
        <module>uof-common</module>
        <module>uof-database</module>
        <module>uof-endpoints</module>
        <module>uof-frontend</module>
        <module>uof-model</module>
        <module>uof-security</module>
        <module>uof-services</module>
        <module>uof-services-interfaces</module>
        <module>uof-transformation</module>
        <module>uof-selenium</module>
    </modules>

    <properties>
        <!-- Java -->
        <java.version>11</java.version>

        <!-- Wicket -->
        <version.wicket>9.8.0</version.wicket>
        <version.wicket-bootstrap>4.0.4</version.wicket-bootstrap>
        <wicket.verifier.dependencies.enabled>false</wicket.verifier.dependencies.enabled>
        <wicket.verifier.dependencies.throw-exception-on-dependency-version-mismatch>false</wicket.verifier.dependencies.throw-exception-on-dependency-version-mismatch>

        <!-- Other dependencies -->
        <version.apache.commons.lang>3.9</version.apache.commons.lang>
        <version.h2-database>1.4.200</version.h2-database>
        <version.iconic>1.1.1</version.iconic>
        <version.java-ee.dependencies>2.3.2</version.java-ee.dependencies>
        <version.javassist>3.25.0-GA</version.javassist>
        <version.jtds>1.3.1</version.jtds>
        <version.lombok>1.18.6</version.lombok>
        <version.mapstruct>1.3.1.Final</version.mapstruct>
        <version.ojdbc>19.3.0.0</version.ojdbc>
        <version.opencsv>4.6</version.opencsv>
        <version.log4j>2.17.1</version.log4j>

        <!-- Project -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <!-- Maven plugins-->
        <maven-jar-plugin.version>3.1.0</maven-jar-plugin.version>
        <maven-javadoc-plugin.version>3.0.1</maven-javadoc-plugin.version>
        <maven-war-plugin.version>3.2.2</maven-war-plugin.version>
        <buildnumber-maven-plugin.version>1.4</buildnumber-maven-plugin.version>
    </properties>

    <dependencyManagement>
        <dependencies>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>2.6.4</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
            <dependency>
                <groupId>com.giffing.wicket.spring.boot.starter</groupId>
                <artifactId>wicket-spring-boot-starter-parent</artifactId>
                <version>3.1.6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Uploadfactory dependencies -->
            <dependency>
                <groupId>com.xyz.uof</groupId>
                <artifactId>uof-app</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.xyz.uof</groupId>
                <artifactId>uof-common</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.xyz.uof</groupId>
                <artifactId>uof-database</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.xyz.uof</groupId>
                <artifactId>uof-endpoints</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.xyz.uof</groupId>
                <artifactId>uof-frontend</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.xyz.uof</groupId>
                <artifactId>uof-model</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.xyz.uof</groupId>
                <artifactId>uof-security</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.xyz.uof</groupId>
                <artifactId>uof-services</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.xyz.uof</groupId>
                <artifactId>uof-services-interfaces</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>com.xyz.uof</groupId>
                <artifactId>uof-transformation</artifactId>
                <version>${project.version}</version>
            </dependency>

            <!-- Database dependencies -->
            <dependency>
                <groupId>com.oracle.database.jdbc</groupId>
                <artifactId>ojdbc8</artifactId>
                <version>${version.ojdbc}</version>
            </dependency>
            <dependency>
                <groupId>net.sourceforge.jtds</groupId>
                <artifactId>jtds</artifactId>
                <version>${version.jtds}</version>
            </dependency>

            <!-- Log4j -->
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-api</artifactId>
                <version>${version.log4j}</version>
            </dependency>

            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.30</version>
                <classifier>sources</classifier>
            </dependency>

            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-to-slf4j</artifactId>
                <version>${version.log4j}</version>
            </dependency>

            <!-- Wicket Dependencies -->
            <dependency>
                <groupId>org.apache.wicket</groupId>
                <artifactId>wicket-core</artifactId>
                <version>${version.wicket}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.wicket</groupId>
                <artifactId>wicket-request</artifactId>
                <version>${version.wicket}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.wicket</groupId>
                <artifactId>wicket-util</artifactId>
                <version>${version.wicket}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.wicket</groupId>
                <artifactId>wicket-extensions</artifactId>
                <version>${version.wicket}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.wicket</groupId>
                <artifactId>wicket-spring</artifactId>
                <version>${version.wicket}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.wicket</groupId>
                <artifactId>wicket-auth-roles</artifactId>
                <version>${version.wicket}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.wicket</groupId>
                <artifactId>wicket-ioc</artifactId>
                <version>${version.wicket}</version>
            </dependency>
            <dependency>
                <groupId>com.googlecode.wicket-jquery-ui</groupId>
                <artifactId>wicket-jquery-ui</artifactId>
                <version>${version.wicket}</version>
            </dependency>

            <!-- Wicket Bootstrap -->
            <dependency>
                <groupId>de.agilecoders.wicket</groupId>
                <artifactId>wicket-bootstrap-core</artifactId>
                <version>${version.wicket-bootstrap}</version>
            </dependency>
            <dependency>
                <groupId>de.agilecoders.wicket</groupId>
                <artifactId>wicket-bootstrap-less</artifactId>
                <version>${version.wicket-bootstrap}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>de.agilecoders.wicket</groupId>
                <artifactId>wicket-bootstrap-extensions</artifactId>
                <version>${version.wicket-bootstrap}</version>
            </dependency>
            <dependency>
                <groupId>de.agilecoders.wicket</groupId>
                <artifactId>wicket-bootstrap-themes</artifactId>
                <version>${version.wicket-bootstrap}</version>
            </dependency>

            <!-- Misc dependencies -->
            <dependency>
                <groupId>com.opencsv</groupId>
                <artifactId>opencsv</artifactId>
                <version>${version.opencsv}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>${version.apache.commons.lang}</version>
            </dependency>
            <dependency>
                <groupId>org.webjars.bower</groupId>
                <artifactId>open-iconic</artifactId>
                <version>${version.iconic}</version>
            </dependency>

            <!-- Test and Runtime -->
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
                <version>${version.h2-database}</version>
                <scope>runtime</scope>
            </dependency>

        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!-- Missing libraries in Java 11 -->
        <dependency>
            <groupId>jakarta.xml.bind</groupId>
            <artifactId>jakarta.xml.bind-api</artifactId>
            <version>${version.java-ee.dependencies}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>${version.java-ee.dependencies}</version>
        </dependency>
        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>${version.javassist}</version>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
        </dependency>

        <!-- Helpers -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${version.lombok}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${version.mapstruct}</version>
            <scope>provided</scope>
        </dependency>

        <!-- Test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <!-- this is needed or IntelliJ gives junit.jar or junit-platform-launcher:1.3.2 not found errors -->
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-launcher</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>${maven-jar-plugin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>test-jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>${maven-javadoc-plugin.version}</version>
                <configuration>
                    <doclint>none</doclint>
                    <!--<additionalparam>-Xdoclint:none</additionalparam> -->
                    <failOnError>false</failOnError>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${version.lombok}</version>
                        </path>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${version.mapstruct}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <redirectTestOutputToFile>true</redirectTestOutputToFile>
                        <argLine>
                            @{argLine} --illegal-access=permit -Xss2048k -Xmx2048m
                        </argLine>
                    </configuration>
                </plugin>       
            </plugins>
        </pluginManagement>
    </build>
</project>

Ajax文件下载

import java.io.File;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.AbstractAjaxBehavior;
import org.apache.wicket.request.IRequestCycle;
import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler;
import org.apache.wicket.request.resource.ContentDisposition;
import org.apache.wicket.util.file.Files;
import org.apache.wicket.util.resource.FileResourceStream;
import org.apache.wicket.util.resource.IResourceStream;

// Based on: https://cwiki.apache.org/confluence/display/WICKET/AJAX+update+and+file+download+in+one+blow
public class AjaxFileDownload extends AbstractAjaxBehavior {
    private static final long serialVersionUID = -3721931990952363001L;

    private File file;
    private boolean deleteAfter;
    private boolean addAntiCache;

    public AjaxFileDownload() {
        this(false, true);
    }

    public AjaxFileDownload(boolean deleteAfter) {
        this(deleteAfter, true);
    }

    public AjaxFileDownload(boolean deleteAfter, boolean addAntiCache) {
        super();
        this.deleteAfter = deleteAfter;
        this.addAntiCache = addAntiCache;
    }

    // Call this method to initiate the download
    public void initiate(AjaxRequestTarget target) {
        if (file == null) {
            throw new IllegalArgumentException("No file has been provided for download.");
        }
        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);");
    }

    @Override
    public void onRequest() {
        ResourceStreamRequestHandler handler = new ResourceStreamRequestHandler(getResourceStream(), getFileName()) {
            @Override
            public void respond(IRequestCycle requestCycle) {
                super.respond(requestCycle);

                if (deleteAfter) {
                    Files.remove(file);
                }
            }
        };
        handler.setContentDisposition(ContentDisposition.ATTACHMENT);
        getComponent().getRequestCycle().scheduleRequestHandlerAfterCurrent(handler);
    }

    private String getFileName() {
        return file.getName();
    }

    private IResourceStream getResourceStream() {
        return new FileResourceStream(new org.apache.wicket.util.file.File(file));
    }

    // Set file to download
    public void setFile(File file) {
        this.file = file;
    }
}

initiate被此方法调用

private AbstractButtonPanel createDownloadTemplateButton(String markupId) {
    return new ButtonPanel(markupId) {
        @Override
        protected void buttonClick(final AjaxRequestTarget target) {
            FormExceptionHandler<File> handler = dataHolder -> generateCsvTemplateFile();
            File templateDownload = handler.apply(new WicketExceptionDataholder(target, form, log));

                    fileDownloadBehaviour.setFile(file);
                    fileDownloadBehaviour.initiate(target);
        }

    }.withLinkTextKey("downloadTemplateButton.label");
}

按钮面板

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;

public abstract class ButtonPanel extends AbstractButtonPanel {

    public ButtonPanel(String markupId) {
        super(markupId);
    }

    @Override
    protected AjaxLink<Void> createAbstractLink(String markupId) {
        return new AjaxLink<>(markupId) {

            @Override
            public void onClick(AjaxRequestTarget target) {
                buttonClick(target);
            }
        };
    }

    protected abstract void buttonClick(AjaxRequestTarget target);

}

抽象按钮面板

import com.xyz.uof.frontend.web.bootstrap.css.BootstrapCssEnum;
import com.xyz.uof.frontend.web.bootstrap.css.BootstrapCssEnum.BUTTON;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.apache.wicket.Component;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.markup.html.WebComponent;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.AbstractLink;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;

public abstract class AbstractButtonPanel extends Panel {

    /**
     * Change the button to be a link, btn-primary, or what else
     */
    private String buttonSizeClass = BUTTON.SIZE_SMALL;
    private String cssClass = BootstrapCssEnum.BUTTON.PRIMARY;
    private String linkTextKey;
    private String buttonName = "submitButton"; // default
    private IModel<Boolean> visibleModel = Model.of(true);
    private IModel<Boolean> enabledModel = Model.of(true);
    private String iconClass;
    private boolean spinnerActive = false;

    public AbstractButtonPanel(String markupId) {
        super(markupId);
        setOutputMarkupId(true);
    }

    @Override
    protected void onInitialize() {
        super.onInitialize();
        add(createLink("link"));
    }

    @Override
    protected void onConfigure() {
        super.onConfigure();
        setVisibilityAllowed(visibleModel.getObject());
        setEnabled(enabledModel.getObject());
    }

    private AbstractLink createLink(String markupId) {
        AbstractLink ajaxLink = createAbstractLink(markupId);
        ajaxLink.add(new AttributeAppender("class", buttonSizeClass + " " + cssClass, " "));
        ajaxLink.add(createSpinner("spinner", ajaxLink));
        ajaxLink.add(createLabel("label"));
        ajaxLink.add(createIcon("labelIcon"));
        ajaxLink.get("labelIcon").add(new AttributeAppender("class", iconClass, " "));
        return ajaxLink;
    }

    protected abstract AbstractLink createAbstractLink(String markupId);

    private Component createSpinner(String markupId, AbstractLink ajaxLink) {
        if (spinnerActive) {
            ajaxLink.add(new AttributeAppender("onClick", String.format("document.getElementById('%s').childNodes[1].className = 'spinner-grow spinner-grow-sm';", ajaxLink.getMarkupId())));
        }
        return new WebComponent(markupId) {
            @Override
            protected void onConfigure() {
                super.onConfigure();
                getParent().getId();

                setVisibilityAllowed(spinnerActive);
            }
        };
    }
    
    private Label createLabel(String markupId) {
        // Use this model to handle null linkTextKey.
        // Helps to have buttons with glyphicons only
        return new Label(markupId, () -> StringUtils.isNotBlank(linkTextKey) ? getString(linkTextKey) : "") {

            @Override
            protected void onConfigure() {
                super.onConfigure();
                setVisibilityAllowed(StringUtils.isNotBlank(linkTextKey));
            }

        };
    }

    private Component createIcon(String markupId) {
        return new WebComponent(markupId) {
            @Override
            protected void onConfigure() {
                super.onConfigure();
                setVisibilityAllowed(Optional.ofNullable(iconClass).isPresent());
            }
        };
    }

    public AbstractButtonPanel withButtonSizeClass(String buttonSizeClass) {
        this.buttonSizeClass = buttonSizeClass;
        return this;
    }

    public AbstractButtonPanel withCssClass(String cssClass) {
        this.cssClass = cssClass;
        return this;
    }

    // Important for Selenium
    public AbstractButtonPanel withName(String... buttonName) {
        StringBuilder sb = new StringBuilder();
        for (String currentSplit : buttonName) {
            sb.append(currentSplit);
        }
        sb.append(this.buttonName);
        this.buttonName = sb.toString();
        return this;
    }

    public AbstractButtonPanel withLinkTextKey(String linkTextKey) {
        this.linkTextKey = linkTextKey;
        return this;
    }

    public AbstractButtonPanel withVisibleModel(IModel<Boolean> visibleModel) {
        this.visibleModel = visibleModel;
        return this;
    }

    public AbstractButtonPanel withEnabledModel(IModel<Boolean> enabbledModel) {
        this.enabledModel = enabbledModel;
        return this;
    }

    public AbstractButtonPanel withIconName(String iconName) {
        this.iconClass = iconName;
        return this;
    }

    public AbstractButtonPanel withSpinner(boolean spinnerActive) {
        this.spinnerActive = spinnerActive;
        return this;
    }

}
k10s72fa

k10s72fa1#

所以问题是

target.appendJavaScript("setTimeout(\"window.location.href='" + url + "'\", 100);");

Javascript被阻止了,我需要在另一个类中解除阻止,这个类像这样扩展WicketBootSecuredWebApplication

@Override
protected void init() {
super.init();
getCspSettings().blocking().disabled();
}
}

相关问题