我正在开发一个 Java EE(我对它相当陌生)Web 应用程序(JSF、JPA、EJB),并且正在将 PrettyFaces 合并为人类可读/可添加书签的 URL。我一直在使用过滤器有两个原因。
- 以确保用户已登录。
- 在事务中包装对 filterChain.doFilter(...) 的调用,以便 JPA 延迟加载在生成视图时起作用(例如,我可以在支持 bean 中设置一个部门对象,并使用 #{backingBean.department.employees}获取 .xhmtl 文件中的相关员工列表)。
在合并 PrettyFaces 之前,我为过滤器使用了 *.xhmtl 的 url 模式(在 web.xml 中)(尽管过滤器并不真正需要为登录页面运行)。使用 PrettyFaces,尝试为 Filters 指定 url-pattern 似乎有点问题,主要是由于 url-pattern 规则缺乏灵活性(缺乏对正则表达式的支持)。是否有另一种方法可以在不使用过滤器的情况下完成我需要的工作(并且不必复制代码)?
另外,我知道我可以在 URL 的开头添加一个静态部分(例如 /dept/#{deptName}/...,然后使用带有 /dept/* 的 url 模式的过滤器,但我希望从 /#{deptName}/... 之类的东西开始(并使用 /* 的 url 模式对所有内容运行过滤器,包括图像、javascript、css 等)
基本上,过滤器有一个事务注入......
@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
}
在视图 uutSerialNumber.xhmtl 中,我做了这样的事情(这需要延迟加载,除非我想在我的 uutServiceBean.findUutByUutId() 中手动预取集合)...
<ul>
<c:forEach var="serialNumber item="#{uut.serialNumbers}>
<li>#{serialNumber.description}</li>
</c:forEach>
</ul>