是否有一种很好的方法可以使过滤器不适用于h:commandLink click?

时间:2013-03-21 21:46:14

标签: jsf action servlet-filters

我遇到一个问题,我的h:commandLink中的某个操作未触发。我查看了BalusC非常useful post关于原因可能是什么,我能够追溯到11号:

  

确保同一请求 - 响应链中没有Filter或Servlet以某种方式阻止了对FacesServlet的请求。

有一个过滤器似乎导致问题 - 我通过删除过滤器并再次尝试找到了这个。遗憾的是我没有编写过滤器,更不幸的是我对它们知之甚少。所以我想知道是否有一个很好的方法让这个过滤器不适用于h:commandLink动作射击?我看到doFilter()方法传递了以下参数:

ServletRequest request
ServletResponse response
FilterChain chain 

所以我的第一直觉是看看我是否可以在其中一个参数中使用这些参数,这些参数会告诉我这是来自h:commandLink的点击。如果是这样,我会绕过doFilter()方法中的所有代码。不确定这是否可行,或者是一种很好的方法,但这是首先想到的。

但我还想在这里询问是否有一个不错的方法来处理这个问题?或者这是否表明过滤器本身存在某些问题?我可能需要考虑修复?任何类似的信息都会有用。

顺便说一句,我知道我可以使用actionListener来激活我的bean中的方法,但是,这是我理解的糟糕设计,所以我想避免这种情况。

1 个答案:

答案 0 :(得分:0)

我说过,一旦解决了问题,我就会更新。所以我原来问题的答案是有可能的。但是做到这一点的方法并不是很好的设计。

警告 - 这个第一个选项非常hacky我不建议你这样做 - 只是为了完整性而添加。一种方法是给你的h:commandLink一个ID,比如“skipFilter”。然后在过滤器中,检查此ID。您可以在#HttpServletRequest.getParameterNames()中查看此内容。如果您发现请求来自此ID,请添加逻辑以跳过过滤器。

另一种选择是使用ajax。然后在过滤器中添加逻辑以检查请求是否为ajax,如果是,则绕过过滤器:if("partial/ajax".equalsIgnoreCase(#HttpServletRequest.getHeader("Faces-Request")))

稍微不那么苛刻。

但是这已经在我的项目过滤器中完成了,所以我不是自己添加它。

其他选项当然是BalusC推荐的,用于纠正或更换过滤器。在我的情况下,这不是一个选项,所以我必须在我的过滤器的约束下工作。所以我只使用ajax。我有h:commandLink

<h:commandLink action="#{orderInvoiceBean.navToPdfAction}" value="-EXTRA INVOICE LINK- #{invoice.customerTrxId}" >   
   <f:setPropertyActionListener target="#{orderInvoiceBean.orderInvoiceNative}" value="#{invoice}"/>
   <f:ajax/>  
</h:commandLink>

这样,首先设置orderInvoiceNative属性,然后发生ajax操作,并且可以根据需要访问该值。

但是,我还有一个问题。我需要显示二进制响应 - 而不是文本。当然,ajax并不完全允许这样做。但我被限制使用ajax。那该怎么办?

好吧,我的ajax动作会触发导航规则,只需导航到以下页面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
   <h:body binding="#{orderInvoiceBean.orderInvoicePdf}"/>
</html>

通过此页面操作,将创建一个新请求,因此现在我可以在响应中返回二进制文件。结果是,你留在你点击链接的页面上,然后你得到一个文件下载对话框 - 在发送二进制文件响应之前,这不会导航到空白页面,因为我首先担心它会 - 你继续即使您调用了导航规则,原始页面和浏览器中的网址也不会更改,请转到新页面。

希望这对某人有用。