从请求读取时防止illegalstateexception

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

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

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

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

  1. StringWriter msg = new StringWriter();
  2. msg.write("Requested URI: " + request.getRequestURI()+NEW_LINE);
  3. msg.write("Requested Query String: " + request.getQueryString()+NEW_LINE);
  4. msg.write("Request method: "+request.getMethod()+NEW_LINE);
  5. try {
  6. if (request.getReader() != null) {
  7. msg.write("Request body: "+ request.getReader().readLine()+NEW_LINE);
  8. request.getReader().close();
  9. }
  10. } catch (IOException e) {
  11. e.printStrackTrace();
  12. } catch(IllegalStateException e) {
  13. e.printStrackTrace();
  14. }

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

rslzwgfq

rslzwgfq1#

也许您应该尝试使用请求的 InputStream 而不是它的 Reader 如果你收到 IllegalStateException :

  1. BufferedReader bufferedReader;
  2. try {
  3. bufferedReader = request.getReader();
  4. } catch (IllegalStateException e) {
  5. InputStream inputStream = request.getInputStream();
  6. // As per BalusC's comment:
  7. String charsetName = request.getCharacterEncoding();
  8. if (charsetName == null) {
  9. charsetName = "UTF-8";
  10. }
  11. InputStreamReader inputStreamReader = new InputStreamReader(inputStream, charsetName);
  12. bufferedReader = new BufferedReader(inputStreamReader);
  13. }
  14. bufferedReader.readLine();
展开查看全部
hmtdttj4

hmtdttj42#

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

  1. <exception
  2. key="exception"
  3. path="/UserExists.jsp"
  4. type="java.lang.Exception"/>

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

qgzx9mmu

qgzx9mmu3#

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

相关问题