如何代理一个InputStream

我正在使用Android-Universal-Image-Loader在我的Android应用程序上通过HTTPS从远程服务器加载图像。 要访问映像,客户端应提供有效的令牌,有时服务器可能会返回“过期的令牌令牌”错误。 为了处理这个行为,应该定义一个自定义的ImageDownloader。 下面是在我的实现中应该被覆盖的方法的基本实现。

 protected InputStream getStreamFromNetwork(String imageUri, Object extra) throws IOException { HttpURLConnection conn = createConnection(imageUri, extra); int redirectCount = 0; while (conn.getResponseCode() / 100 == 3 && redirectCount < MAX_REDIRECT_COUNT) { conn = createConnection(conn.getHeaderField("Location"), extra); redirectCount++; } InputStream imageStream; try { imageStream = conn.getInputStream(); } catch (IOException e) { // Read all data to allow reuse connection (http://bit.ly/1ad35PY) IoUtils.readAndCloseStream(conn.getErrorStream()); throw e; } if (!shouldBeProcessed(conn)) { IoUtils.closeSilently(imageStream); throw new IOException("Image request failed with response code " + conn.getResponseCode()); } return new ContentLengthInputStream(new BufferedInputStream(imageStream, BUFFER_SIZE), conn.getContentLength()); } 

我想重写它来处理无效的令牌错误。 例如,如果服务器返回这样的错误应该被识别,令牌应该被重新生成并且重复请求。

我想出的唯一解决scheme就是这样(缩短的代码):

 imageStream = conn.getInputStream(); byte[] body = org.apache.commons.io.IOUtils.toByteArray(imageStream); if (body.length < 300 // high probability to contain err message && isInvalidToken(body)) { // handle error } return new ByteArrayInputStream(body); 

考虑到我只用于最大80kb大小的缩略图,使用这种解决scheme是安全的吗? 还有其他解决scheme吗?

    您的解决scheme是安全的,但是如果您创build实现InputStream ImageDownloaderInputStream类并包装原始InputStream ,则会更好。 您可以预先加载(缓冲)来自底层inputstream的一些块,以检测内容是否有效。

    你应该重写的唯一方法是read() 。

    如果内容有效,则可以将缓冲区内容提供给调用方,缓冲区为空时,直接从基础InputStreamstream式传输。

    如果内容无效,只需简单地读取另一个stream,或返回一个零长度的stream。

     public class ImageDownloaderInputStream implements InputStream { private byte[] buffer = null; private int bufLen = 0; private int bufIndex = 0; private boolean isContentValid; private InputStream wrapped; public ImageDownloaderInputStream (InputStream wrapped) { this.wrapped = wrapped; } @Override public ind read() { if(buffer == null) { // check content and fill buffer this.isContentValid = checkContent(); } if (this.isContentValid) { if(bufIndex < bufLen) { return buffer[bufIndex++] & 0xFF; } else { return wrapped.read(); } } else { // error handling: zero-length stream return -1; } } private boolean checkContent() { // fill the buffer this.buffer = new byte[1024]; this.bufLen = wrapped.read(this.buffer); // read more if not enough // check the content return true; // return false; } } 

    你可以检查一个有效的令牌后,你检查答复是200 OK,如下所示:

     conn.getResponseCode() == HttpStatus.RESPONSE_OK && isValidToken(body) 

    如果不满足这些条件,则相应地处理它,即重复请求x次。

    我会考虑有一个isValidToken(...)方法,而不是你的isInvalidToken(...)所以你不必否定该方法的响应。

    你有没有考虑过这样的事情?

     if(conn.getResponseCode()==HttpStatus.RESPONSE_OK) else{ //repeat request...}