gpt4 book ai didi

jsf-2 - 发布后处理 JSF 中的 View 参数

转载 作者:行者123 更新时间:2023-12-04 00:22:21 25 4
gpt4 key购买 nike

我有几个页面需要 userId 才能工作,因此代码如下:

用户页面.xhtml

<!-- xmlns etc. omitted -->
<html>
<f:metadata>
<f:viewParam name="userId" value="#{userPageController.userId}"/>
</f:metadata>
<f:view contentType="text/html">
<h:head>
</h:head>
<h:body>
<h:form>
<h:commandButton action="#{userPageController.doAction}" value="post"/>
</h:form>
</h:body>
</f:view>

用户页面 Controller .java
@Named
@ViewScoped
public class userPageControllerimplements Serializable {
private static final long serialVersionUID = 1L;

@Inject protected SessionController sessionController;
@Inject private SecurityContext securityContext;
@Inject protected UserDAO userDAO;

protected User user;
protected Long userId;

public UserPage() {
}

public User getUser() {
return user;
}

public void setUser(User user) {
this.user = user;
}

public Long getUserId() {
return userId;
}

public void setUserId(Long userId) {
if(!FacesContext.getCurrentInstance().isPostback()){
User u = userDAO.find(userId);
this.userId = userId;
this.user = u;
}
}

public void doAction(){

}

}

但是调用doAction后,url中的view参数就消失了。由于其 View 范围的性质,该 bean 仍然有效,但它破坏了我 future 导航的尝试。当我四处搜索时,我的印象是 View 参数应该在发布后保留,因此阅读 userpage.jsf?userId=123,但事实并非如此。真正的预期行为是什么?

与此相关,我尝试在导航到另一个我想保留 userId 的页面时实现 View 参数的自动添加。它似乎对其他人有效,但对我来说,ViewRoot 中的 userId 始终为空。下面的代码用于检索 View 参数(我知道我可以使用我在 bean 中临时存储的 userId 进行导航,但这个解决方案会更漂亮):
    String name = "userId";
FacesContext ctx = FacesContext.getCurrentInstance();
ViewDeclarationLanguage vdl = ctx.getApplication().getViewHandler().getViewDeclarationLanguage(ctx, viewId);
ViewMetadata viewMetadata = vdl.getViewMetadata(ctx, viewId);
UIViewRoot viewRoot = viewMetadata.createMetadataView(ctx);
UIComponent metadataFacet = viewRoot.getFacet(UIViewRoot.METADATA_FACET_NAME);

// Looking for a view parameter with the specified name
UIViewParameter viewParam = null;
for (UIComponent child : metadataFacet.getChildren()) {
if (child instanceof UIViewParameter) {
UIViewParameter tempViewParam = (UIViewParameter) child;
if (name.equals(tempViewParam.getName())) {
viewParam = tempViewParam;
break;
}
}
}

if (viewParam == null) {
throw new FacesException("Unknown parameter: '" + name + "' for view: " + viewId);
}

// Getting the value
String value = viewParam.getStringValue(ctx); // This seems to ALWAYS be null.

最后一个想法是 setter 方法似乎仍然有效, setUserId 在 post 时使用正确的值调用。

我是否完全误解了 View 参数的工作原理,或者这里是否存在某种错误?我认为我的用例应该是非常普遍的,并且在框架中有基本的支持。

最佳答案

When i search around, I get the impression that the view parameter should remain after a post thus reading userpage.jsf?userId=123, but this is not the case. What is really the intended behaviour?



这种行为是正确的。 <h:form>生成 HTML <form>带有操作 URL 的元素 没有 任何 View 参数。 POST 请求只是提交到该 URL。如果你打算在 URL 中保留 View 参数,那么基本上有 3 种方式:
  • 引入一些 ajax 魔法。

    <h:commandButton action="#{userPageController.doAction}" value="post">
    <f:ajax execute="@form" render="@form" />
    </h:commandButton>

    这样,最初请求的页面以及浏览器地址栏中的请求 URL 始终保持不变。
  • 如果适用(例如用于页面到页面导航),请将其设为 GET 请求并使用 includeViewParams=true .您可以使用 <h:link><h:button>为此:

    <h:button outcome="nextview?includeViewParams=true" value="post" />

    但是,这在早于 2.1.6 的 Mojarra 版本中存在 EL 安全漏洞。确保您使用的是 Mojarra 2.1.6 或更新版本。另见 issue 2247 .
  • 控制<h:form>的action URL的生成你自己。提供定制 ViewHandler (只需扩展 ViewHandlerWrapper )其中您在 getActionURL() 中完成工作.

    public String getActionURL(FacesContext context, String viewId) {
    String originalActionURL = super.getActionURL(context, viewId);
    String newActionURL = includeViewParamsIfNecessary(context, originalActionURL);
    return newActionURL;
    }

    要让它运行,请在 faces-config.xml 中注册它如下:

    <application>
    <view-handler>com.example.YourCustomViewHandler</view-handler>
    </application>

    这也是什么OmniFaces <o:form> 正在做。它支持额外的 includeViewParams包含表单操作 URL 中所有 View 参数的属性:
    <o:form includeViewParams="true">


  • 更新 :以编程方式获取当前 View 的 View 参数(这基本上是你的第二个问题)应该如下完成:
    Collection<UIViewParameter> viewParams = ViewMetadata.getViewParameters(FacesContext.getCurrentInstance().getViewRoot());

    for (UIViewParameter viewParam : viewParams) {
    String name = viewParam.getName();
    Object value = viewParam.getValue();
    // ...
    }

    关于jsf-2 - 发布后处理 JSF 中的 View 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10352641/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com