我试图使用自定义ActionListener拦截p:menuitem结果,但我不能。似乎如果我将结果改为行动,它当然有效,但是我不能在这些链接中使f:param工作。
截取p:menuitem结果的正确方法是什么?
更新:这是我目前的做法/想法。听起来很麻烦,但可能有用。虽然,欢迎采用更好的方法来实现这一点 -
我正在考虑使用过滤器,就像BalusC在这里描述的那样
How could I read a JSF session bean from a filter?
我最初的想法是拦截任何请求(不仅是动作请求)并对其应用一些安全规则。
我做了一些研究,似乎有很多JSF应用程序的安全模型,有些会受到bean方法的限制,有些会受到URL的限制,但在我的情况下,我想要一些我可以用xhtml控制的东西。
所以我要走向这样的事情 - http://www.kianworknotes.com/2013/06/authorization-in-jsf-with-facelets-view.html
我希望我的应用让用户为每个xhtml应用权限规则,所以我正在考虑这个想法
我可以列出所有这样的xhtml
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
List<String> pages = getResources("/private", ".xhtml");
for (String page : pages) {
try {
System.out.println(page);
System.out.println(getMetaData(context.getResourceAsStream(page)));
} catch (Exception e) {
e.printStackTrace();
}
}
return pages;
,其中
private List<String> getResources(String path, String suffix) {
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
Set<String> resources = context.getResourcePaths(path);
List<String> filteredResources = new ArrayList<String>();
for (String resource : resources) {
if (resource.endsWith(suffix)) {
filteredResources.add(resource);
} else if (resource.endsWith("/")) {
filteredResources.addAll(getResources(resource, suffix));
}
}
return filteredResources;
}
(上面的代码从这里借来 - https://community.jboss.org/thread/189427)
每个xhtml都有自己的元标记,如[h:head]
中的[meta name =“module”content =“Security”]我可以解析每个xhtml以使用SAX解析器(如
)提取此信息private class MyDefaultHandler extends DefaultHandler{
private String titleName = null;
private boolean skip = false;
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (!skip && qName.equalsIgnoreCase("meta")) {
boolean isThis = false;
for (int i = 0; i < attributes.getLength(); i++) {
String attributeName = attributes.getLocalName(i);
String attributeValue = attributes.getValue(i);
System.out.println("found attribute with localname=" + attributeName + " and value=" + attributeValue);
if (attributeName.equals("name") && attributeValue.equals("module")){
titleName = attributes.getValue(i);
isThis = true;
break;
}
}
if (isThis){
for (int i = 0; i < attributes.getLength(); i++) {
String attributeName = attributes.getLocalName(i);
String attributeValue = attributes.getValue(i);
if (attributeName.equals("content")){
titleName = attributeValue;
skip = true;
break;
}
}
}
}
}
public String getTitleName(){
return titleName;
}
}
public String parseTitle(InputStream inputStream) throws ParserConfigurationException, SAXException, IOException {
XMLReader reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
//if you comment the line below, your parser will take 1 minute EACH XML
reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
MyDefaultHandler handler = new MyDefaultHandler();
reader.setContentHandler(handler);
InputSource inputSource = new InputSource(new BufferedInputStream(inputStream));
reader.parse(inputSource);
return handler.getTitleName();
}
最后,我可以按照BallusC的建议从过滤器内部获取一些sessionScoped托管bean
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) arg0;
HttpServletResponse response = (HttpServletResponse) arg1;
HttpSession session = ((HttpServletRequest) request).getSession();
Enumeration<String> names = session.getAttributeNames();
while(names.hasMoreElements()){
System.out.println(names.nextElement());
}
AuthorizationManagerMB authorizationManagerMB = (AuthorizationManagerMB)session.getAttribute("authorizationManagerMB");
if (authorizationManagerMB == null){
System.out.println("Filter = not logged");
}else{
System.out.println("Filtering = "+request.getRequestURI());
authorizationManagerMB.doSomething();
}
这很麻烦:-)我知道
但即使用户在浏览器中提供了直接网址,我也可以通过xhtml管理访问权限,无论是否使用ajax
如果有人知道不那么繁琐且更优雅的方式,允许用户动态配置角色,欢迎: - )
PS。有趣的是,JSF如何使用xhtml的方式很少。您无法列出,无法添加元数据,也无法检索元数据。这是以豆为中心的: - )
答案 0 :(得分:1)
outcome
生成一个简单的GET请求,该请求可以与参数一起使用,不需要被表单包围。为了在服务器端执行某些逻辑,首先需要POST。
对于您的具体情况,最佳选择是使用操作方法,让您在导航到新视图之前执行操作。只需执行您想要的操作并返回与目标视图匹配的导航结果:
<p:menuitem action="#{bean.changePage(param)}" />
public String changePage(String param){
//Do some stuff
return "page2?faces-redirect=true&includeViewParams=true&p1="+param;
}
此外,您必须在目标视图中捕获该参数并将其设置到您的bean中:
<f:metadata>
<f:viewParam name="p1" value="#{destinationBean.param}" />
</f:metadata>