Wicket从文件系统提供图像

4

我是一个刚接触Wicket的新手,使用资源引用时遇到了一些困难。我使用的是wicket 1.5.4,并遇到了以下问题:我在文件系统中存储图像。我有一个名为ImageElement的类,它保存与配置的rootFilePath相对应的文件路径的一部分(例如dir1/dir2/img1.png)。在页面上,我按如下方式添加图像:

new Image("id",ImagesResourceReference.get(), pageParameters)

其中页面参数包括图像路径参数 (path="/dir1/dir2/img1.png")。我的问题是:

  • 这是否是从文件系统中提供图像的最简单方法?
  • 使用静态方法的ResourceReference可以吗?还是每次都应该构造一个新的ResourceReference?我发现在之前的版本中可以使用new ResourceReference(globalId),但现在似乎不再适用了。如果是这样,全局资源引用又是什么?就我目前的理解,资源引用应该是资源工厂,因此为每个资源请求创建新的工厂可能会相当奇怪。
  • 最后一个问题是,如何以更好的方式传递图像路径,以便在ImageResource上调用respond方法时不必连接索引参数来构建路径。
  • 什么是使其以高效且简单的方式正常工作的最佳方案?我看到了《Wicket in action》中的示例,但这是针对从数据库进行动态图像生成的,不确定是否适合我的情况。

我在应用程序下挂载的ResourceReference实现,在"/images"路径下如下:

public class ImagesResourceReference extends ResourceReference {

private static String rootFileDirectory;

private static ImagesResourceReference instance;

private ImagesResourceReference() {
    super(ImagesResourceReference.class, "imagesResourcesReference");
}

public static ImagesResourceReference get() {
    if(instance == null) {
        if(StringUtils.isNotBlank(rootFileDirectory)) {
            instance = new ImagesResourceReference();
        } else {
            throw new IllegalStateException("Parameter configuring root directory " +
                    "where images are saved is not set");
        }
    }
    return instance;
}

public static void setRootFileDirectory(String rootFileDirectory) {
    ImagesResourceReference.rootFileDirectory = rootFileDirectory;
}

private static final long serialVersionUID = 1L;

@Override
public IResource getResource() {

    return new ImageResource(rootFileDirectory);
}

private static class ImageResource implements IResource {

    private static final long serialVersionUID = 1L;

    private final String rootFileDirectory;

    public ImageResource(String rootFileDirectory) {
        this.rootFileDirectory = rootFileDirectory;
    }

    @Override
    public void respond(Attributes attributes) {

         PageParameters parameters = attributes.getParameters();
         List<String> indexedParams = getAllIndexedParameters(parameters);
         if(!indexedParams.isEmpty() && isValidImagePath(indexedParams)) {
             String pathToRequestedImage = getImagePath(indexedParams);
             FileResourceStream fileResourceStream = new FileResourceStream(new File(pathToRequestedImage));
             ResourceStreamResource resource = new ResourceStreamResource(fileResourceStream);
             resource.respond(attributes);
         }
    }

    private boolean isValidImagePath(List<String> indexedParams) {
        String fileName = indexedParams.get(indexedParams.size() -1);
        return !FilenameUtils.getExtension(fileName).isEmpty();
    }

    private List<String> getAllIndexedParameters(PageParameters parameters) {
        int indexedparamCount = parameters.getIndexedCount();
        List<String> indexedParameters = new ArrayList<String>();
        for(int i=0; i<indexedparamCount ;i++) {
            indexedParameters.add(parameters.get(i).toString());
        }
        return indexedParameters;
    }

    private String getImagePath(List<String> indexedParams) {
        return rootFileDirectory + File.separator + StringUtils.join(indexedParams, File.separator);
    }

}

非常感谢您的帮助和建议!提前致谢。

2个回答

8

您可以将其用作共享资源:

    public class WicketApplication extends WebApplication {
        @Override
        public Class<HomePage> getHomePage() {
            return HomePage.class;
        }
        @Override
        public void init() {
            super.init();
            getSharedResources().add("downloads", new FolderContentResource(new File("C:\\Users\\ronald.tetsuo\\Downloads")));
            mountResource("downloads", new SharedResourceReference("downloads"));
        }
        static class FolderContentResource implements IResource {
            private final File rootFolder;
            public FolderContentResource(File rootFolder) {
                this.rootFolder = rootFolder;
            }
            public void respond(Attributes attributes) {
                PageParameters parameters = attributes.getParameters();
                String fileName = parameters.get(0).toString();
                File file = new File(rootFolder, fileName);
                FileResourceStream fileResourceStream = new FileResourceStream(file);
                ResourceStreamResource resource = new ResourceStreamResource(fileResourceStream);
                resource.respond(attributes);
            }
        }
    }

非常感谢你,tetsuo。SharedResourceReference是我所缺少的信息。现在我清楚了如何使用它! - Sempa
很高兴能帮到你。现在,接受答案怎么样?这就是StackOverflow的工作方式 :) - tetsuo
你好Marcin。你能否建议我最终的编码部分,以便从文件系统中提供图像,因为我也遇到了同样的问题,而且我没有正确理解它。提前致谢。 - code_fish
@MarcinZasepa,您能发布一下可行的实现吗?因为我现在也遇到了完全相同的问题。谢谢!问题:我想在WicketPanel上做同样的事情。我应该在面板类中使用这个实现吗?还是应该像这里的WicketApplication一样创建一个新类? - ZelelB
1
为了支持FolderContentResource中的任何子目录(而不仅仅是根目录): 不要使用: String fileName = parameters.get(0).toString(); 而是使用: <code> File file = rootFolder; for (int i=0; i<parameters.getIndexedCount(); i++) { file = new File(file, parameters.get(i).toString()); } <code> - Raigedas

0

你仍然可以使用带全局ID的ResourceReferences,只需要使用SharedResourceReference即可。这可能也更好。

add(new Image("image", new SharedResourceReference("mySharedResourceRef", parameters));

我会尽量避免从URL参数构建路径。这很容易导致安全漏洞。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接