2

我正在开发一个 Java EE(我对它相当陌生)Web 应用程序(JSF、JPA、EJB),并且正在将 PrettyFaces 合并为人类可读/可添加书签的 URL。我一直在使用过滤器有两个原因。

  1. 以确保用户已登录。
  2. 在事务中包装对 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>
4

2 回答 2

3

Turns out I didn't have PrettyFaces configured correctly (doh!). It was a little confusing because in the PrettyFaces Reference Guide, it says that you don't need to edit web.xml if using Servlet 3.0 (which I am). But, doing the following solved my problem.

<!-- 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>

With this, I'm able to run a filter on my views and use a Transaction View Pattern (similar to the one mentioned in Pro JPA 2, except using a Filter instead of a Serlvet, so lazy loading works with JPA), and also check that the user has a session going.

于 2012-03-31T00:02:23.337 回答
0

我看不出 usingPrettyFaces会如何影响您的过滤器 - 您始终可以PrettyContext从中获取HttpServletRequest并获取处理 url 所需的一切,包括正则表达式。至于 JPA 和延迟加载 - 这是一个完全不同的故事,我建议在这方面更具体,并提供更多细节、代码片段等,以便我们能够提供帮助。

于 2012-03-29T20:56:08.600 回答