2017-03-06 1 views
0

J'ai un httpClient qui envoie un objet json et un ensemble de fichiers dans le corps Le WS REST est un serveur glassfish (payara) Lorsque le fichier est petit (pas plus de 1k), il fonctionne bien Lorsque j'envoie une demande avec un fichier plus volumineux que les autres (j'ai essayé avec ~ 130k et fichier ~ 50k), il renvoie une erreur à multipartStream.readBodyData(os); de la fonction suivanteDélai de soumission d'un post de repos avec httpClient et Glassfish

public static String parseMultipart(InputStream stream, List<UploadedFile> uploadedFiles) throws IOException { 

    String msgInfo = null; 

    MultipartStream multipartStream = new MultipartStream(stream, "".getBytes()); 
    boolean nextPart = multipartStream.skipPreamble(); 

    if (nextPart) { 

     // Information 
     multipartStream.readHeaders(); 

     ByteArrayOutputStream os = new ByteArrayOutputStream(); 
     multipartStream.readBodyData(os); 
     //json part 
     msgInfo = new String(os.toByteArray(), java.nio.charset.StandardCharsets.UTF_8); 

     nextPart = multipartStream.readBoundary(); 
    } 

    // Files 
    while (nextPart) { 

     String header = multipartStream.readHeaders(); 
     String fileName = null; 

     int fileNameStart = header.indexOf("filename=\""); 
     int fileNameEnd = -1; 
     if (fileNameStart != -1) { 

      fileNameEnd = header.indexOf("\"", fileNameStart + 10); 
      if (fileNameEnd != -1) { 
       fileName = header.substring(fileNameStart + 10, fileNameEnd); 
      } 
     } 

     if (fileName != null) { 

      // Reads the body - Actual file data 
      ByteArrayOutputStream os = new ByteArrayOutputStream(); 
      multipartStream.readBodyData(os); 

      if (os.size() > 0) { 
       UploadedFile uploadedFile = new ByteArrayUploadedFile(os.toByteArray(), fileName, ""); 
       uploadedFiles.add(uploadedFile); 
      } else { 

       return null; 
      } 

     } else { 
      return null; 
     } 

     nextPart = multipartStream.readBoundary(); 
    } 

    return msgInfo; 

l'erreur est

Warning: StandardWrapperValve[webServices.ApplicationConfig]: Servlet.service() for servlet webServices.ApplicationConfig threw exception 
java.util.concurrent.TimeoutException 
    at org.glassfish.grizzly.nio.tmpselectors.TemporarySelectorReader.read(TemporarySelectorReader.java:126) 
    at org.glassfish.grizzly.nio.tmpselectors.TemporarySelectorReader.read(TemporarySelectorReader.java:75) 
    at org.glassfish.grizzly.AbstractReader.read(AbstractReader.java:72) 
    at org.glassfish.grizzly.nio.transport.TCPNIOTransportFilter.handleRead(TCPNIOTransportFilter.java:77) 
    at org.glassfish.grizzly.filterchain.TransportFilter.handleRead(TransportFilter.java:173) 
    at org.glassfish.grizzly.ssl.SSLBaseFilter$SSLTransportFilterWrapper.handleRead(SSLBaseFilter.java:1132) 
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.read(DefaultFilterChain.java:352) 
    at org.glassfish.grizzly.filterchain.FilterChainContext.read(FilterChainContext.java:736) 
    at org.glassfish.grizzly.http.io.InputBuffer.blockingRead(InputBuffer.java:1103) 
    at org.glassfish.grizzly.http.server.io.ServerInputBuffer.blockingRead(ServerInputBuffer.java:95) 
    at org.glassfish.grizzly.http.io.InputBuffer.fill(InputBuffer.java:1127) 
    at org.glassfish.grizzly.http.io.InputBuffer.read(InputBuffer.java:348) 
    at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:273) 
    at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:270) 
    at org.glassfish.jersey.message.internal.EntityInputStream.read(EntityInputStream.java:102) 
    at myapp.webServices.MultipartStream.readBodyData(MultipartStream.java:333) 
    ... 

La partie client est avec apache httpClient, la partie concernée est

request = new HttpPost(baseUrl + wsName); 
    MultipartEntityBuilder builder = MultipartEntityBuilder.create(); 
    builder.addTextBody("info", restBag.getAsJsonObject().toString(), ContentType.APPLICATION_JSON); 

    for (File file : restBag.getFileMap().values()) { 
     builder.addBinaryBody("file", file, ContentType.APPLICATION_OCTET_STREAM, file.getName()); 
    } 
    HttpEntity multipart = builder.build(); 
    request.setEntity(multipart); 
response = httpClient.execute(request, localContext); 

MISE À JOUR

J'ai essayé de changer la méthode REST, en utilisant Apache Commons, mais le résultat est le même

@POST 
@Path("/send") 
@Consumes(MediaType.MULTIPART_FORM_DATA) 
@Produces(MediaType.APPLICATION_JSON) 
@RolesAllowed({"WS_Crea_Messaggio"}) 
public ReturnMessage sendMessage1(@Context HttpServletRequest httpRequest) throws IOException, JAXBException 
{ 

    LOG.log(Level.FINEST, "User {0} called sendMessage", new Object[]{user}); 

    ReturnMessage ret = new ReturnMessage(); 
    String info = null; 
    List<UploadedFile> uploadedFiles = new ArrayList<>(); 
    FileItemFactory factory = new DiskFileItemFactory(); 
    ServletFileUpload upload = new ServletFileUpload(factory); 
// Parse the request 
    Iterator /* FileItem */ items; 
    try { 
     items = upload.parseRequest(httpRequest).iterator(); 
while (items.hasNext()) { 
    FileItem thisItem = (FileItem) items.next(); 
     if (thisItem.getFieldName().equals("info")) { 
      info = thisItem.getString(); 
      // Do something with the value 
    } else if (thisItem.getFieldName().equals("file")) { 
     uploadedFiles.add(new ByteArrayUploadedFile(thisItem.get(), thisItem.getName(), thisItem.getContentType())); 
    } 

} 
    } 
    catch (FileUploadException ex) { 
     LOG.log(Level.INFO, "Erroro uploading messages", ex); 
     ret.setStatus(ReturnStatusEnum.ERROR); 
     ret.setErrorCode(ReturnErrorCodeEnum.FILE_NOT_UPLOADED); 
     return ret; 
    } 
.... 
} 

Pas de chance, arrêtez à nouveau items = upload.parseRequest(httpRequest).iterator(); en attente de timeouts

