2013-09-10 8 views
4

Кто-нибудь имеет какие-либо идеи о каких-либо продуктах или библиотеках, таких как Apache Commons FileUpload, которые будут обрабатывать загрузки файлов PUT?Загрузка файлов через HTTP-запрос PUT

Любые дружеские советы или рекомендации были бы очень благодарны!

Полная история:

Мы начинаем реализовывать остальные загрузки файлов (как) сервис для наших Java веб-приложение, но не похоже, чтобы быть никаких «простых» решений для работы с загрузки файлов через HTTP PUT.

Мы надеемся найти библиотеку, такую ​​как проект Apache Commons FileUpload, но что-то, что касается не только «Загрузка файлов на основе форм в формате HTML» и/или «multipart/form-data».

Нам очень нравится способность FileUpload временно хранить файлы, перемещать их по их просьбе, а затем очищать временные файлы после того, как они больше не используются. Нам также нравится тот факт, что Spring автоматически привяжет список MultipartFile к нашему объекту команды и его доступную для нас возможность использовать, когда он попадает в наши другие контроллеры загрузки файлов на основе html-форм.

Full Stack фон:

  • Spring MVC (3.2.3.RELEASE)
  • Tomcat 7
  • Мы пытаемся следовать многоуровневой архитектуре (UI, услуги/бизнес-логика, настойчивость)

Спасибо за ваше время!


Следующий URL-адрес является примером, который показывает возможность загрузки файла из InputStream запроса. Код выполняет эту работу, но это не совсем качественное качество.

https://boplicity.nl/confluence/display/spring/Using+HTTP+PUT+and+Spring+MVC+to+upload+files


Мы используем следующую команду завиток, чтобы проверить наш веб-сервиса:

curl -v -k -X PUT --data-binary @"c:/java/files/tempfilename.txt" https://localhost:8443/api/file/tempfilename.txt 

xwoker затем дал следующий хороший завиток пример:

curl -v -X PUT -T "myfile" http://localhost:8080/mytargetfilename 
+0

Найдено исходный код: https://boplicity.nl/confluence/display/spring/Using+HTTP+PUT+and+Spring+MVC+to+upload+files – hooknc

+0

Вы не должны использовать переменную FileName путь где-то? – xwoker

+0

@xwoker, да, мы должны использовать имя_файла где-то, но это не совсем то же самое, что и мой пост. Я попытаюсь обновить свой вопрос с помощью лучшего примера кода, объясняющего простоту, которую мы пытаемся достичь. – hooknc

ответ

7

Это довольно легко получить весной правильно ответить на запрос Загрузка файла для HTTP PUT метод.

Все, что требуется, это переопределить метод isMultipart() в специальном классе MultipartResolver.

import org.apache.commons.fileupload.FileUploadBase; 
import org.apache.commons.fileupload.servlet.ServletRequestContext; 

import javax.servlet.http.HttpServletRequest; 

public class PostAndPutCommonsMultipartResolver extends CommonsMultipartResolver { 

    private static final String POST_METHOD = "POST"; 
    private static final String PUT_METHOD = "PUT"; 

    @Override 
    public boolean isMultipart(HttpServletRequest request) { 

     boolean isMultipartRequest = false; 

     if (request != null) { 

      if (POST_METHOD.equalsIgnoreCase(request.getMethod()) || PUT_METHOD.equalsIgnoreCase(request.getMethod())) { 

       isMultipartRequest = FileUploadBase.isMultipartContent(new ServletRequestContext(request)); 
      } 
     } 

     return isMultipartRequest; 
    } 
} 

Что действительно важно, это то, что по умолчанию MultipartResolver расширяется так, что метод isMultipart() будет возвращать верно для либо POST или PUT запрос.

В целом существуют две реализации по умолчанию MultipartResolver: CommonsMultipartResolver (используется с Apache Commons FileUpload) и StandardServletMultipartResolver (используется с API-интерфейсом сервлет 3.0+).

Поскольку мы используем Apache Commons FileUpload, мы расширили класс CommonsMultipartResolver.

Существует документация на MultipartResolver's Javadoc странице, которая объясняет, как правильно определить индивидуальные MultipartResolver для вашего приложения (курсив мой):

Там не реализация не распознаватель по умолчанию используется для Spring DispatcherServlets, а приложение может выбрать синтаксический анализ своих . Чтобы определить реализацию, создайте компонент с идентификатором «multipartResolver» в приложении DispatcherServlet . Такой резольвер применяется к всем запросам, обрабатываемым этим DispatcherServlet.

Для XML настроенного приложения будет выглядеть близко к следующему:

<bean id="multipartResolver" class="<package>.<name>.PostAndPutCommonsMultipartResolver"/> 

Для аннотаций настроенного приложения будет выглядеть близко к следующему:

@Bean(name = "multipartResolver") 
public CommonsMultipartResolver createMultipartResolver() { 
    return new PostAndPutCommonsMultipartResolver(); 
} 

More information on Annotation configuration of MultipartResolver.

1

Я не знают о каких-либо библиотеках, которые отвечают вашим требованиям. Но если вы не возражаете, чтобы сделать некоторые кодирования, я думаю, что хороший способ, чтобы создать что-то подобное было бы написать свой собственный

public class FileMessageConverter extends AbstractHttpMessageConverter<File> 

, который преобразует тело запроса в файл в каталоге TMP:

@Override 
protected File readInternal(Class<? extends File> clazz, HttpInputMessage inputMessage) 
     throws IOException, HttpMessageNotReadableException { 

    InputStream inputStream = inputMessage.getBody(); 
    File tmpFile = File.createTempFile("upload","tmp"); 
    if (inputStream != null) { 
     FileOutputStream outputStream = new FileOutputStream(tmpFile); 

     byte[] buffer = new byte[1024]; 
     int bytesRead; 

     while ((bytesRead = inputStream.read(buffer)) > 0) { 
      outputStream.write(buffer, 0, bytesRead); 
     } 

     outputStream.flush(); 

     outputStream.close(); 
    } 
    return tmpFile; 
} 

в контроллере вы должны определить ваш метод с:

@RequestMapping(value="/{fileName}", method = RequestMethod.PUT) 
public ResponseEntity uploadFile(@PathVariable(value="fileName") String fileName, @RequestBody File tmpFile) throws IOException { 

    // .. process tmpFile, e.g. tmpFile.renameTo(new File(fileName); 
    return new ResponseEntity<String>(HttpStatus.CREATED); 
} 

не забудьте зарегистрировать FileMessageConverter, например,

@Configuration 
@EnableWebMvc 
@ComponentScan(basePackages = {"my.controller.package"}) 
public class WebConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 
     converters.add(new FileMessageConverter()); 
    } 
} 

Завиток команда для вызова загрузки:

curl -v -X PUT -T "myfile" http://localhost:8080/mytargetfilename 
+0

Ницца. Я еще не думал об использовании MessageConverter, отличная идея! Я знал, что у меня есть библиотека в дикой природе, потому что эта работа, скорее всего, не произойдет, и мы решили, что нам придется написать код. Вопрос, хотя, как бы вы очистили временный файл в этом случае? – hooknc

+0

Я не думаю, что вы можете гарантировать раннюю очистку. Но вы можете посмотреть, как Apache Axis реализовал свой TempFileManager. Или даже используйте его вместо File.createTempFile https://svn.apache.org/repos/asf/axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/deployment/util/TempFileManager .Ява – xwoker

Смежные вопросы