Set default home page via <welcome-file> in JSF project
Asked Answered
M

3

12

I am unable to set a default page that loads in the browser when I start a Java EE project using Tomcat 8.0 from Eclipse. I am trying to learn JSF, so I followed this tutorial

Everything works fine, but I can only see the created pages when I right click on the login.xhtml or welcome.xhtml file and choose "Run As/Run on Server".

So far, all the other web applications I have created loaded default page when I started the entire project. The default behavior is to load index.html page (or maybe index.jsp if there is some). So I added index.html and index.xhtml pages into my WEB-INF folder in the project, hoping that at least one of them will be shown. However, nothing happens. The browser always shows just the page on localhost:8080/JSFFaceletsTutorial/ URL, but the page is white clean, not even an error message. I think I have been getting error 404 in the process of solving this issue along the way, however, I am no longer able to reproduce this error and I don't remember what caused it.

I found that it's possible to change the default starting page

However, it doesn't work for me either. Regardless if I edit the web.xml file or not, I am getting the same result.

What is even more puzzling, is that when I tried to change the web browser: "Window/Web Browser/..." it acted for a while differently in the external web browsers than in the internal Eclipse web browser. The internal had always blank page - but the external web browsers once managed to show the index.html page - but it was some outdated version. Despite I made absolutely sure that I edited it, saved the changes, restarted the server... and still, it showed me the outdated version of the page. And even in this case, it still ignored the changes made in the web.xml file. But when I am trying it now, it again shows blank white page in all browsers. I am not aware of any change I made except for editing web.xml file...

My guess is that the problem is in the JSF technology I don't fully grasp yet. It's because when I choose to run the login.xhtml and welcome.xhtml pages using right click "Run As/Run on Server", the URL of those pages are on localhost:8080: with path /JSFFaceletsTutorial/faces/login.xhtml and /JSFFaceletsTutorial/faces/welcome.xhtml. That is weird, because I don't have any directory "faces" in my project. Typing all possible permutations of:

<welcome-file-list>
    <welcome-file>faces/index.html</welcome-file>
    <welcome-file>faces/index.xhtm</welcome-file>
</welcome-file-list>

in the web.xml didn't help either. It didn't help when I typed the full address there either.

Here are warnings I am getting in the console (I skipped the INFO log entries):

"Dec 19, 2014 9:39:55 AM org.apache.tomcat.util.digester.SetPropertiesRule begin WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:JSFFaceletsTutorial' did not find a matching property. ... WARNING: JSF1074: Managed bean named 'loginBean' has already been registered. Replacing existing managed bean class type com.tutorial.LoginBean with com.tutorial.LoginBean. Dec 19, 2014 9:39:57 AM org.apache.coyote.AbstractProtocol start"

I am not sure this is helpful though. I am out of ideas now.

Mudslinger answered 19/12, 2014 at 9:15 Comment(1)
I think its just <welcome-file>index.xhtml</welcome-file>? All your files are named .xhtml? so that would be the first guess. Note if you use a servlet mapping for the JSF servlet (*.jsf) to point to .xhtml files the welcome file will not be able to pick it up. It needs to be a physical file.Jaf
T
16

First of all, the <welcome-file> does not represent the path to the "default home page". It represents the filename of the physical file contained in the folder which you'd like to serve up as default file when a folder like /, /foo/, /foo/bar/, etc is requested.

So, in JSF 2.x flavor, that would basically be:

<welcome-file-list>
    <welcome-file>index.xhtml</welcome-file>
</welcome-file-list>

This way, if the enduser requests / and you have /index.xhtml, then it will be served. Or, if the enduser requests /foo and you have /foo/index.xhtml, then it will be served, etc. If there is no such file, then a 404 error will be returned.

Now, you appear to have mapped your FacesServlet on a prefix <url-pattern> of /faces/*. This is a leftover from JSF 1.0/1.1 ages and really not recommended these days. Perhaps you were reading an outdated tutorial targeted at JSF 1.x, or a poorly maintained tutorial which was originally written for JSF 1.x and then uncarefully updated for JSF 2.x instead of rewritten from scratch.

That tutorial did also not seem to have explained you some servlet basics. Namely, in order to get JSF components in the XHTML page to run and generate some HTML output, the FacesServlet has to be invoked when the XHTML page is being requested. When you request the XHTML page like so /index.xhtml, while the FacesServlet is being mapped on /faces/*, then it won't be invoked. The browser would then retrieve the raw unparsed JSF source code instead of the generated HTML output. You can see it by rightclick, View Source in webbrowser. You should have requested the page like so /faces/index.xhtml so that the FacesServlet can run and produce HTML output which the browser can understand and present.

That only doesn't go well together with welcome files. This totally explains why you get a "clean white" (blank) page when using index.xhtml as welcome file (some inferior webbrowsers like IE would confusingly prompt a download dialog because of missing/wrong content type on the response containing raw XHTML source code). The FacesServlet was simply not being invoked. Just get rid of the old fashioned /faces/* URL pattern and use the JSF 2.x minded *.xhtml URL pattern instead.

<servlet-mapping>
    <servlet-name>facesServlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

This way the welcome files should work and you can just open JSF pages by directly requesting its physical URL without hassling with virtual URLs. This was not possible in JSF 1.x because it would let the FacesServlet run in an infinite loop calling itself and cause a stack overflow.

See also:


As to those warnings, they are unrelated but quite googlable.

Tammany answered 19/12, 2014 at 10:5 Comment(2)
Yeah, I knew that it represents only physical file. I just didn't explain it right. I was not trying to run those pages login.xhtml and welcome.xhtml on default. I was trying to create a new page with a link to this login page. That new page would be just a new simple physical file. I knew about servlets, I was working on jsp pages few years back. Though thanks for the third link especially. It will come in handy. It works now, it was problem with the servlet-mapping tag. Interesting that this was not allowed in JSF 1...Mudslinger
@Tammany I'm fiddling with this issue at the moment. I want to have custom mapping so I replaced /faces/* with *.html. However, my index page is behaving unexpected. I tried <welcome-file>index.html</welcome-file> but it only displays my title in the upper left corner (I'm using template, with <ui:composition>. When I inspect the source code, it shows the source code of the index file itself. If I put the xhtml back, both for welcome file and the mapping, it works again. So, it seems that they need to be in sync. Is there a way to solve this?Attenborough
L
0

You can set a default page in the web.xml file to have the facesServlet invoked in JSF in 2 ways:

<web-app xmlns="http://xmlns.xyz.org/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.xyz.org/xml/ns/javaee http://xmlns.xyz.org/xml/ns/javaee/web-app_4_0.xsd"
     version="4.0">
    <servlet>
        <servlet-name>facesServlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>facesServlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

or invoke the facesServlet directly from the welcome file like this:

<web-app xmlns="http://xmlns.xyz.org/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://xmlns.xyz.org/xml/ns/javaee http://xmlns.xyz.org/xml/ns/javaee/web-app_4_0.xsd"
 version="4.0">
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

I hope it helps somebody!

Leftwich answered 22/6, 2018 at 11:21 Comment(0)
G
0

i think this will work

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.xyz.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.xyz.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <welcome-file-list>
    <welcome-file>/main/login.xhtml</welcome-file>
      </welcome-file-list>
<!--         <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>com.xyz.servlets.login</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping> -->

</web-app>
Grandiloquent answered 30/5, 2019 at 8:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.