我正在使用JSF 2.2。我試圖使用JSF作爲純模板語言。但是,有一個問題。是誰在我的環境中創建一個JSF頁面任何用戶都可以做這樣的事情:如何在JSF頁面上禁用#{session}?
#{session.getAttribute('user').getApiKey()}
在這裏我有一個存儲在會話和getApiKey()方法是該類中的吸氣用戶對象。
是否存在'web.xml'配置或其他一些技巧,我可以用它來在JSF頁面上完全禁用會話對象?
我正在使用JSF 2.2。我試圖使用JSF作爲純模板語言。但是,有一個問題。是誰在我的環境中創建一個JSF頁面任何用戶都可以做這樣的事情:如何在JSF頁面上禁用#{session}?
#{session.getAttribute('user').getApiKey()}
在這裏我有一個存儲在會話和getApiKey()方法是該類中的吸氣用戶對象。
是否存在'web.xml'配置或其他一些技巧,我可以用它來在JSF頁面上完全禁用會話對象?
是否存在'web.xml'配置或其他一些技巧,我可以用它來在JSF頁面上完全禁用會話對象?
號
手動解析模板與允許標記的白名單,屬性和EL表達式(注意:不要使用黑名單,黑客會發現你無法想象的方式)。例如,下列詞彙具有作爲同樣的效果:
#{request.session.getAttribute('user').apiKey}
#{sessionScope.user.apiKey}
#{user.apiKey}
#{facesContext.externalContext.sessionMap.user.apiKey}
#{facesContext.externalContext.session.getAttribute('user').apiKey}
畢竟,JSF/Facelets的可能這個工作的錯誤工具爲客戶提供某種將在服務器上執行的模板。而不是尋找BB/Wiki/Markdown -like標記或whitelisted HTML,你通過<h:outputText escape="false">
顯示。
也許吧。隱式變量由特定的ELResolver提供。從ELResolvers列表中刪除那個,或者預先添加一個自己的解析器,該解析器總是爲該列表的所有隱式變量返回null,這應該能夠做到。
副手,我不知道JSF是否提供了一個公共API來做到這一點,或者規範甚至允許這樣的事情。
無論哪種方式,如果你只需要一個模板引擎,有一個自定義狀態,基於組件的Web應用程序框架更容易的選擇...
這裏是我做過什麼來解決這個問題。這個類從本質上撤銷對頁面上所有核心對象的訪問。另外,我添加了一個實用變量來訪問上下文路徑。我已經試過這個,並且似乎是工作!。
package com.example.templates.jsf;
import javax.el.ELContext;
import javax.el.ELException;
import javax.el.PropertyNotFoundException;
import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import com.sun.faces.component.CompositeComponentStackManager;
import com.sun.faces.el.ImplicitObjectELResolver;
import com.sun.faces.util.MessageUtils;
/**
* This class revokes access to server page context objects
*/
public class CustomImplicitObjectELResolver extends ImplicitObjectELResolver {
public static final int CONTEXT_PATH = 19;
public CustomImplicitObjectELResolver(){
super();
// Revoke access to variables that can potentially
// give access to internal class objects.
IMPLICIT_OBJECTS.remove("facesContext");
IMPLICIT_OBJECTS.remove("session");
IMPLICIT_OBJECTS.remove("sessionScope");
IMPLICIT_OBJECTS.remove("application");
IMPLICIT_OBJECTS.remove("applicationScope");
IMPLICIT_OBJECTS.remove("request");
IMPLICIT_OBJECTS.remove("requestScope");
IMPLICIT_OBJECTS.remove("view");
IMPLICIT_OBJECTS.remove("viewScope");
IMPLICIT_OBJECTS.remove("initParam");
IMPLICIT_OBJECTS.remove("component");
IMPLICIT_OBJECTS.remove("cookie");
IMPLICIT_OBJECTS.remove("header");
IMPLICIT_OBJECTS.remove("headerValues");
IMPLICIT_OBJECTS.remove("flowScope");
// My own utility method
IMPLICIT_OBJECTS.put("contextPath", CONTEXT_PATH);
}
@Override
public Object getValue(ELContext context,Object base, Object property)
throws ELException {
// variable resolution is a special case of property resolution
// where the base is null.
if (base != null) {
return null;
}
if (property == null) {
String message = MessageUtils.getExceptionMessageString
(MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "property");
throw new PropertyNotFoundException(message);
}
Integer index = IMPLICIT_OBJECTS.get(property.toString());
if (index == null) {
return null;
} else {
FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
ExternalContext extCtx = facesContext.getExternalContext();
switch (index) {
case COMPOSITE_COMPONENT:
// The following five lines violate the specification.
// The specification states that the 'cc' implicit object
// always evaluates to the current composite component,
// however, this isn't desirable behavior when passing
// attributes between nested composite components, so we
// need to alter the behavior so that the components behave
// as the user would expect.
/* BEGIN DEVIATION */
CompositeComponentStackManager manager =
CompositeComponentStackManager.getManager(facesContext);
Object o = manager.peek();
/* END DEVIATION */
if (o == null) {
o = UIComponent.getCurrentCompositeComponent(facesContext);
}
context.setPropertyResolved(o != null);
return o;
case PARAM:
context.setPropertyResolved(true);
return extCtx.getRequestParameterMap();
case PARAM_VALUES:
context.setPropertyResolved(true);
return extCtx.getRequestParameterValuesMap();
case CONTEXT_PATH:
context.setPropertyResolved(true);
return extCtx.getRequestContextPath();
case RESOURCE:
context.setPropertyResolved(true);
return facesContext.getApplication().getResourceHandler();
default:
return null;
}
}
}
}
接下來,在faces-config.xml中,添加如下條目:
<application>
<el-resolver>
com.example.templates.jsf.CustomImplicitObjectELResolver
</el-resolver>
</application>
EL解析器是應用程序範圍這將由此也打敗 「自己的」 代碼工作。 – BalusC 2013-04-10 22:51:34
如果我們已經在JSF內部開始探索,那麼可能有很多方法。例如,我們可以使用一個專用的FacesContextFactory和一個不同配置的EL-Context。 – meriton 2013-04-10 23:05:54