0

xml-rcp サーバーとクライアントを実行しています。リクエストをサーバーに記録しようとしています。ただし、ファイルエラーの早期終了が発生します。誰かが私が間違っていることを見ることができますか?

 public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException

 ServletInputStream sis = req.getInputStream();
 int len = req.getContentLength();
 byte[] bytes = new byte[len]; 

 int offset = 0;  
 int numRead = 0;  
 while ((offset < bytes.length) && (numRead=sis.read(bytes, offset, bytes.length-offset)) >= 0) {  
       offset += numRead;  
   }  

   if (offset < bytes.length) {  
       throw new IOException("Could not complete reading request body");  
   }  

   sis.close();  

   FileOutputStream f = new FileOutputStream(new File("C:\\Users\\test\\file.log"), true);
   f.write(bytes);  
   f.flush();
   f.close();

   super.doPost(req, res);
 }

[致命的なエラー] :1:1: ファイルの終わりが早すぎます。

org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:609) でハンドル (AsyncHttpConnection.java:77) org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:45) で) org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:599) で org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:534) で java.lang.Thread .run(Thread.java:722) 原因: org.xml.sax.SAXParseException; 行番号: 1; 列番号: 1; com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1236) でファイルの終わりが早すぎる ... 26 詳細 45) org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:599) で org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:534) で java.lang. Thread.run(Thread.java:722) 原因: org.xml.sax.SAXParseException; 行番号: 1; 列番号: 1; com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1236) でファイルの終わりが早すぎる ... 26 詳細 45) org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:599) で org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:534) で java.lang. Thread.run(Thread.java:722) 原因: org.xml.sax.SAXParseException; 行番号: 1; 列番号: 1; com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1236) でファイルの終わりが早すぎる ... 26 詳細

解決:

 import javax.servlet.ServletException;
 import javax.servlet.ServletInputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequestWrapper;
 import javax.servlet.http.HttpServletResponse;

 public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
 {
 CustomHttpServletRequestWrapper wrapper = new CustomHttpServletRequestWrapper((HttpServletRequest) req);

 ServletInputStream sis = wrapper.getInputStream();
 String StringFromInputStream = IOUtils.toString(sis, "UTF-8");
 LOG.info( "request:");
 LOG.info( StringFromInputStream );
 super.doPost(wrapper, res);
 }


 public class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper
 {

  private final String body;
  private final Logger LOG = LoggerFactory.getLogger( CustomHttpServletRequestWrapper.class );

  public CustomHttpServletRequestWrapper( final HttpServletRequest request )
  {
     super( request );

     final StringBuilder stringBuilder = new StringBuilder();
     BufferedReader bufferedReader = null;

     try
     {
        final InputStream inputStream = request.getInputStream();

        if (inputStream != null)
        {
           bufferedReader = new BufferedReader( new InputStreamReader( inputStream ) );

           final char[] charBuffer = new char[128];
           int bytesRead = -1;

           while (( bytesRead = bufferedReader.read( charBuffer ) ) > 0)
           {
              stringBuilder.append( charBuffer, 0, bytesRead );
           }
        }
        else
        {
           stringBuilder.append( "" );
        }
     }
     catch (final IOException ex)
     {
        LOG.error( "Error reading the request body..." );
     }
     finally
     {
        if (bufferedReader != null)
        {
           try
           {
              bufferedReader.close();
           }
           catch (final IOException ex)
           {
              LOG.error( "Error closing bufferedReader..." );
           }
        }
     }

     body = stringBuilder.toString();
     LOG.info( "body:" );
     LOG.info( body );
  }

  @Override
  public ServletInputStream getInputStream() throws IOException
  {
     final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( body.getBytes() );

     final ServletInputStream inputStream = new ServletInputStream()
     {
        @Override
        public int read() throws IOException
        {
           return byteArrayInputStream.read();
        }
     };

     return inputStream;
  }

}

4

1 に答える 1

2

リクエストで送信されたすべてのデータをすでに消費しているため、super.doPost(...)メソッドには何も残っていません!

HttpServletRequestWrapper代わりにtoを渡すことができますsuper.doPost(...)。元のリクエストをラップする必要がありますがInputStream、このメソッドで既に読み取ったバイト配列に基づく別のリクエストを返します。また、リクエストから取得できるリーダーもラップする必要があることに注意してください ( HttpServletRequest#getReader())。

How to log response content from a java web serverも参照してください。ログの反対側に関する完全なコード サンプルを見つけることができます。必要なものに取り入れやすいと思います。

于 2013-11-12T12:03:04.920 に答える