WEB-INF目录内的JSF文件,我如何访问它们?
我想把我的JSF 2.0 xhtml文件放在WEB-INF \ jsf下。 那么我如何访问它们呢? 我知道WEB-INF中的任何东西都不会暴露在外面,所以我需要一个控制器来将我redirect到相应的JSP,对吧? (这也是模式2的模式iirc)。
我可以用web.xml / faces-config.xml中的参数来实现吗? 我认为FacesServlet是我的web应用程序的控制器,所以它应该为此目的?
另一个问题是理解模型2模式。 每个动作都必须先到达一个servlet,然后处理下一个可能的步骤? 那么一个简单的<a href="anotherPage.html" />
在这种模式下是被禁止的,因为它不会去控制servlet?
我想把我的JSF 2.0 xhtml文件放在WEB-INF \ jsf下。 那么我如何访问它们呢?
你不能。 /WEB-INF
文件夹中的文件不能直接访问。
有两个选项可以解决公共可访问的JSF源文件的问题。
-
将
FacesServlet
映射到*.xhtml
而不是*.jsf
。 -
或者,通过
web.xml
的<security-constraint>
来限制对*.xhtml
的直接访问。<security-constraint> <display-name>Restrict direct access to XHTML files</display-name> <web-resource-collection> <web-resource-name>XHTML files</web-resource-name> <url-pattern>*.xhtml</url-pattern> </web-resource-collection> <auth-constraint /> </security-constraint>
也可以看看:
- 我需要将哪些XHTML文件放在/ WEB-INF中,哪些不是?
- JSF Facelets:有时我会看到URL是.jsf,有时是.xhtml。 为什么?
另一个问题是理解模型2模式。 每个动作都必须先到达一个servlet,然后处理下一个可能的步骤?
FacesServlet
已经做到了。 这是控制器。 使用JSF,您已经以一个简单的javabean模型和JSP / Facelets文件作为视图。 作为控制器的FacesServlet
已经从您的手中完成了所有请求参数收集,validation,转换,模型更新和导航的恶意工作。
也可以看看:
- JSF MVC框架中的MVC是什么组件?
- JSF控制器,服务和DAO
那么一个简单的
<a href="anotherPage.html" />
在这种模式下是被禁止的,因为它不会去控制servlet?
不,这很好。 控制器将在需要时启动。 如果资源不需要控制器(即静态资源),那么你也不需要让它通过某个控制器。
将来,请在单独的堆栈溢出问题中提出多个问题。
安全约束只是JSF缺失的一种解决方法。 我如何能像home.jsf映射到不同于home.xhtml放在WebContent下的文件? 以这种方式,我在导航和项目结构之间有很高的耦合度。 我如何避免在JSF中?
要访问WEB-INF/jsf
文件夹内的xhtml
页面,请执行下一步:
- 将
xhtml
页面文件夹从webapp root
移到WEB-INF
- 向项目介绍“ 调度员视图 ”模式
- 将“ Front Controller ”servlet映射到基于应用程序页面的
url
- 将Faces Servlet映射到“
.xhtml
” - 在“ Dispatcher ”里向“
WEB-INF/jsf/<name>.xhtml
”页面转发请求 - 重写
jsf ViewHandler getActionUrl
从生成的action
url
(form, link, button
)中排除“WEB-INF
”
例如, xhtml
页面位于webapp根文件夹“ jsf
”中。 页面之间的所有url
都像jsf/<pageName>.xhtml
。 所以我们接下来做:
-
将
<webapp root>/jsf
移动到<webapp root>/WEB-INF/jsf
-
创buildFrontController servlet:
“
public class FrontController extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { process(req, resp); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { process(req, resp); } private void process(HttpServletRequest request, HttpServletResponse response) { Dispatcher dispatcher = Dispatcher.getInstance(); dispatcher.dispatch(request, response); } }
- 将
web.xml
Front Controller servlet映射到基于页面的url
:
<servlet> <servlet-name>Front Controller</servlet-name> <servlet-class>controllers.FrontController</servlet-class> </servlet> <servlet-mapping> <servlet-name>Front Controller</servlet-name> <url-pattern>/jsf/*</url-pattern> </servlet-mapping>
- 将
web.xml
Faces Servlet映射到.xhtml
<servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping>
- 创build调度器 ,转发
request
来更正xhtml
页面:
“
public class Dispatcher { public void dispatch(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String pageBase = "/WEB-INF/jsf/"; String pagePath = null; String errorPage = "/WEB-INF/jsf/error.xthml"; //here could be complicated logic to analyze if the page should be visible for security reasons, authorisation etc, business logic //requested page could be taken from parsing requested URI //pageName = findPageNameFromURI(request.getRequestURI()); pagePath = pageBase + pageName; //if page should not be visible pagePath = errorPage; //forward to page inside WEB-INF/jsf request.getServletContext().getRequestDispatcher(pagePath). forward(request, response); } }
所以如果页面的url是/myapp/jsf/home.xhtml
那么Dispatcher会把它转发到myapp/WEB-INF/jsf/home.xhtml
。 而Faces Servlet将处理“ .xhtml
”请求。 但是,如果在页面上使用jsf
组件,如h:form, h:link, h:button
等等,那么这些url
就会包含“ /WEB-INF
”。 所以要排除它,我们需要下一步。
-
从
jsf
生成的url
排除“/WEB-INF
”(对于jsf表单,链接,button)。 为了那个原因:6.1创build
jsf ViewHandler
子类并重写getActionUrl
:
“
public class HiddenPageViewHandler extends ViewHandlerWrapper { private static final String WEB_INF = "/WEB-INF"; private ViewHandler parent; public HiddenPageViewHandler(ViewHandler parent) { this.parent = parent; } @Override public String getActionURL(FacesContext context, String viewId) { String actionUrl = super.getActionURL(context, viewId); if (actionUrl != null && actionUrl.contains(WEB_INF)) { actionUrl = actionUrl.replace(WEB_INF, ""); } return actionUrl; } @Override public ViewHandler getWrapped() { return parent; } }
6.2configurationjsf
使用指定的ViewHandler
。 在faces-config.xml
添加next:
<application> ... <view-handler> controllers.HiddenPageViewHandler </view-handler> </application>