java - Wicket 中有静态 "sub-site"(即 : mounting a directory in Wicket)

标签 java html wicket wicket-6

我正在使用 Wicket 开发 Web 应用程序。

虽然大部分网站是通过 wicket 动态生成的,但我需要让网站的一部分成为普通的“静态”html 网站。基本上是主网站内的一个小型“子网站”,根本不受 wicket 管理,但它只是静态内容(html 页面、css、图像)的集合。

这可以做到吗?这个想法是“安装”某个子路径以指向子站点,但我不知道这是否可能,因为 mountResource() 方法需要一个 Resource 作为输入。

编辑:我需要一个允许我直接在文件系统上修改静态html文件的解决方案,这就是我尝试通过wicket“挂载目录”的原因。我不能简单地将页面放入我的 webapp 文件夹中,因为这样它们最终会出现在应用程序的 WAR 文件中,并且每次对静态页面的修改都需要完全部署。

有什么想法吗?

最佳答案

好吧,我最终使用动态资源自己实现了这一点。我不是 Wicket 专家,因此出于某种原因这可能是一个“糟糕”的解决方案,但它似乎有效。将代码发布到此处,以便其他人可以根据需要使用它:

我所做的是创建这个资源:

public class DirectoryResolverResource implements IResource {
    private static final long serialVersionUID = 1L;

    private File servedDirectory;
    private String urlPrefix;

    //served directory is the directory you want to mount as a static sub-site
    //urlPrefix is the mountpoint where you're going to mount this resource, without the leading "/". E.g.: if you mount your directory in "/help" so that the sub-site URL is www.yoursite.com/pages/help the urlPrefix value must be "help"
    public DirectoryResolverResource(File servedDirectory, String urlPrefix) {
        super();
        if (servedDirectory == null || !servedDirectory.isDirectory()) {
            throw new IllegalArgumentException("Directory is null or doesn't exist");
        }
        this.servedDirectory = servedDirectory;
        this.urlPrefix = urlPrefix;
    }

    @Override
    public void respond(Attributes attributes) {
        Url url = attributes.getRequest().getUrl();
        String subPath = "";
        try {
            //we decode the URL by reversing the percent-encoding, so that filenames are properly resolved
            subPath = URLDecoder.decode(url.toString(), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new AbortWithHttpErrorCodeException(HttpServletResponse.SC_BAD_REQUEST, "Encoding is invalid");
        }

        if (subPath.startsWith(urlPrefix)) {
            subPath = subPath.substring(urlPrefix.length());
        } else {
            throw new AbortWithHttpErrorCodeException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Url is invalid");
        }

        File file = new File(servedDirectory.getAbsolutePath() + (subPath.startsWith("/") ? "" : "/") + subPath);
        if (file.isDirectory()) {
            // In case of a directory, redirect to the path ending in "/", otherwise browsers will fail to resolve relative paths in the page
            if (!subPath.endsWith("/")) {
                throw new RedirectToUrlException("." + (subPath.isEmpty() ? "/" + urlPrefix : subPath) + "/", HttpServletResponse.SC_MOVED_PERMANENTLY);
            }
            // no specific file specified, try to return index.html
            file = new File(file.getAbsolutePath(), "index.html");
        }
        if (!file.exists() || file.isDirectory()) {
            // file not found
            throw new AbortWithHttpErrorCodeException(HttpServletResponse.SC_NOT_FOUND, "Resource not found");
        }

        if (!FSManager.isInSubDirectory(servedDirectory, file)) {
            // Security check: user is trying to escape the served directory via a non-canonical path
            throw new AbortWithHttpErrorCodeException(HttpServletResponse.SC_FORBIDDEN, "Access to this resource is forbidden");
        }

        // Serve the file
        FileResourceStream fileResourceStream = new FileResourceStream(file);
        ResourceStreamResource resource = new ResourceStreamResource(fileResourceStream);
        resource.respond(attributes);
    }

}

您可以像这样挂载此资源:

mountResource("/help", new ResourceReference("helpres") {
                private static final long serialVersionUID = 1L;

                @Override
                public IResource getResource() {
                    return new DirectoryResolverResource(helpDir, "help");
                }
            });

希望这对某人有帮助。 任何改进/评论/更正/建设性批评都将受到高度赞赏!

注意:isInSubDirectory() 方法仅检查文件是否位于某个目录树内。不会让您厌倦细节,您可以在这里找到此类方法的实现:Check if file is in (sub)directory

关于java - Wicket 中有静态 "sub-site"(即 : mounting a directory in Wicket),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38185999/

相关文章:

java - 如何为具有多个存储库的 IntelliJ 项目编写 Dockerfile?

java - 使用 VideoView 从 Android 应用程序播放存储在 EC2 实例上的视频?

javascript - Toggle Javascript 中的 Onclick 问题

java - 手动调用组件的 wicket 事件处理程序

java - Apache Wicket 与 Apache Click

Java 8 流 API : get all nodes after specific Node

java - ActivityThread.performLaunchActivity(ActivityThread$ActivityClientRecord, Intent )

html - 如何让我的推特 Bootstrap 与所有其他元素重叠?

javascript - 在 WebWorker 和主线程之间传递二进制数据的最佳做法是什么?

javascript - Wicket 口 6 : calling javascript function after page load