Как создать файл на сервере с путем к файлу относительно приложения?

В моем весеннем загрузочном приложении Vaadin мне нужно загрузить файлы на сервер и сохранить их там.

Локальная загрузка файлов на мой рабочий стол работает нормально, но я хочу развернуть приложение на сервере, поэтому я хочу сохранить загруженные файлы в каталоге относительно базового пути моего приложения.

Я создал папку с именем «input_files» как прямой дочерний элемент корневой папки приложения (applicationName -> input_files). Когда файл загружается, содержимое файла должно быть записано во вновь созданный файл внутри этой папки «input_files».

Код:

class FileReceiver implements Upload.Receiver, Upload.SucceededListener {
  private File file;

  public OutputStream receiveUpload(String filename, String mimeType) {
    String basePath = VaadinService.getCurrent().getBaseDirectory().getAbsolutePath();                
    FileOutputStream fileOutputStream;

    try {
      //this line would work:
      //file = new File("/Users/username/Desktop/input_files/" + filename);          

      //this line does not work:
      file = new File(basePath + "/input_files/" + filename);


      fileOutputStream = new FileOutputStream(file);
      labelFilename.setCaption(filename);
    }
    catch (final java.io.FileNotFoundException e) {
      new Notification("Could not open file", e.getMessage(), Notification.Type.ERROR_MESSAGE).show(Page.getCurrent());
      return null;
    }
    return fileOutputStream;
  }

  public void uploadSucceeded(Upload.SucceededEvent event) {

  }
};

Важная строка кода такова:

file = new File(basePathOfApplication + "/input_files/" + filename);

Эта линия не работает. Внутри папки input_files файл не создается.

********************************ОБНОВИТЬ***************** *****************

Сообщение об ошибке, отображаемое на экране:

введите здесь описание изображения

Сообщение об ошибке в консоли:

com.vaadin.server.UploadException: Upload failed
    at com.vaadin.server.communication.FileUploadHandler.streamToReceiver(FileUploadHandler.java:631) [vaadin-server-8.1.0.jar:8.1.0]
    at com.vaadin.server.communication.FileUploadHandler.handleFileUploadValidationAndData(FileUploadHandler.java:460) [vaadin-server-8.1.0.jar:8.1.0]
    at com.vaadin.server.communication.FileUploadHandler.doHandleSimpleMultipartFileUpload(FileUploadHandler.java:413) [vaadin-server-8.1.0.jar:8.1.0]
    at com.vaadin.server.communication.FileUploadHandler.handleRequest(FileUploadHandler.java:290) [vaadin-server-8.1.0.jar:8.1.0]
    at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1568) [vaadin-server-8.1.0.jar:8.1.0]
    at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:381) [vaadin-server-8.1.0.jar:8.1.0]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105) [spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) [spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) [spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_111]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_111]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.16.jar:8.5.16]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_111]
Caused by: com.vaadin.server.NoOutputStreamException: null
    at com.vaadin.server.communication.FileUploadHandler.streamToReceiver(FileUploadHandler.java:559) [vaadin-server-8.1.0.jar:8.1.0]
    ... 43 common frames omitted

person steady_progress    schedule 26.10.2017    source источник
comment
Какую ошибку вы получаете при использовании VaadinService.getCurrent().getBaseDirectory().getAbsolutePath(); ?   -  person pan    schedule 27.10.2017
comment
Спасибо за ваш комментарий ... Я обновил свой пост, который теперь также содержит сообщения об ошибках, которые я получаю (на экране и в консоли)   -  person steady_progress    schedule 27.10.2017


Ответы (3)


Убедитесь, что ваше приложение может создавать файлы в каталоге /private/var/.... Скорее всего, не может. Я мало что знаю о Vaadin, но сама папка может быть «только для чтения»/«временным» каталогом для хранения распакованных классов и данных, необходимых для приложения. Этот каталог не может быть предназначен для хранения каких-либо загрузок и динамического контента.

В документации указано:

Возвращает базовый каталог контекста. Обычно приложение развертывается таким образом, что оно имеет каталог приложения. Для веб-приложений этот каталог является корневым каталогом веб-приложений. В некоторых случаях приложения могут не иметь каталога приложений (например, веб-приложения, работающие внутри войны).

Таким образом, это может быть даже null, что также сломает ваш код.

ИМХО, для загрузки лучше использовать другой выделенный каталог, который можно указать в конфигурации приложения. Или используйте известное местоположение, например /tmp.

Кроме того, не забудьте сначала создать родительские каталоги с помощью file.getParentFile().mkdirs().

person madhead    schedule 29.10.2017

Не следует сохранять файл в сервисе Vaadin, согласно форуму Vaadin,

Вы должны сохранять файлы в app.getContext().getBaseDirectory()

  • Примечание: где приложение com.vaadin.Application

Вы можете проверить Sample, который также проверяет свойство на случай, если оно не будет работать:

 // cannot access example directory, possible security issue with
// Application Server or Servlet Container
// Try to read sample directory from web.xml parameter
if (application.getProperty("sampleDirectory") != null) {
                file = new File(application.getProperty("sampleDirectory"));
                if ((file != null) && (file.canRead())
                        && (file.getAbsolutePath() != null)) {
                    // Success using property
                    return file;
                }
person user7294900    schedule 29.10.2017

У вашей папки нет разрешения, попробуйте дать ей полное разрешение, как у /tmp

drwxrwxrwt  15 root root 4.0K Nov  4 20:23 tmp

использовать sudo chmod 777 /opt/myapp/input_files/

после этого попробуйте выполнить свой код.

Примечание: я использовал /opt/use, можно использовать и любую другую папку, но не забудьте дать ей разрешение.

person Manish Jaiswal    schedule 04.11.2017