2012-04-26 28 views
5

Patrzę na realizację HiddenMethodFilter w sitebricks here:Czy można odczytać parametry HttpRequest bez zużywania strumienia?

Na linii 65 znajduje się następujący kod:

try { 
    String methodName = httpRequest.getParameter(this.hiddenFieldName); 
    if ("POST".equalsIgnoreCase(httpRequest.getMethod()) && !Strings.empty(methodName)) { 
    .... 

sprawdza, czy dany parametr został ustawiony i używa tego zawinąć żądanie . Jednak podczas odczytu tego parametru pobierze strumień, a ewentualny serwlet nie będzie mógł odczytać żadnych danych.

Jaki byłby najlepszy sposób na uniknięcie tego? Zaimplementowałem HttpServletRequestWrapper here, który odczytuje zawartość strumienia do tablicy bajtów. To jednak może zużywać dużo pamięci do przechowywania żądań.

private HttpServletRequestWrapper getWrappedRequest(HttpServletRequest httpRequest, final byte[] reqBytes) 
    throws IOException { 

final ByteArrayInputStream byteInput = new ByteArrayInputStream(reqBytes); 
return new HttpServletRequestWrapper(httpRequest) { 

    @Override 
    public ServletInputStream getInputStream() throws IOException { 
    ServletInputStream sis = new ServletInputStream() { 

     @Override 
     public int read() throws IOException { 
     return byteInput.read(); 
     } 
    }; 
    return sis; 
    } 
}; 
} 

Czy istnieje lepszy sposób? Czy możemy odczytać parametr bez zużywania strumienia? (Niektóre rzeczy podobne do peek) możemy zresetować strumień?

Odpowiedz

2

Jeśli korzystasz z POST żądań i odczytów parametrów z httpRequest, wpłynie to na InputStream, a będziesz mieć problemy z innymi częściami potrzebującymi go odczytać.
ta jest zawarta w ServletRequest#getParameter javadoc:

Jeżeli dane parametrów został przesłany w treści żądania, jak następuje z żądanie POST HTTP, to czytać ciało bezpośrednio poprzez getInputStream() lub getReader() może ingerować w wykonanie tej metody.

The ServletInputStream pochodzi od InputStream i dziedziczy markSupportedreset itp, które są rzeczywiście no-ops i tak nie można zresetować ServletInputStream.
Oznacza to, że będziesz musiał go skonsumować.

+0

Czy istnieją jakieś alternatywne sposoby uzyskania danych meta ze strony internetowej do kontenera serwletu, który nie wymaga, aby dane znajdowały się w treści żądania? –

+0

Użyj GET zamiast POST. Lub poszukaj alternatywnego podejścia do konkretnego wymogu funkcjonalnego, abyś nie musiał czytać ciała wielokrotnie. – BalusC

+0

@UsmanIsmail: Odczytaj raz input, buforuj go i przekazuj do różnych komponentów, które będą potrzebne do jego przeczytania. – Jim

Powiązane problemy