2

I'm working on a Java EE (which I'm fairly new to) web application (JSF, JPA, EJB), and am in the process of incorporating PrettyFaces for human readable/bookmarkable URLs. I've been using a Filter for 2 reasons.

  1. to make sure a user is logged in.
  2. to wrap the call to filterChain.doFilter(...) in a transaction so JPA lazy loading works when generating views (for example, I can just set a Department object in the backing bean, and use #{backingBean.department.employees} to get the associated list of employees in the .xhmtl file).

Before incorporating PrettyFaces, I was using a url-pattern (in web.xml) of *.xhmtl (although the filter doesn't really need to run for the login page) for the Filter. With PrettyFaces, trying to specify a url-pattern for Filters seems to be a bit of a problem, mainly due to the lack of flexibility of the url-pattern rules (lack of support for regular expressions). Is there another way of accomplishing what I need with-out using Filters (and without having to duplicate code)?

Also, I know I can add a static portion to the beginning of the URL (like, /dept/#{deptName}/... and then use a Filter with a url-pattern of /dept/*, but I was hoping to just start with something like /#{deptName}/... (and using a url-pattern of /* runs the filter on everything, including images, javascript, css, etc.)

Basically, the filter has a transaction injected...

@Resource UserTransaction tx;

And does something like this.

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) { }
    }
}

I have a managed bean that is like this...

@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
}

In the view uutSerialNumber.xhmtl, I do something like this (which requires lazy-loading, unless I want to go to the trouble of manually pre-fetching collections in my uutServiceBean.findUutByUutId())...

<ul>
<c:forEach var="serialNumber item="#{uut.serialNumbers}>
   <li>#{serialNumber.description}</li>
</c:forEach>
</ul>
JasonI
  • 159
  • 1
  • 15

2 Answers2

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.

JasonI
  • 159
  • 1
  • 15
0

I cant see how using PrettyFaces may affect your filter - you can always get PrettyContext from HttpServletRequest and get all you need for processing url's, including regular expressions. As for JPA and lazy loading - this is quite a different story, I'd suggest to be more specific in this area and provide more details, code snippets, etc for us to be able to help.

andbi
  • 4,426
  • 5
  • 45
  • 70
  • 1
    Thanks for your reply. PrettyFaces doesn't affect my filter, but it does affect my URLs (and thus URL mappings). Without pretty faces, it's pretty easy to specify that a filter will run for all .xhtml files (set url-pattern to \*.xhtml in web.xml). With PrettyFaces the URLs don't have a .xhtml extension. What url-pattern (in web.xml) would you use for a Filter that you want to run for pages with a pattern like /#{department}/{#employee}? I'll edit my initial post with code snippets so that it's more clear. – JasonI Mar 29 '12 at 22:16
  • I think I may break this up into a few smaller questions. This is a bit loaded. – JasonI Mar 30 '12 at 01:09