2011-06-17 109 views
4

REF: http://www.lunatech-research.com/playframework-file-upload-blob播放框架:圖像顯示問題

我感到不安在這個例子中

#{list items:models.User.findAll(), as:'user'} 
    <img src="@{userPhoto(user.id)}"> 
    #{/list} 

一個點此時我已經保持用戶對象(包括圖像斑點)。然而,userPhoto()方法,使另一個浸入後端以獲取圖像user.photo

public static void userPhoto(long id) { 
     final User user = User.findById(id); 
     notFoundIfNull(user); 
     response.setContentTypeIfNotSet(user.photo.type()); 
     renderBinary(user.photo.get()); 
    } 

任何辦法來避免這種不必要的findById電話?

回答

4

雖然您實際上並未持有用戶對象,因爲userPhoto操作是在瀏覽器嘗試從@{userPhoto(user.id)}生成的URL加載圖像時發送的單獨請求中調用的。

當然,您可以從use the cache存儲來自每個用戶的照片Blob的數據,這將減少您必須在圖像請求中轉到數據庫的可能性。在這種情況下,它比它的價值更麻煩,不過因爲你只是爲用戶對象做一個簡單的主鍵查找,而且這應該相對便宜。 Plus Blob不可序列化,因此您必須分別提取每條信息。

不過,如果你嘗試,它可能是這個樣子:

// The action that renders your list of images 
public static void index() { 
    List<User> users = User.findAll(); 

    for (User user : users) { 
     cachePhoto(user.photo); 
    } 

    render(users); 
} 

// The action that returns the image data to display 
public static void userPhoto(long id) { 
    InputStream photoStream; 
    String path = Cache.get("image_path_user_" + id); 
    String type = Cache.get("image_type_user_" + id); 

    // Was the data we needed in the cache? 
    if (path == null || type == null) { 
     // No, we'll have to go to the database anyway 
     User user = User.findById(id); 
     notFoundIfNull(user); 
     cachePhoto(user.photo); 
     photoStream = user.photo.get(); 
     type = user.photo.type(); 
    } else { 
     // Yes, just generate the stream directly 
     try { 
      photoStream = new FileInputStream(new File(path)); 
     } catch (Exception ex) { 
      throw new UnexpectedException(ex); 
     } 
    } 

    response.setContentTypeIfNotSet(type); 
    renderBinary(photoStream); 
} 

// Convenience method for caching the photo information 
private static void cachePhoto(Blob photo) { 
    if (photo == null) { 
     return; 
    } 

    Cache.set("image_path_user_" + user.id, 
      photo.getFile.getAbsolutePath()); 
    Cache.set("image_type_user_" + user.id, 
      photo.getType()); 
} 

然後,你仍然有大約適當填充擔心/在你添加,更新緩存無效,並刪除操作。否則你的緩存將被過時的數據污染。