Play Framework:图像显示问题

时间:2011-06-17 21:50:33

标签: image playframework

REF: http://www.lunatech-research.com/playframework-file-upload-blob

我对这个例子中的一点感到不安

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

此时我已经持有用户对象(包括图像blob)。然而,userPhoto()方法再次进入后端以获取Image 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调用?

1 个答案:

答案 0 :(得分:5)

您实际上并没有实际持有用户对象,因为在浏览器尝试从@{userPhoto(user.id)}生成的URL加载图像时发送的单独请求中调用了userPhoto操作。

当然,您可以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());
}

然后,您仍然需要担心在添加,更新和删除操作中适当填充/无效缓存。否则,您的缓存将被陈旧的数据污染。