java.lang.IllegalStateException: getReader() a déjà été appelée pour cette demande
Je veux ajouter de la journalisation pour ma Servlet, j'ai donc créé Filtre qui devrait afficher de demande et d'aller à la Servlet. Mais malheureusement, j'ai rencontré exception:
java.lang.IllegalStateException: getReader() has already been called for this request
at org.apache.catalina.connector.Request.getInputStream(Request.java:948)
at org.apache.catalina.connector.RequestFacade.getInputStream(RequestFacade.java:338)
at com.noelios.restlet.ext.servlet.ServletCall.getRequestEntityStream(ServletCall.java:190)
Donc, pour résoudre ce problème j'ai trouvé la solution avec ce film, mais ça ne fonctionne pas. Quoi d'autre puis-je utiliser/modifier dans le code? Des idées?
[MyHttpServletRequestWrapper]
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper
{
public MyHttpServletRequestWrapper(HttpServletRequest request)
{
super(request);
}
private String getBodyAsString()
{
StringBuffer buff = new StringBuffer();
buff.append(" BODY_DATA START [ ");
char[] charArr = new char[getContentLength()];
try
{
BufferedReader reader = new BufferedReader(getReader());
reader.read(charArr, 0, charArr.length);
reader.close();
}
catch (IOException e)
{
e.printStackTrace();
}
buff.append(charArr);
buff.append(" ] BODY_DATA END ");
return buff.toString();
}
public String toString()
{
return getBodyAsString();
}
}
[MyFilter]
public class MyFilterimplements Filter
{
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
final HttpServletRequestWrapper requestWrapper = new MyHttpServletRequestWrapper(httpServletRequest);
final String requestBody = requestWrapper.toString();
chain.doFilter(request, response);
}
}
OriginalL'auteur smas | 2011-09-06
Vous devez vous connecter pour publier un commentaire.
Ressemble à la restlet framework a appelé
getRequestEntityStream()
sur l'objet de la Requête qui appelle à son tourgetInputStream()
, afin de l'appelantgetReader()
sur la demande jetteIllegalStateException
. La documentation de l'API Servlet pour getReader() et getInputStream() dit:De la documentation, il semble que l'on ne peut pas appeler à la fois getReader() et getInputStream() sur l'objet de la Requête. Je vous suggère d'utiliser
getInputStream()
plutôt quegetReader()
dans votre enveloppe.OriginalL'auteur
Le principal problème est que vous ne pouvez pas lire l'entrée à la fois comme flux binaire et les flux de caractères, pas même si l'un est appelé dans un filtre et l'autre dans la servlet.
OriginalL'auteur
Aussi loin que je peux dire que les servlets sont fondamentalement rompu à cet égard. Vous pouvez essayer de contourner ce problème comme indiqué ici mais qui provoque d'autres mystérieux des problèmes lorsque d'autres choses à essayer et travailler avec elle.
Effectivement, il suggère le clonage de la demande, la lecture du corps et ensuite dans le clonés de classe substitution de la getReader et getInputStream méthodes de retourner les choses déjà récupérées.
Le code que j'ai fini avec cela:
De toute façon, cela semble bien fonctionner jusqu'à ce que nous nous sommes rendu compte que le téléchargement d'un fichier depuis le navigateur n'a pas de travail. Je l'ai coupée en deux par les changements et découvert que c'était le coupable.
Certaines personnes dans les commentaires que dans l'article de dire vous avez besoin de remplacer les méthodes à faire avec les paramètres mais n'expliquent pas comment le faire.
Par conséquent, j'ai vérifié pour voir si il n'y avait aucune différence entre les deux demandes. Cependant, après le clonage de la demande qu'il avait identiques jeux de paramètres (à la fois de la demande d'origine + cloné n'y en avait aucun) aswell comme identique d'un jeu d'en-têtes.
Cependant d'une certaine manière, la demande a été effectuée et le vissage jusqu'à la compréhension de la demande par la suite - dans mon cas, provoquant une bizaare erreur dans une bibliothèque (extdirectspring) où quelque chose a été d'essayer de lire le contenu Json. Prendre le code qui lisent le corps dans le filtre de le faire fonctionner à nouveau.
Mon code d'appel qui ressemblait à ceci:
J'ai oublié le contenu de
ParseExtDirectTargetFrom
mais il appelle getReader().Dans mon cas, le filtre a été de travail pour toutes les autres demandes, mais le comportement étrange dans ce cas, m'a fait réaliser quelque chose n'allait pas et que j'essaye de faire (mettre en œuvre judicieuse de gestion des exceptions de comportement pour les tests) n'était pas la peine de ce qui peut potentiellement rendre aléatoire les futures demandes (que je ne comprenais pas ce qui avait causé la demande pour devenir cassé).
Aussi, il est intéressant de noter que le code cassé est inévitable - je suppose qu'il pourrait être quelque chose de printemps, mais ServletRequest va tout le chemin jusqu' - c'est tout ce que vous obtenir, même si vous faisiez une servlet à partir de zéro par sous-classement HttpServlet
Ma recommandation serait ce - ne lisent pas le corps de la requête dans un filtre. Vous allez ouvrir une boîte de pandore qui va provoquer d'étranges problèmes plus tard.
OriginalL'auteur
Utilisation ContentCachingRequestWrapper classe. Envelopper HttpServletRequest thi va résoudre le problème
OriginalL'auteur