如何解决失败的GET参数验证后,jsf 2.0返回http错误代码
| 我有这个本地URL: 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中找不到“无法通过”该页面的任何内容。也许在其他地方?
解决方法
您可以在验证器中做一个“ 1”。但这要求将值声明为
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);
, 我发现执行此操作的最佳方法(处理请求参数并发送有用的HTTP响应)是完全删除ѭ11,然后在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();
}
然后,在视图中:
<f:metadata>
<f:event listener=\"#{portariasMB.preRenderViewLoadPortaria}\"
type=\"preRenderView\" />
</f:metadata>
也许有更多的代码,但是至少更直接了。
此外,这样做还可以避免出现无法显示消息的怪异问题,所以...这就是我一直在做的事情。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。