从请求中读取时防止IllegalStateException

时间:2009-11-04 15:13:46

标签: java rest struts2 request

我有一个用于捕获异常并发送此例外电子邮件的拦截器。

我的所有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()

3 个答案:

答案 0 :(得分:3)

如果您收到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();

答案 1 :(得分:1)

如果其他人已经阅读了请求正文,或者其他类型的阅读器(在您的情况下是InputStream)已被某人打开,您将获得该异常。

我的猜测是,这会发生在解析请求的代码中。因此,在此阶段,您无法再阅读请求正文。相反,您应该检查包含异常的字段。你的struts配置必须包含这个代码:

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

这意味着您可以在请求属性exception中找到例外。

答案 2 :(得分:0)

如果您想多次读取请求主体,可以添加一个Filter,它将原始HttpServletRequest包装在支持多次读取的自定义实现中(例如,通过将请求主体存储到字节数组中并为其创建新的ByteArrayInputStream每次电话会议。)

注意:包装HttpServletRequest和HttpServletResponse并不罕见(例如参见Jetty's GzipFilter,尤其是其GZIPResponseWrapper类)。尽管请求对象的更改(行为)可能影响其他过滤器或servlet,但您应该小心这样做。