我正在开发 Java EE(我对此还很陌生)Web 应用程序(JSF、JPA、EJB),并且正在将 PrettyFaces 合并为人类可读/可添加书签的 URL。我使用过滤器有两个原因。
- 确保用户已登录。
- 将对 filterChain.doFilter(...) 的调用包装在事务中,以便 JPA 延迟加载在生成 View 时起作用(例如,我可以在支持 bean 中设置一个 Department 对象,并使用 #{backingBean.department .employees} 以获取 .xhmtl 文件中关联的员工列表)。
在合并 PrettyFaces 之前,我使用 *.xhmtl 的 url 模式(在 web.xml 中)(尽管过滤器并不真正需要为登录页面运行)作为过滤器。使用 PrettyFaces,尝试为过滤器指定 url-pattern 似乎有点问题,主要是由于 url-pattern 规则缺乏灵活性(缺乏对正则表达式的支持)。是否有另一种方法可以在不使用过滤器(并且无需重复代码)的情况下完成我的需要?
此外,我知道我可以在 URL 的开头添加静态部分(例如/dept/#{deptName}/...,然后使用 URL 模式为/dept/* 的过滤器,但是我希望从/#{deptName}/... 之类的东西开始(并使用/* 的 url 模式对所有内容运行过滤器,包括图像、javascript、css 等)
基本上,过滤器注入(inject)了一个事务......
@Resource UserTransaction tx;
并执行类似的操作。
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) request;
HttpServletResponse httpRes = (HttpServletResponse) response;
HttpSession session = httpReq.getSession();
User currentUser = (User)session.getAttribute("userInSession");
if (currentUser == null) {
httpRes.sendRedirect("...") //redirect to LoginServlet
} else {
try {
tx.begin();
chain.doFilter(httpReq, httpRes);
}
catch (Exception e) { }
finally {
try {
tx.commit();
}
catch (Exception e) { }
}
}
我有一个像这样的托管 bean...
@ManagedBean
@RequestScoped
@URLMapping(
id="uutSerialNumber",
pattern="/#{uutSerialNumberController.programId}/uut/#{uutSerialNumberController.uutId}",
viewId="/uutSerialNumber.xhtml"
)
public class UutSerialNumberController {
@EJB private ProgramServiceBean programServiceBean;
@EJB private UutServiceBean uutServiceBean;
private Integer programId;
private Integer uutId;
private Program program;
private Uut uut;
@URLAction
public String loadData() {
program = programServiceBean.findByProgramId(programId);
uut = uutServiceBean.findUutByUutId(uutId);
return null;
}
//other stuff, setters/getters
}
在 View uutSerialNumber.xhmtl 中,我做了类似的事情(这需要延迟加载,除非我想在 uutServiceBean.findUutByUutId() 中手动预取集合)...
<ul>
<c:forEach var="serialNumber item="#{uut.serialNumbers}>
<li>#{serialNumber.description}</li>
</c:forEach>
</ul>
最佳答案
事实证明我没有正确配置 PrettyFaces(哦!)。这有点令人困惑,因为在PrettyFaces Reference Guide中,它说如果使用 Servlet 3.0(我就是),则不需要编辑 web.xml。但是,执行以下操作解决了我的问题。
<!-- PrettyFaces Filter -->
<filter>
<filter-name>Pretty Filter</filter-name>
<filter-class>com.ocpsoft.pretty.PrettyFilter</filter-class>
</filter>
<!-- My own view Filter -->
<filter>
<filter-name>View Filter</filter-name>
<filter-class>com.jasoni.ViewFilter</filter-class>
</filter>
<!-- mappings -->
<filter-mapping>
<filter-name>Pretty Filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>View Filter</filter-name>
<url-pattern>*.xhtml</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
有了这个,我可以在我的 View 上运行过滤器并使用事务 View 模式(类似于 Pro JPA 2 中提到的模式,除了使用过滤器而不是 Serlvet,因此延迟加载适用于 JPA) ,并检查用户是否正在进行 session 。
关于jsf-2 - PrettyFaces、过滤器和 url 模式问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9929201/