Simple issue with the Upload widget

I am having difficulty trying to fix a very simple problem. I have an panel with an Upload widget whose
SucceededListener, FailedListener, Receiver and StartedListener all point back to “this” … or otherwords, the panel itself. Everything works great, however if the user doesn’t choose a file and presses the Upload Button, an exception is thrown:

com.vaadin.server.UploadException: Upload failed

This isn’t really a huge problem, because nothing really breaks, but I don’t like random exception showing up in my logs. So, how do I catch the fact that no file is selected and abort the upload process? My last attempt was this:

@Override public void uploadStarted(Upload.StartedEvent startedEvent) { System.out.println("STARTING ... " + startedEvent.getFilename()); if (startedEvent.getFilename().trim().equals("")) { System.out.println(" ... interrupting"); startedEvent.getUpload().interruptUpload(); } } But, unfortunately, this interrupt method doesn’t seem to do what I want it to do. Any suggestions?

I don’t see any exception if I just return output stream in receiver.

I have two screens that can upload files and both have the same layout and the same problem when someone presses the Upload Button with no file selected. Here is a very trimmed down version of my code which should give you an idea of what I’m doing.

public class DistributionLoadWindow extends Window implements Upload.SucceededListener, Upload.FailedListener, Upload.Receiver {
..
..
..
    private Upload upload;
..
..

    public DistributionLoadWindow(() {
..
..
        upload = new Upload("Please select your pipe delimited file", this);
        upload.setButtonCaption("Upload Now");
        upload.addSucceededListener(this);
        upload.addFailedListener(this);
..
..
    }

..
..
    
    @Override
    public void uploadFailed(Upload.FailedEvent failedEvent) {
        statusLabel.setValue("Upload FAILED! Please try again.");
        distributions = null;
    }

    @Override
    public OutputStream receiveUpload(String filename, String MIMEType) {
        if (filename.trim().equals(""))  
            return null;

        titleLabel.setValue("File Uploaded : " + filename);

        FileOutputStream fos;
        file = new File(tempPath + filename);
        try {
            fos = new FileOutputStream(file);
        } catch (final java.io.FileNotFoundException e) {
            e.printStackTrace();
            return null;
        }

        return fos;
    }

    @Override
    public void uploadSucceeded(Upload.SucceededEvent succeededEvent) {
        statusLabel.setValue("");

        String[][]
 fileValues = getFileValues();
        distributions = analyzeFileValues(fileValues);
        distributionsGrid.getContainerDataSource().removeAllItems();
        distributionsGrid.setContainerDataSource(new BeanItemContainer<>(DistributionModuleData.class, distributions));
    }
}

Interestingly enough, the receiveUpload function still fires when the upload button is pressed with no file selected and that filename check is necessary or another set of exceptions are thrown when it can’t find the file.

And here’s the complete stack trace of the exception thrown:

com.vaadin.server.UploadException: Upload failed
    at com.vaadin.server.communication.FileUploadHandler.streamToReceiver(FileUploadHandler.java:627)
    at com.vaadin.server.communication.FileUploadHandler.handleFileUploadValidationAndData(FileUploadHandler.java:456)
    at com.vaadin.server.communication.FileUploadHandler.doHandleSimpleMultipartFileUpload(FileUploadHandler.java:403)
    at com.vaadin.server.communication.FileUploadHandler.handleRequest(FileUploadHandler.java:285)
    at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1409)
    at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:364)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at com.google.inject.servlet.ServletDefinition.doServiceImpl(ServletDefinition.java:287)
    at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:277)
    at com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:182)
    at com.google.inject.servlet.ManagedServletPipeline.service(ManagedServletPipeline.java:91)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:85)
    at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108)
    at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
    at com.google.inject.servlet.ManagedFilterPipeline.dispatch(ManagedFilterPipeline.java:119)
    at com.google.inject.servlet.GuiceFilter$1.call(GuiceFilter.java:133)
    at com.google.inject.servlet.GuiceFilter$1.call(GuiceFilter.java:130)
    at com.google.inject.servlet.GuiceFilter$Context.call(GuiceFilter.java:203)
    at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:130)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: com.vaadin.server.NoOutputStreamException
    at com.vaadin.server.communication.FileUploadHandler.streamToReceiver(FileUploadHandler.java:555)
    ... 34 more

One thing that would circumvent the issue is that you hide the upload button until a file has been selected.

How do I do that? I can’t seem to find any control on the Browse button, or am I missing something?

Try this:

addChangeListener(new ChangeListener() {
      @Override
      public void filenameChanged(ChangeEvent event) {
        if (event.getFilename() != null && !event.getFilename().isEmpty()) {
          setButtonCaption(“Upload”);
        }
        else {
          setButtonCaption(null);
        }
      }
    });

setButtonCaption(null);

WOW, that worked perfectly. Thanks!

Great, glad I could help :slight_smile: