我有这个本地网址: http://localhost:8084/Name/faces/Blah.xhtml?flkatid=AAA
这是一个来自facelet的片段,它检查参数“flkatid”并将其分配给bean:
<f:metadata>
<f:viewParam name="flkatid"
id="flkatid"
value="#{floKatBean.flkatid}"
required="true"
requiredMessage="URL incomplete"
validator="#{floKatBean.validateFlKatId}"
validatorMessage="URL incomplete or invalid"
>
</f:viewParam>
<f:event type="preRenderView" listener="#{floKatBean.init}"/>
<f:event type="preRenderView" listener="#{floBean.holFloListe}"/>
</f:metadata>
floKatBean.flkatid是一个整数,因此URL无效。将显示一个页面,告诉您:
flkatid:'AAA'必须是由一个或多个数字组成的数字。 flkatid:'AAA'必须是-2147483648和2147483647之间的数字示例:9346
JSF检查参数本身,因为它知道bean元素是一个整数。仅当参数是整数时才调用自定义验证器。
是否可以让服务器返回HTTP错误代码,例如403(禁止)没有离开“标准JSF世界”(或切换到RichFaces,MyFaces,SmileyFaces或其他)?我在f:viewParam中找不到任何“失败”的页面。也许在其他地方?
答案 0 :(得分:3)
您可以在验证器中执行ExternalContext#responseSendError()
。但是这需要将值声明为String
而不是Integer
并且required="true"
已被删除,所有这些都是为了防止JSF默认验证机制进行空/空检查和从String
转换为Integer
。
<f:metadata>
<f:viewParam name="flkatid" value="#{floKatBean.flkatid}"
validator="#{floKatBean.validateFlKatId}"
validatorMessage="URL incomplete or invalid"
/>
...
</f:metadata>
与
public void validate(FacesContext context, UIComponent component, Object value)
throws ValidatorException, IOException
{
if (value == null || !((String) value).matches("\\d+")) {
context.getExternalContext().responseSendError(
403, (String) component.getAttributes().get("validatorMessage"));
}
}
您可以使用init()
方法进行转换。
this.flkatidInteger = Integer.valueOf(this.flatkid);
答案 1 :(得分:0)
我发现执行此操作的最佳方法(处理请求参数和发送有用的HTTP响应)是完全删除f:viewParam
,并使用{{1中的参数“手动”处理像这样的监听器:
preRenderView
然后,在视图中:
public void preRenderViewCheckParameters() throws IOException {
if (!isPostback()) {
flkatid = getFlkatidFromRequest();
if (flkatid == null) {
responseSendError(404, "URL incomplete or invalid!");
}
}
}
private Integer getFlkatidFromRequest(){
try {
return Integer.valueOf(getRequestParameter("flkatid"));
} catch (NumberFormatException e) {
return null;
}
}
// util methods stolen from OmniFaces (check out this project, you'll love it):
// https://github.com/omnifaces/omnifaces/blob/master/src/org/omnifaces/util/Faces.java
public static String getRequestParameter(String name) {
return FacesContext.getCurrentInstance().getExternalContext()
.getRequestParameterMap().get(name);
}
public static void responseSendError(int status, String message)
throws IOException {
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.getExternalContext().responseSendError(status, message);
facesContext.responseComplete();
}
可能会有更多代码,但至少它更直接。
另外,这样做可以避免weird problems with messages not being displayed,所以......这就是我一直在做的事情。