Получение шаблонов / файлов Facelets из внешней файловой системы или базы данных
Я могу успешно заставить это работать с шаблоном в моем приложении:
<ui:decorate template="/WEB-INF/templates/mytemplate.xhtml">
Я также могу переместить шаблон в /META-INF/templates/mytemplate.xhtml
банку и заставить это работать:
<ui:decorate template="/templates/mytemplate.xhtml">
Я действительно хотел бы поместить этот файл в файловую систему (или базу данных в этом отношении). Как мне этого добиться? Я нашел много вещей, связанных с com.sun.facelets.impl.DefaultResourceResolver
, но я не думаю, что это на самом деле связано с переопределением подачи шаблона. Он не пытается разрешить URL, он просто пытается каким-то образом получить файл в пути к классам.
1 ответ
Если вы уже используете JSF 2.2, вы можете сделать это, предоставив ResourceHandler
где вы возвращаете нужный ресурс просмотра в createViewResource()
,
public class FaceletsResourceHandler extends ResourceHandlerWrapper {
private ResourceHandler wrapped;
public FaceletsResourceHandler(ResourceHandler wrapped) {
this.wrapped = wrapped;
}
@Override
public ViewResource createViewResource(FacesContext context, final String name) {
ViewResource resource = super.createViewResource(context, name);
if (resource == null) {
resource = new ViewResource() {
@Override
public URL getURL() {
try {
return new File("/some/base/path", name).toURI().toURL();
} catch (MalformedURLException e) {
throw new FacesException(e);
}
}
};
}
return resource;
}
@Override
public ResourceHandler getWrapped() {
return wrapped;
}
}
Который зарегистрирован в faces-config.xml
как показано ниже:
<application>
<resource-handler>com.example.FaceletsResourceHandler</resource-handler>
</application>
Или, если вы еще не используете JSF 2.2, используйте ResourceResolver
вместо.
public class FaceletsResourceResolver extends ResourceResolver {
private ResourceResolver parent;
public FaceletsResourceResolver(ResourceResolver parent) {
this.parent = parent;
}
@Override
public URL resolveUrl(String path) {
URL url = parent.resolveUrl(path); // Resolves from WAR.
if (url == null) {
try {
url = new File("/some/base/path", path).toURI().toURL();
} catch (MalformedURLException e) {
throw new FacesException(e);
}
}
return url;
}
}
Который зарегистрирован в web.xml
как показано ниже:
<context-param>
<param-name>javax.faces.FACELETS_RESOURCE_RESOLVER</param-name>
<param-value>com.example.FaceletsResourceResolver</param-value>
</context-param>
Независимо от способа, для предоставления ресурса из базы данных, вы должны либо сохранить / кэшировать их в (временную) дисковую файловую систему, чтобы вы могли предоставить URL
только через File
или придумать собственный протокол, такой как db://
и предоставить обычай URLStreamHandlerFactory
а также URLStreamHandler
реализация для выполнения фактической работы потоковой передачи из БД. Вы можете найти пример запуска здесь Регистрация и использование собственного протокола java.net.URL.