#java #file-upload #java-ee-6 #jax-rs #resteasy
#java #загрузка файла #java-ee-6 #jax-rs #resteasy
Вопрос:
У меня есть ресурс rest, на который могут быть загружены файлы.
@Path("/rest/input")
public class InputResourceBean {
@POST
@Path("{directory: .*}")
@Consumes("multipart/form-data")
public void post(final String directory, final MultipartFormDataInput input) {
}
Я использовал SOAPUI, curl и HTML-форму для тестирования этого кода, и для всех них я получаю одну и ту же ошибку: не удалось найти заголовок удаления содержимого в части
12:55:19,739 WARN [org.jboss.resteasy.core.SynchronousDispatcher] Failed executing POST /rest/input/myDir: org.jboss.resteasy.spi.ReaderException: java.lang.RuntimeException: Could find no Content-Disposition header within part
at org.jboss.resteasy.core.messagebody.ReaderUtility.doRead(ReaderUtility.java:123) [:6.0.0.Final]
at org.jboss.resteasy.core.messagebody.ReaderUtility.doRead(ReaderUtility.java:93) [:6.0.0.Final]
at org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBodyParameterInjector.java:146) [:6.0.0.Final]
at org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInjectorImpl.java:114) [:6.0.0.Final]
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:137) [:6.0.0.Final]
at org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:252) [:6.0.0.Final]
at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:217) [:6.0.0.Final]
at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:206) [:6.0.0.Final]
at org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:503) [:6.0.0.Final]
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:480) [:6.0.0.Final]
at org.jboss.resteasy.core.SynchronousDispatcher.invokePropagateNotFound(SynchronousDispatcher.java:139) [:6.0.0.Final]
at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:211) [:6.0.0.Final]
at org.jboss.resteasy.plugins.server.servlet.FilterDispatcher.doFilter(FilterDispatcher.java:59) [:6.0.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:274) [:6.0.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242) [:6.0.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:274) [:6.0.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242) [:6.0.0.Final]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [:6.0.0.Final]
at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:191) [:6.0.0.Final]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java) [:6.0.0.Final]
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:181) [:6.0.0.Final]
at org.jboss.modcluster.catalina.CatalinaContext$RequestListenerValve.event(CatalinaContext.java:285) [:1.1.0.Final]
at org.jboss.modcluster.catalina.CatalinaContext$RequestListenerValve.invoke(CatalinaContext.java:261) [:1.1.0.Final]
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:88) [:6.0.0.Final]
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:100) [:6.0.0.Final]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) [:6.0.0.Final]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [:6.0.0.Final]
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158) [:6.0.0.Final]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [:6.0.0.Final]
at org.jboss.web.tomcat.service.request.ActiveRequestResponseCacheValve.invoke(ActiveRequestResponseCacheValve.java:53) [:6.0.0.Final]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362) [:6.0.0.Final]
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [:6.0.0.Final]
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:654) [:6.0.0.Final]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:951) [:6.0.0.Final]
at java.lang.Thread.run(Thread.java:662) [:1.6.0_24]
Caused by: java.lang.RuntimeException: Could find no Content-Disposition header within part
at org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInputImpl.extractPart(MultipartFormDataInputImpl.java:69) [:6.0.0.Final]
at org.jboss.resteasy.plugins.providers.multipart.MultipartInputImpl.extractParts(MultipartInputImpl.java:108) [:6.0.0.Final]
at org.jboss.resteasy.plugins.providers.multipart.MultipartInputImpl.parse(MultipartInputImpl.java:77) [:6.0.0.Final]
at org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataReader.readFrom(MultipartFormDataReader.java:52) [:6.0.0.Final]
at org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataReader.readFrom(MultipartFormDataReader.java:20) [:6.0.0.Final]
at org.jboss.resteasy.core.interception.MessageBodyReaderContextImpl.proceed(MessageBodyReaderContextImpl.java:105) [:6.0.0.Final]
at org.jboss.resteasy.plugins.interceptors.encoding.GZIPDecodingInterceptor.read(GZIPDecodingInterceptor.java:46) [:6.0.0.Final]
at org.jboss.resteasy.core.interception.MessageBodyReaderContextImpl.proceed(MessageBodyReaderContextImpl.java:108) [:6.0.0.Final]
at org.jboss.resteasy.core.messagebody.ReaderUtility.doRead(ReaderUtility.java:111) [:6.0.0.Final]
... 35 more
Я использую JBoss КАК 6 и resteasy. Я не понимаю, почему я получаю эту ошибку или как ее решить.
Ответ №1:
Я получил ту же ошибку при попытке использовать resteasy и, в моем случае, Seam framework. Причиной ошибки было то, что Seam MultipartFilter перехватил запрос. Что мне нужно было сделать, так это указать Seam MultipartFilter обрабатывать только составные запросы, заканчивающиеся на *.seam .
Таким образом, resteasy получил предполагаемый запрос, а не фильтр seam.
Мой метод Rest:
@POST
@Path("admin/uploadImage")
public String uploadImage(@MultipartForm UploadForm form);
Форма загрузки:
public class UploadForm {
private byte[] filedata;
public UploadForm() {
}
public byte[] getFileData() {
return filedata;
}
@FormParam("filedata")
@PartType("application/octet-stream")
public void setFileData(final byte[] filedata) {
this.filedata = filedata;
}
}
components.xml:
<component class="org.jboss.seam.web.MultipartFilter">
<property name="createTempFiles">true</property>
<property name="maxRequestSize">8000000</property>
<property name="urlPattern">*.seam</property>
</component>
Даже если вы можете не использовать Seam, я бы начал изучать используемую вами платформу и выяснять, где обрабатывается ваш запрос в первую очередь.
Ответ №2:
Я получил ту же ошибку, используя Resteasy и Spring Boot.
Spring MVC не настраивает a MultipartResolver
по умолчанию, но Spring Boot MultipartAutoConfiguration
это делает.
Просто добавьте следующее в свой application.yml
, чтобы отключить многоэлементный преобразователь, который Spring Boot хочет настроить:
spring.http.multipart.enabled: false
Если вы используете версию Spring Boot ниже 1.4:
multipart.enabled: false
Комментарии:
1. В более новых версиях spring-boot это свойство было переименовано в spring.http.multipart.enabled
2. Спасибо @JoachimVanderAuwera, я обновил ответ.