【发布时间】:2023-03-18 19:48:02
【问题描述】:
给定一个<p:selectOneMenu>,如下所示。
<f:metadata>
<f:viewParam name="id" value="#{testManagedBean.id}" converter="javax.faces.Long"/>
</f:metadata>
<p:selectOneMenu value="#{localeBean.language}" onchange="changeLanguage();">
<f:selectItem itemValue="en" itemLabel="English" />
<f:selectItem itemValue="hi" itemLabel="Hindi" />
</p:selectOneMenu>
<p:remoteCommand action="#{testManagedBean.submitAction}"
name="changeLanguage"
process="@this"
update="@none"/>
对应的托管bean:
@ManagedBean
@RequestScoped
public final class TestManagedBean {
private Long id; //Getter and setter.
public TestManagedBean() {}
public String submitAction() {
return FacesContext.getCurrentInstance().getViewRoot().getViewId() + "?faces-redirect=true&includeViewParams=true";
}
}
<f:viewParam> 表示的参数是可选的。例如,使用如下 URL 访问页面。
https://localhost:8181/Project-war/private_resources/Test.jsf
由于id是一个可选参数,一个空参数附加到URL(当从<p:selectOneMenu>更改语言时),以防它如下提供。
https://localhost:8181/Project-war/private_resources/Test.jsf?id=
这不应该发生。如果未提供空参数且 URL 应与第一个类似,则不应附加空参数。
有没有办法防止空参数在未传递的情况下附加到 URL 中?
这仅与<f:viewParam> - javax.faces.Long 指定的转换器相关联。
如果移除此转换器,则不会将参数附加到 URL,以防不提供任何参数。
虽然完全没有必要指定此处演示的转换器,但我有如下所示的转换器将通过 URL 作为查询字符串参数传递的 id 转换为 JPA 实体。
@ManagedBean
@RequestScoped
public final class ZoneConverter implements Converter {
@EJB
private final SharableBeanLocal sharableService = null;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
try {
long parsedValue = Long.parseLong(value);
if (parsedValue <= 0) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Message Summary", "Message"));
}
ZoneTable entity = sharableService.findZoneById(parsedValue);
if (entity == null) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_WARN, "Message Summary", "Message"));
}
return entity;
} catch (NumberFormatException e) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Message Summary", "Message"), e);
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return value instanceof ZoneTable ? ((ZoneTable) value).getZoneId().toString() : "";
}
}
现在需要使用<f:viewParam> 明确指定此转换器,如下所示。
<f:viewParam name="id"
value="#{testManagedBean.id}"
converter="#{zoneConverter}"
rendered="#{not empty param.id}"/>
并且关联的托管bean需要进行如下更改。
@ManagedBean
@RequestScoped
public final class TestManagedBean {
private ZoneTable id; //Getter and setter.
public TestManagedBean() {}
public String submitAction() {
return FacesContext.getCurrentInstance().getViewRoot().getViewId() + "?faces-redirect=true&includeViewParams=true";
}
}
【问题讨论】:
-
您是否尝试过将
required="false"用于您的<f:viewParam>? -
尝试将
required的<f:viewParam>设置为false,但这也没有什么不同。 -
您在帖子中遇到的一些错误/不是最佳实践:1. 从 JSF 2 开始,
*.xhtml被用作映射模式,而不是*.jsf。 X。 2. 你忘了告诉#{bean}的实现。 3. 您为您的问题包装了很多不相关的代码:托管属性与您的案例无关,p:remoteCommand也不相关。删除它们并最小化您的测试用例,直到您可以用最少的代码重现问题。如果您继续拥有它,请按原样发布。见SSCCEquestionformatting.PD:我对你的问题做了一个测试用例,没有问题。
标签: jsf jsf-2.2 viewparams