Pourquoi HttpServletRequest inputstream est-il vide?
J'ai ce code où j'ai lu les commentaires d'une demande de flux d'entrée et d'utiliser un JacksonMapper convertir en un POJO. Son exécution dans une jetée de 7 conteneur avec guice soutien.
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
RequestType requestType = mapper.readValue(req.getInputStream(), RequestType.class);
} Catch(Exception ex) {
....
}
}
Cependant, parfois sous la charge, l'exception suivante est levée. J'ai vérifié mon client et je suis sûr que son envoi une chaîne json valide. Ce qui ne va pas? C'est le comportement attendu pour la Jetée de 7 sous charge?
java.io.EOFException: No content to map to Object due to end of input
at org.codehaus.jackson.map.ObjectMapper._initForReading(ObjectMapper.java:2433)
at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2385)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1637)
at com.ea.wsop.user.LoginServlet.processRequest(LoginServlet.java:69)
at com.ea.wsop.user.LoginServlet.doPost(LoginServlet.java:63)
at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd.CGLIB$doPost$0(<generated>)
at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd$$FastClassByGuice$$c6f479ee.invoke(<generated>)
at com.google.inject.internal.cglib.proxy.$MethodProxy.invokeSuper(MethodProxy.java:228)
at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:72)
at com.ea.monitor.MethodExecutionTimer.invoke(MethodExecutionTimer.java:130)
at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:72)
at com.google.inject.internal.InterceptorStackCallback.intercept(InterceptorStackCallback.java:52)
at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd.doPost(<generated>)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd.CGLIB$service$8(<generated>)
at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd$$FastClassByGuice$$c6f479ee.invoke(<generated>)
at com.google.inject.internal.cglib.proxy.$MethodProxy.invokeSuper(MethodProxy.java:228)
at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:72)
at com.ea.monitor.MethodExecutionTimer.invoke(MethodExecutionTimer.java:130)
at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:72)
at com.google.inject.internal.InterceptorStackCallback.intercept(InterceptorStackCallback.java:52)
at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd.service(<generated>)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd.CGLIB$service$9(<generated>)
at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd$$FastClassByGuice$$c6f479ee.invoke(<generated>)
at com.google.inject.internal.cglib.proxy.$MethodProxy.invokeSuper(MethodProxy.java:228)
at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:72)
at com.ea.monitor.MethodExecutionTimer.invoke(MethodExecutionTimer.java:130)
at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:72)
at com.google.inject.internal.InterceptorStackCallback.intercept(InterceptorStackCallback.java:52)
at com.ea.wsop.user.LoginServlet$$EnhancerByGuice$$a91c2ebd.service(<generated>)
at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:263)
source d'informationauteur Usman Ismail
Vous devez vous connecter pour publier un commentaire.
Il sera vide si elle est déjà consommée à l'avance. Ce sera implicitement fait chaque fois que vous appelez
getParameter()
getParameterValues()
getParameterMap()
getReader()
etc sur leHttpServletRequest
. Assurez-vous que vous n'appelez pas tout de ce genre de méthodes qui, par eux-mêmes besoin de recueillir des informations à partir du corps de la requête avant d'appelergetInputStream()
. Si votre servlet n'est pas fait, puis commencer à vérifier la servlet filtres qui sont mappés sur le même modèle d'URL.Mise à jour: cela semble être GAE 1.5 spécifiques. Voir aussi
J'ai peur qu'il n'y a pas de solution jusqu'à ce qu'il fixe. Vous pourriez essayer pour vérifier si il est disponible à l'intérieur d'un
Filter
et si oui, puis copiez et l'enregistrer comme attribut de la demande. Mais ce pourrait incidence sur la poursuite du traitement par certains GAE servlet.J'ai eu un problème similaire de l'exécution d'un Printemps de Démarrage de l'application. Mon Printemps de Démarrage de l'app est un simple
Dispatcher
servlet qui lit le corps de la demande et des processus.Dans mon cas, le client (
curl
) définit un type de contenu de l'en-tête de l'application/x-www-form-urlencoded si la boucle de la ligne de commande utilise-d {some-data}
et ne permet pas de définir un contenu spécifique-type d'en-tête via-Hcontent-type=some-other-media-type
.À l'intérieur de l'Apache Catalina moteur de servlet qui Ressort de Démarrage s'exécute, le
Request
classe fait le test suivant dansparseParameters()
Pour d'autres
content-type
valeurs,Request
renvoie ici, c'est fait.Toutefois, si le type de contenu correspond
application/x-www-form-urlencoded
Request
continue:qui consommer le corps. Donc dans mon cas, même si mon servlet n'est rien d'autre que d'appeler
request.getInputStream()
et essayer deread()
il est déjà trop tard - l'exécutionRequest
déjà lit l'entrée et n'a pas de tampon ou non lus. La seule solution consiste à définir un autreContent-Type
.Le coupable est
OrderedHiddenHttpMethodFilter(HiddenHttpMethodFilter).doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain)
ligne 70qui est à la recherche pour le
"_method"
paramètre de requête.J'ai été en mesure de désactiver le filtre en ajoutant
(qui a été utilisée pour résoudre un autre problème)
J'ai eu le problème que ma demande InputStream était toujours vide avec ponton 6.1.15, et découvert qu'il a été causé par un manque ou mal "Content-Type" en-tête.
Je générer les demandes dans un autre programme Java avec HttpUrlConnection. Quand je n'ai pas de définir le Contenu de l'en-tête de Type explicite, l'
InputStream
retourné parrequest.getInputStream()
dans le programme de réception était toujours vide. Lorsque j'ai mis le contenu de type "binaire/octet-stream", leInputStream
de la demande contenait les données correctes.La seule méthode qui est appelée sur l'objet de la requête avant de
getInputStream()
estgetContentLength()
.J'ai été en utilisant mod_jk 1.2.39 qui avait un bug qui a causé ce problème. Après la mise à jour de 1.2.40 il a commencé à travailler.
J'ai eu ce problème avec un post. Je l'ai résolu en PREMIÈRE lecture, l'inputstream et le mettre dans un cache, avant de lire les paramètres. Qui semblait faire l'affaire