httpServletRequest中的流只能讀取一次的原因
首先,我們復習一下InputStream read方法的基礎知識,
java InputStream read方法內部有一個,postion,標誌當前流讀取到的位置,每讀取一次,位置就會移動一次,如果讀到最後,InputStream.read方法會返回-1,標誌已經讀取完了,如果想再次讀取,可以調用inputstream.reset方法,position就會移動到上次調用mark的位置,mark默認是0,所以就能從頭再讀了。
當然,能否reset是有條件的,它取決於markSupported,markSupported() 方法返回是否可以mark/reset
我們再回頭看request.getInputStream
request.getInputStream返回的值是ServletInputStream,查看ServletInputStream源碼發現,沒有重寫reset方法,所以查看InputStream源碼發現marksupported 返回false,並且reset方法,直接拋出異常。
InputStream.java
public boolean markSupported() { return false; } public synchronized void reset() throws IOException { throw new IOException("mark/reset not supported"); }
綜上所述,在request.getinputstream讀取一次後position到了文件末尾,第二次就讀取不到數據,由於無法reset(),所以,request.getinputstream只能讀取一次。
總結:
這個問題最根本還是對java IO的read、reset方法的深入理解,尤其是read方法的內部實現原理。
附ServletInputStream.java源碼
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package javax.servlet; import java.io.IOException; import java.io.InputStream; /** * Provides an input stream for reading binary data from a client request, * including an efficient <code>readLine</code> method for reading data one line * at a time. With some protocols, such as HTTP POST and PUT, a * <code>ServletInputStream</code> object can be used to read data sent from the * client. * <p> * A <code>ServletInputStream</code> object is normally retrieved via the * [email protected]
以上這篇淺談request.getinputstream只能讀取一次的問題就是小編分享給大家的全部內容了,希望能給大家一個參考。
httpServletRequest中的流只能讀取一次的原因