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 calle开发者_StackOverflowd for this request
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();
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
.
If you want to read the request body more than once, you could add a Filter that wraps the original HttpServletRequest inside a custom implementation that supports multiple reads (e.g. by storing the request body into a byte array and creating a new ByteArrayInputStream for each call).
Note: Wrapping HttpServletRequest and HttpServletResponse isn't uncommon (see for instance Jetty's GzipFilter, especially its GZIPResponseWrapper class). You should do this carefully though as changing (the behavior of) the request object might affect other filters or servlets.
精彩评论