‹Ui: include› выбрасывает javax.faces.view.facelets.TagAttributeException: неверный путь

Я практикую JSF + JPA и застрял со следующим исключением:

19/03/2013 00:04:18 org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() for servlet [Faces Servlet] in context with path [/K19-Futebol] threw exception [/times.xhtml @11,60 <ui:include src="formulario-novo-time.xhtml"> Invalid path : formulario-novo-time.xhtml] with root cause
javax.faces.view.facelets.TagAttributeException: /times.xhtml @11,60 <ui:include src="formulario-novo-time.xhtml"> Invalid path : formulario-novo-time.xhtml
[...]
at filters.JPAFilter.doFilter(JPAFilter.java:42)
[...]

Когда я перешел по ссылке BalusC (Как включить другой XHTML в XHTML с помощью JSF 2.0 Facelets?) Я думаю, проблема не в Facelets, а в этом фильтре:

@WebFilter(servletNames = {"Faces Servlet"})
public class JPAFilter implements Filter {

    private EntityManagerFactory factory;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.factory = Persistence.createEntityManagerFactory("K19-Futebol-PU");
    }

    @Override
    public void destroy() {
        this.factory.close();
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        // CHEGADA
        EntityManager manager = this.factory.createEntityManager();
        request.setAttribute("EntityManager", manager);
        manager.getTransaction().begin();
        // CHEGADA

        // FACES SERVLET
        chain.doFilter(request, response);
        // FACES SERVLET

        // SAÍDA
        try {
            manager.getTransaction().commit();
        } catch (Exception e) {
            manager.getTransaction().rollback();
        } finally {
            manager.close();
        }
        // SAÍDA
    }
}

Я также спрашиваю вашего мнения, является ли использование фильтра таким способом хорошей практикой, я имею в виду, используя фильтр для уровня модели / персистентности.

Другие классы для уточнения:

@Entity
public class Time implements Serializable { //in portuguese 'Time' means Team (e.g.:football Team)

    @Id
    @GeneratedValue
    private Long id;
    private String nome;
    private String tecnico;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getTecnico() {
        return tecnico;
    }

    public void setTecnico(String tecnico) {
        this.tecnico = tecnico;
    }
}

Управляемый компонент:

@ManagedBean
public class TimeBean {

    public Time getTime() {
        return time;
    }

    public void setTime(Time time) {
        this.time = time;
    }

    public void setTimes(List<Time> times) {
        this.times = times;
    }

    private Time time = new Time();
    private List<Time> times;

    public void adiciona() {
        EntityManager manager = this.getManager();
        TimeRepository repository = new TimeRepository(manager);
        if (this.time.getId() == null) {
            repository.adiciona(this.time);
        } else {
            repository.atualiza(this.time);
        }
        this.time = new Time();
        this.times = null;
    }

    public void preparaAlteracao() {
        Map<String, String> params = FacesContext.getCurrentInstance()
                .getExternalContext().getRequestParameterMap();
        Long id = Long.parseLong(params.get("id"));
        EntityManager manager = this.getManager();
        TimeRepository repository = new TimeRepository(manager);
        this.time = repository.procura(id);
    }

    public void remove() {
        Map<String, String> params = FacesContext.getCurrentInstance()
                .getExternalContext().getRequestParameterMap();
        Long id = Long.parseLong(params.get("id"));
        EntityManager manager = this.getManager();
        TimeRepository repository = new TimeRepository(manager);
        repository.remove(id);
        this.times = null;
    }

    public List<Time> getTimes() {
        if (this.times == null) {
            EntityManager manager = this.getManager();
            TimeRepository repository = new TimeRepository(manager);
            this.times = repository.getLista();
        }
        return this.times;
    }

    private EntityManager getManager() {
        FacesContext fc = FacesContext.getCurrentInstance();
        ExternalContext ec = fc.getExternalContext();
        HttpServletRequest request = (HttpServletRequest) ec.getRequest();
        return (EntityManager) request.getAttribute(" EntityManager ");
    }
}

Класс "репозиторий":

public class TimeRepository {

    private EntityManager manager;

    public TimeRepository(EntityManager manager) {
        this.manager = manager;
    }

    public void adiciona(Time time) {
        this.manager.persist(time);
    }

    @SuppressWarnings("unchecked")
    public void remove(Long id) {
        Time time = this.procura(id);
        Query query = this.manager.createQuery("select x from Jogador x");
        List<Jogador> jogadores = query.getResultList();
        for (Jogador jogador : jogadores) {
            jogador.setTime(null);
        }
        this.manager.remove(time);
    }

    public Time atualiza(Time time) {
        return this.manager.merge(time);
    }

    public Time procura(Long id) {
        return this.manager.find(Time.class, id);
    }

    @SuppressWarnings("unchecked")
    public List<Time> getLista() {
        Query query = this.manager.createQuery("select x from Time x");
        return query.getResultList();
    }
}

Как я могу это исправить?


person jMarcel    schedule 19.03.2013    source источник


Ответы (1)


javax.faces.view.facelets.TagAttributeException: /times.xhtml @ 11,60 <ui:include src="formulario-novo-time.xhtml"> Неверный путь: formulario-novo-time.xhtml

Эта проблема не вызвана фильтром. Он просто находится в стеке вызовов, потому что вызывается перед сервлетом лиц.

Это конкретное исключение будет выдано, когда _ 2_ бросил IOException. Этот IOException, в свою очередь, к сожалению, не является основной причиной, он регистрируется только на уровне FINE. Вы можете включить FINE (или ALL) ведение журнала, чтобы увидеть это. См. Также этот ответ, как настроить ведение журнала для JSF: Журналы JSF2 с помощью tomcat

Одна из наиболее частых причин заключается в том, что файла нет там, где вы думаете. Например. путь действительно недействителен. Путь <ui:include> разрешается относительно пути к родительскому файлу. Вы должны стремиться использовать абсолютные пути в тегах <ui:xxx>, чтобы избежать проблем с обслуживанием при реструктуризации файловой иерархии, т.е. начать путь с / и, таким образом, сделать его по существу относительно корня веб-содержимого. Например.

<ui:include src="/WEB-INF/includes/foo.xhtml" />

Если вы абсолютно уверены, что путь правильный, другой вероятной причиной является то, что желаемый включаемый файл сохраняется с использованием неизвестной или неправильной кодировки символов, что вызывает проблемы во время синтаксического анализа XML-дерева. Вам необходимо проверить, правильно ли настроен ваш редактор для сохранения всех файлов в формате UTF-8.

person BalusC    schedule 19.03.2013
comment
Привет, BalusC. Все пути уже были правильно определены, но с вашим потрясающим объяснением у меня был намек на проблему (проблема UTF-8). Я просто удалил некоторые специальные (португальские) символы из файла шаблона, и теперь это сработало! Большое тебе спасибо! - person jMarcel; 21.03.2013
comment
Пожалуйста. JSF2 / Facelets по умолчанию полностью использует UTF-8. Поэтому настоятельно рекомендуется настроить редактор для сохранения файлов в формате UTF-8. Таким образом, наличие специальных символов в файлах Facelets не должно приводить к такому сбою. - person BalusC; 21.03.2013