从请求读取时防止illegalstateexception

nkkqxpd9  于 2021-06-30  发布在  Java
关注(0)|答案(3)|浏览(285)

我有一个截获例外和发送电子邮件的例外。
我的所有struts操作都扩展了实现serlvetrequestaware的corecontroller。
在邮件服务课上,我有:

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

如果存在,我想在电子邮件中插入请求正文。像这样:

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();
}

现在,当reader不为null时,它总是抛出一个illegalstateexception。如何“还原”读卡器,或者如何以其他方式读取请求正文?
编辑异常:已为此请求调用getinputstream()

rslzwgfq

rslzwgfq1#

也许您应该尝试使用请求的 InputStream 而不是它的 Reader 如果你收到 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();
hmtdttj4

hmtdttj42#

如果其他人已经读取了请求主体,或者其他类型的读取器(在您的例子中是inputstream)已经被其他人打开,那么您将得到该异常。
我猜这发生在解析请求的代码中。所以在这个阶段,您不能再读取请求体了。相反,应该检查包含异常的字段。struts配置必须包含以下代码:

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

这意味着您可以在request属性中找到异常 exception .

qgzx9mmu

qgzx9mmu3#

如果要多次读取请求正文,可以添加一个过滤器,将原始httpservletrequest封装在支持多次读取的自定义实现中(例如,将请求正文存储到字节数组中,并为每个调用创建一个新的bytearrayinputstream)。
注意: Package httpservletrequest和httpservletresponse并不少见(例如,请参阅jetty的gzipfilter,特别是它的gzipresponsewrapper类)。尽管更改请求对象的(行为)可能会影响其他过滤器或servlet,但您应该谨慎地执行此操作。

相关问题