Play Framework:图像显示问题

ros*_*han 4 image playframework

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

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

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

此时我已经持有用户对象(包括图像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());
    }
Run Code Online (Sandbox Code Playgroud)

有什么方法可以避免这种不必要的findById调用?

Tim*_*one 5

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

当然,您可以使用缓存来存储来自每个用户的照片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());
}
Run Code Online (Sandbox Code Playgroud)

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