Проблема с PrettyFaces, фильтром и шаблоном URL

Я работаю над веб-приложением Java EE (в котором я довольно новичок) (JSF, JPA, EJB) и нахожусь в процессе включения PrettyFaces для читаемых/закладок URL-адресов. Я использую фильтр по двум причинам.

  1. чтобы убедиться, что пользователь вошел в систему.
  2. чтобы обернуть вызов filterChain.doFilter(...) в транзакцию, чтобы ленивая загрузка JPA работала при создании представлений (например, я могу просто установить объект отдела в компоненте поддержки и использовать #{backingBean.department.employees} чтобы получить связанный список сотрудников в файле .xhmtl).

Перед включением PrettyFaces я использовал шаблон URL-адреса (в web.xml) *.xhmtl (хотя фильтр на самом деле не нужно запускать для страницы входа) для фильтра. С PrettyFaces попытка указать шаблон URL-адреса для фильтров кажется небольшой проблемой, в основном из-за отсутствия гибкости правил шаблона URL-адреса (отсутствие поддержки регулярных выражений). Есть ли другой способ выполнить то, что мне нужно, без использования фильтров (и без дублирования кода)?

Кроме того, я знаю, что могу добавить статическую часть в начало URL-адреса (например, /dept/#{deptName}/..., а затем использовать фильтр с шаблоном URL-адреса /dept/*, но я надеялся просто начать с чего-то вроде /#{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>

person JasonI    schedule 29.03.2012    source источник


Ответы (2)


Оказывается, у меня неправильно настроены PrettyFaces (дох!). Это немного сбивало с толку, поскольку в справочном руководстве по PrettyFaces , в нем говорится, что вам не нужно редактировать web.xml при использовании Servlet 3.0 (что я и делаю). Но следующее решило мою проблему.

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

Благодаря этому я могу запустить фильтр для своих представлений и использовать шаблон представления транзакций (аналогичный упомянутому в Pro JPA 2, за исключением использования фильтра вместо Serlvet, поэтому ленивая загрузка работает с JPA), а также проверьте, что у пользователя есть сеанс.

person JasonI    schedule 31.03.2012

Я не понимаю, как использование PrettyFaces может повлиять на ваш фильтр — вы всегда можете получить PrettyContext из HttpServletRequest и получить все, что вам нужно для обработки URL-адресов, включая регулярные выражения. Что касается JPA и ленивой загрузки - это совсем другая история, я бы посоветовал быть более конкретным в этой области и предоставить больше деталей, фрагментов кода и т. д., чтобы мы могли помочь.

person andbi    schedule 29.03.2012
comment
Спасибо за ответ. PrettyFaces не влияет на мой фильтр, но влияет на мои URL-адреса (и, следовательно, сопоставления URL-адресов). Без красивых лиц довольно легко указать, что фильтр будет работать для всех файлов .xhtml (установите url-pattern в *.xhtml в web.xml). С PrettyFaces URL-адреса не имеют расширения .xhtml. Какой шаблон URL-адреса (в web.xml) вы бы использовали для фильтра, который вы хотите запустить для страниц с таким шаблоном, как /#{department}/{#employee}? Я отредактирую свой первоначальный пост с фрагментами кода, чтобы он был более понятным. - person JasonI; 30.03.2012
comment
Я думаю, что могу разбить это на несколько более мелких вопросов. Это немного загружено. - person JasonI; 30.03.2012