Prevent IllegalStateException when reading from request

10,125

Solution 1

Perhaps you should try using the request's InputStream rather than its Reader if you receive an IllegalStateException:

BufferedReader bufferedReader;
try {
    bufferedReader = request.getReader();
} catch (IllegalStateException e) {
    InputStream inputStream = request.getInputStream();

    // As per BalusC's comment:
    String charsetName = request.getCharacterEncoding();
    if (charsetName == null) {
        charsetName = "UTF-8";
    }

    InputStreamReader inputStreamReader = new InputStreamReader(inputStream, charsetName);
    bufferedReader = new BufferedReader(inputStreamReader);
}

bufferedReader.readLine();

Solution 2

You will get that exception if someone else has already read the request body or if the other kind of reader (in your case the InputStream) has been opened by someone.

My guess is that this happens in the code which parses the request. So at this stage, you can't read the request body anymore. Instead, you should check the field which contains the exception. Your struts config must contain this code somewhere:

<exception
  key="exception"
  path="/UserExists.jsp"
  type="java.lang.Exception"/>

This means you can find the exception in the request attribute exception.

Share:
10,125
Trick
Author by

Trick

There a feeling I get, when I look to the west.

Updated on June 04, 2022

Comments

  • Trick
    Trick almost 2 years

    I have an interceptor for catching Exceptions and sending emails of this exceptions.

    All my struts actions extend CoreController which implements SerlvetRequestAware.

    In mail service class then I have:

    CoreController cc = (CoreController)invocation.getAction();
    HttpServletRequest request = cc.getRequest();
    

    I want to insert request body to email, if exists. Like so:

    StringWriter msg = new StringWriter();
    msg.write("Requested URI: " + request.getRequestURI()+NEW_LINE);
    msg.write("Requested Query String: " + request.getQueryString()+NEW_LINE);
    msg.write("Request method: "+request.getMethod()+NEW_LINE);
    try {
     if (request.getReader() != null) {
      msg.write("Request body: "+ request.getReader().readLine()+NEW_LINE);
      request.getReader().close();
     }
    } catch (IOException e) {
        e.printStrackTrace();
    } catch(IllegalStateException e) {
        e.printStrackTrace();
    }
    

    Now it always throws an IllegalStateException, when reader is not null. How could I "revert" reader or how any other way to read the request body?

    EDIT Exception: getInputStream() has already been called for this request

  • BalusC
    BalusC over 14 years
    If the IllegalArgumentException is indeed caused by calling the Reader instead of InputStream and the topicstarter'd go for this solution, please keep character encoding in mind. Preferably construct InputStreamReader with the charset as obtained from request.getCharacterEncoding(), otherwise you will get into trouble with "unicode".
  • Trick
    Trick over 14 years
    I tried this, but the value is null (but I am sending it in a request body).
  • Trick
    Trick over 14 years
    I don't understand this. I am doing only REST calls, so I don't have any jsp files to forward it there. I get the exception through an interceptor.
  • BalusC
    BalusC over 14 years
    @Trick: If it is null, use UTF-8.
  • Trick
    Trick over 14 years
    Thanks for the afford, i tried this in the first attempt, but it was still null... Any other idea? :)
  • Adam Paynter
    Adam Paynter over 14 years
    @Trick: The value returned by getCharacterEncoding() is supposedly specified in the Content-Type HTTP header. For example: Content-Type: text/plain;charset=UTF-8