java.lang.IllegalStateException: getReader() bereits aufgerufen wurde für diese Anforderung
Möchte ich hinzufügen, dass die Protokollierung zu meinem Servlet, also ich hab mir erstellte Filter, die angezeigt werden sollen, die Anfrage und gehen Sie an das Servlet. Aber leider habe ich encoutered Ausnahme:
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)
So, um dieses problem zu beheben, habe ich gefunden, die Lösung mit dem Wrapper, aber es funktioniert nicht. Was kann ich sonst noch verwenden/ändern im code? Irgendwelche Ideen?
[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();
}
}
[Meinfilter]
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);
}
}
InformationsquelleAutor der Frage smas | 2011-09-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sieht aus wie das restlet-framework genannt hat
getRequestEntityStream()
auf das Request-Objekt, das wiederum ruftgetInputStream()
so ruftgetReader()
auf die Anfrage wirftIllegalStateException
. Die Servlet-API-Dokumentation für getReader() und getInputStream() sagt:Aus der Dokumentation es scheint, dass wir nicht anrufen können beide getReader() und getInputStream() des Request-Objekts. Ich schlage vor, Sie verwenden
getInputStream()
eher alsgetReader()
in Ihre wrapper.InformationsquelleAutor der Antwort Suresh Kumar
Das Hauptproblem ist, dass Sie nicht Lesen können, die Eingang sowohl als Binär-Streams und character-stream, auch nicht, wenn man aufgerufen wird, in einem filter und das andere in das servlet.
InformationsquelleAutor der Antwort Kennet
Soweit ich das sagen kann-servlets sind grundsätzlich gebrochen in dieser Hinsicht. Sie können versuchen, dieses problem zu umgehen, wie beschrieben hier aber andere Ursachen geheimnisvolle Probleme, wenn andere Dinge versuchen und mit ihm zu arbeiten.
Effektiv er schlägt vor, das Klonen der Wunsch, Lesen den Körper und dann in das geklonte Klasse überschreiben der getReader und getInputStream Methoden zum zurückgeben von dem Zeug bereits abgerufen.
Den code, mit dem ich endete, war diese:
Sowieso das schien einwandfrei zu funktionieren, bis wir gemerkt haben, dass das hochladen einer Datei über den browser nicht funktioniert. Ich halbierter, durch die Veränderungen und entdeckt, das der übeltäter war.
Einige Leute in den Kommentaren in diesem Artikel sagen, müssen Sie das überschreiben von Methoden mit Parametern aber nicht erklären, wie dies zu tun.
Als Ergebnis habe ich überprüft, um zu sehen, ob es einen Unterschied zwischen den beiden Anfragen. Aber nach dem Klonen die Anfrage hatte es identische Sätze von Parametern (sowohl original-Anfrage + geklont hatte keine), sowie einen identischen Satz von Headern.
Jedoch in irgendeiner Art und Weise die Anfrage wurde durchgeführt und Schrauben ist das Verständnis der Anfrage weiter unten in der Zeile - in meinem Fall verursacht eine bizaare Fehler in einer Bibliothek (extdirectspring), wo etwas versucht hatte, Sie zu Lesen, den Inhalt als Json. Nehmen Sie sich den code, das Lesen der Körper in den filter gemacht, es funktioniert wieder.
Meine Berufung code sah so aus:
Ich habe ausgefiltert den Inhalt
ParseExtDirectTargetFrom
aber es fordert getReader().In meinem Fall war der filter funktioniert für alle anderen Anforderungen, aber das seltsame Verhalten in diesem Fall machte mir klar, etwas war nicht ziemlich Recht, und was ich versuche zu tun (umsetzen vernünftiges exception-handling, Verhalten, tests) nicht Wert, potenziell brechen zufällige künftige Anfragen (da ich nicht herausfinden konnte, was hatte die Anfrage an sich defekt).
Auch es ist erwähnenswert, dass der code gebrochen ist unvermeidlich - ich vermutet, es könnte etwas von Frühling, aber ServletRequest geht den ganzen Weg - das ist alles, was Sie bekommen, auch wenn Sie ein servlet, das von Grund auf neu, indem bilden von Unterklassen HttpServlet
Meine Empfehlung wäre das - nicht Lesen der request-body in einem filter. Sie werden die öffnung einer Dose Würmer, seltsame Probleme später auf.
InformationsquelleAutor der Antwort Jonny Leeds
Verwenden ContentCachingRequestWrapper Klasse. Wrap HttpServletRequest in thi beheben Problem
InformationsquelleAutor der Antwort Swarit Agarwal