org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. java.util.concurrent.TimeoutException 
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:371) 
at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126) 
at myapp.webServices.MessagesWebService.sendMessage1(MessagesWebService.java:331) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081) 
at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153) 
at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4762) 
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656) 
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:834) 
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608) 
at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:64) 
at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52) 
at sun.reflect.GeneratedMethodAccessor147.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895) 
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:834) 
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608) 
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163) 
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:140) 
at sun.reflect.GeneratedMethodAccessor149.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895) 
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:834) 
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:374) 
at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4734) 
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4722) 
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212) 
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88) 
at com.sun.proxy.$Proxy450.sendMessage1(Unknown Source) 
at myapp.webServices.__EJB31_Generated__MessagesWebService__Intf____Bean__.sendMessage1(Unknown Source) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) 
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144) 
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161) 
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:205) 
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) 
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) 
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) 
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) 
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326) 
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) 
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) 
at org.glassfish.jersey.internal.Errors.process(Errors.java:315) 
at org.glassfish.jersey.internal.Errors.process(Errors.java:297) 
at org.glassfish.jersey.internal.Errors.process(Errors.java:267) 
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) 
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305) 
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) 
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473) 
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427) 
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388) 
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341) 
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228) 
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1693) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) 
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734) 
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673) 
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174) 
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283) 
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:466) 
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:169) 
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206) 
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180) 
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235) 
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) 
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284) 
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201) 
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133) 
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112) 
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) 
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:526) 
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) 
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117) 
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56) 
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137) 
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593) 
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573) 
at java.lang.Thread.run(Thread.java:745) 
Caused by: java.io.IOException: java.util.concurrent.TimeoutException 
at org.glassfish.grizzly.nio.transport.TCPNIOTransportFilter.handleRead(TCPNIOTransportFilter.java:90) 
at org.glassfish.grizzly.filterchain.TransportFilter.handleRead(TransportFilter.java:173) 
at org.glassfish.grizzly.ssl.SSLBaseFilter$SSLTransportFilterWrapper.handleRead(SSLBaseFilter.java:1132) 
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) 
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284) 
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201) 
at org.glassfish.grizzly.filterchain.DefaultFilterChain.read(DefaultFilterChain.java:352) 
at org.glassfish.grizzly.filterchain.FilterChainContext.read(FilterChainContext.java:736) 
at org.glassfish.grizzly.http.io.InputBuffer.blockingRead(InputBuffer.java:1103) 
at org.glassfish.grizzly.http.server.io.ServerInputBuffer.blockingRead(ServerInputBuffer.java:95) 
at org.glassfish.grizzly.http.io.InputBuffer.fill(InputBuffer.java:1127) 
at org.glassfish.grizzly.http.io.InputBuffer.read(InputBuffer.java:348) 
at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:273) 
at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:270) 
at org.apache.commons.fileupload.MultipartStream$ItemInputStream.makeAvailable(MultipartStream.java:976) 
at org.apache.commons.fileupload.MultipartStream$ItemInputStream.read(MultipartStream.java:886) 
at java.io.InputStream.read(InputStream.java:101) 
at org.apache.commons.fileupload.util.Streams.copy(Streams.java:96) 
at org.apache.commons.fileupload.util.Streams.copy(Streams.java:66) 
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:366) 
... 88 more 
Caused by: java.util.concurrent.TimeoutException 
at org.glassfish.grizzly.nio.tmpselectors.TemporarySelectorReader.read(TemporarySelectorReader.java:126) 
at org.glassfish.grizzly.nio.tmpselectors.TemporarySelectorReader.read(TemporarySelectorReader.java:75) 
at org.glassfish.grizzly.AbstractReader.read(AbstractReader.java:72) 
at org.glassfish.grizzly.nio.transport.TCPNIOTransportFilter.handleRead(TCPNIOTransportFilter.java:77) 
... 107 more 

Je l'ai testé à l'aide à la fois client et serveur sur la même machine, mais je l'ai aussi essayé avec un client à distance sur le même sous-réseau

Répondre

0

Le problème est lié à la méthode auth que j'utilise. J'accède à l'application avec le certificat client et l'authentification de base Désactiver la partie certificat la demande est reçue jusqu'à la fin, sans problème Je vais ouvrir une nouvelle question pour creuser comment résoudre le problème, parce que j'ai besoin du client Cert Auth

0

Le délai d'attente que vous obtenez est parce que le NIO (non bloquant) couche en bas de la lecture du corps du message ne reçoit pas un nouveau morceau de données dans un délai d'attente, qui est par défaut 1 seconde. Cela signifie que le serveur traite tout ce qui vient et si rien de plus n'arrive dans la seconde, il lève l'exception Timeout.

Vous pouvez augmenter le délai d'attente de plus d'une seconde pour gérer les demandes plus importantes. Vous pouvez le faire dans la console d'administration, dans Config réseau -> Transports -> tcp -> Sélecteur Poll Timeout. Par défaut, il s'agit de 1000 millisecondes.

La raison peut être que la connexion est lente, beaucoup plus lente que le serveur est capable de lire les données. Pour les demandes plus petites, je suppose que les requêtes 1k entières correspondent à un ou un petit nombre de paquets TCP et se présentent comme une seule donnée. Pour les requêtes plus importantes, le nombre de paquets est plus important et ils viennent après un gros délai, probablement causé par une connexion lente ou par un client HTTP envoyant les données lentement.

+0

J'ai essayé de définir un délai plus long, sans aucune chance. Comme l'information échoue après un délai de 30 secondes et je travaille dans locahost – user2946593