سؤال

Currently I have two pages and one template:

myapp (war)
|-myTemplate.xhtml  //yes i know, the template is in the main folder :(
|-page1.xhtml
|-folder    
    |--page2.xhtml

page1 and page2 has the same structure

So, when i access to the page1 the jsf template renders pretty well, but, when i tried look at the page2, everything looks distorted. The template is not working in that case.

web.xml has the 'url pattern' in this way:

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
</servlet-mapping>

EDIT: the page is pretty simple, the template is much more elaborated

page1.xhtml and page2.xhtml :

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
                xmlns:h="http://xmlns.jcp.org/jsf/html"
                xmlns:p="http://primefaces.org/ui"
                xmlns:f="http://xmlns.jcp.org/jsf/core"
                template="./mainTemplate.xhtml">

    <ui:define name="content">

        <h1>
            <h:outputText value="#{i18n['cc.title']}"/>
        </h1>

        <h:form id="form">           
           <!-- outputLabels, inputTexts... -->
        </h:form>  

    </ui:define>
</ui:composition>

template.xhtml

<?xml version='1.0' encoding='iso-8859-1' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:p="http://primefaces.org/ui">
    <f:loadBundle var="i18n" basename="co.gov.rnec.srcw.languages.Mensajes"/>
    <f:loadBundle var="i18nDefuncion" basename="co.gov.rnec.srcw.languages.MensajesDefuncion"/>
    <f:loadBundle var="i18nMatrimonio" basename="co.gov.rnec.srcw.languages.MensajesMatrimonio"/>
    <f:loadBundle var="i18nNacimiento" basename="co.gov.rnec.srcw.languages.MensajesNacimiento"/>
    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
        <link href="styles/styles_ani.css" rel="stylesheet" type="text/css"/>
        <link href="styles/form_styles.css" rel="stylesheet" type="text/css"/>
        <link href="styles/menu.css" rel="stylesheet" type="text/css"/>
        <title>#{i18n['srcw.titulo']}</title>
        <script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
        <script type="text/javascript" src="js/jquery-ui-1.9.2.custom.min.js"></script>
        <script type="text/javascript" src="js/general/general.js"></script>
        <script type="text/javascript" src="js/general/fechas.js"></script>
        <script type="text/javascript" src="js/general/frmvalidaciones.js"/>
    </h:head>

    <h:body onload="getHora();" >

        <div class="container">
            <div class="header">
                <div class="floatleft">
                    <a href="#"><img src="images/logorneclittle.jpg" alt="Registraduria Nacional del Estado Civil" name="Logo" width="145" height="90" id="Insert_logo" style="background-color: #8090AB; display:block;" /></a> 
                </div>
                <div class="floatleft">
                    <p class="size50">&nbsp;</p>
                    <p class="ani-verdanagriscatorce size50"><h:outputText value="#{i18n['main.titulo.titulo']}" escape="false"/></p>
                    <p class="ani-verdanaverdedieciseis size50"><h:outputText value="#{i18n['main.titulo.subtitulo1']}" escape="false"/></p>
                    <p class="ani-verdanagriscatorce size50"><h:outputText value="#{i18n['main.titulo.subtitulo2']}" escape="false"/></p>
                    <div class="floatleft"><p><a href="logout.jsp">#{i18n["main.titulo.salida"]}</a></p></div>
                    <div class="floatleft"><p><a href="cambiaclave.jsp">#{i18n["main.titulo.cambiarclave"]}</a></p></div>
                </div>
                <div class="floatright ani-normalgrisdieztitulo">
                    <p class="size30">&nbsp;</p>
                    <p class="size30">&nbsp;</p>
                    <p class="size30"><h:outputText value="#{i18n['main.label.version']}: #{i18n['srcw.version']}" escape="false"/></p>
                    <p class="size30">#{i18n["main.label.usuario"]}: <h:outputText value="#{sessionScope.nombrecompleto} - #{sessionScope.login}" styleClass="capitalized" /></p>
                    <p class="size30">#{i18n["main.label.cargo"]}: <h:outputText value="#{sessionScope.grupo}" styleClass="capitalized" /></p>
                    <p class="size30" id="reloj"></p>
                </div>
                <br class="clearfloat"/>
                <div id="menu" class="menu">
                    <h:outputText escape="false" value="#{sessionScope.menuAplicacion}"/>
                </div>
                <!-- end .header -->
            </div>
            <div id="formulario" class="content">
            <!-- a form -->
            </div>
        </div>

    </h:body>

</html>

As you can see page1 has the same structure as page2 (well, obviously i modified the template path accordingly) and there is no message error. Just when access to page2 a malformed page.

هل كانت مفيدة؟

المحلول

It's because all your CSS/JS resources are referenced using a folder-relative URI.

For example, those two

<link href="styles/menu.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>

will actually be downloaded from

http://localhost:8080/contextpath/styles/menu.css
http://localhost:8080/contextpath/js/jquery-1.8.3.min.js

when you open page1.xhtml.

However, when you open folder/page2.xhtml, the browser will attempt to download them from

http://localhost:8080/contextpath/folder/styles/menu.css
http://localhost:8080/contextpath/folder/js/jquery-1.8.3.min.js

which apparently don't exist at all. You should have noticed this mistake by just looking at the HTTP traffic monitor in browser's web developer toolset (press F12 in Chrome/Firefox>=23/IE>=9 and check Network tab).

You basically need to make those URLs domain-relative, i.e. start with a leading slash:

<link href="/contextpath/styles/menu.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="/contextpath/js/jquery-1.8.3.min.js"></script>

or if you worry about the dynamicness of the context path:

<link href="#{request.contextPath}/styles/menu.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="#{request.contextPath}/js/jquery-1.8.3.min.js"></script>

but, much better, and actually the canonical JSF way, is to put all those files in /resources folder and reference them as JSF resources using <h:outputStylesheet> and <h:outputScript> according the instructions in the answer to: How to reference CSS / JS / image resource in Facelets template?

<h:outputStylesheet name="styles/menu.css" />
<h:outputScript name="js/jquery-1.8.3.min.js" />

This way JSF will automatically worry about generating the right URL.


Unrelated to the concrete problem: that manually included jQuery JS file is recipe for trouble given that you're using PrimeFaces. See also the answer to Adding jQuery to PrimeFaces results in Uncaught TypeError over all place.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top