It took me a while to get welcome files working with the SpringMVC web
framework.
I created the attached servlet to get things working properly. It requires
servlet spec 2.4, and it works by mapping the welcome file to a servlet,
WelcomeFileServlet, rather than direct to a JSP. The WelcomeFileServlet then
forwards it on to the correct servlet, and makes sure that the requestURI
returns the right value (e.g. /index.htm rather than just /) It should work
fine with JSF, if you configure it properly.
Here's an example of how to configure it in web.xml
<servlet>
<servlet-name>WelcomeFileServlet</servlet-name>
<servlet-class>com.mbromley.util.servlet.WelcomeFileServlet</servlet-class>
<init-param>
<param-name>forward-to-servlet-name</param-name>
<param-value>DispatcherServlet</param-value>
</init-param>
<init-param>
<param-name>welcome-file</param-name>
<param-value>index.htm</param-value>
</init-param>
</servlet>
It works by mapping the index page (index.htm in my case, index.faces or
whatever in yours) to the WelcomeFileServlet:
<!-- Exact mappings are needed below for the welcome-file feature to work
with WelcomeFileServlet. -->
<servlet-mapping>
<servlet-name>WelcomeFileServlet</servlet-name>
<url-pattern>/index.htm</url-pattern>
</servlet-mapping>
and then defining the welcome file as
<!-- This relies on the 2.4 spec allowing mappings to a servlet as opposed to just
a real file (index.htm doesn't exist as a real file in any of the directories this
feature is required). The WelcomeFileServlet docs have lots of info on the correct
setup of that class. -->
<welcome-file-list>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
Take a look at the docs with the attached file for more.
Hope it helps,
Martin with an 'i' ;-)
Marten Lehmann wrote:
Hello,
I tried to put the following into web.xml:
<welcome-file-list>
<welcome-file>index.faces</welcome-file>
</welcome-file-list>
But obviously, this doesn't work, because there is no file index.faces,
but index.jsp. However, if the index.jsp isn't called through
index.faces, the FacesContext isn't used. How can I achieve this as
expected? I don't want to use the plain old workaround with an
index.html containing a refresh.
Regards
Marten
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
package com.mbromley.util.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/** This enables the URLs in an HttpServletRequest to be consistently rewritten.
* This needs to be extended for it to do anything useful. At least one of the
* rewriteURL methods needs to be overridden.
*/
public abstract class URLRewritingRequestWrapper
extends HttpServletRequestWrapper {
public URLRewritingRequestWrapper(
final HttpServletRequest request) {
super(request);
}
@Override
public final String getPathInfo() {
return getPossiblyNull(super.getPathInfo());
}
@Override
public final String getPathTranslated() {
return getPossiblyNull(super.getPathTranslated());
}
@Override
public final String getRequestURI() {
return rewriteURL(super.getRequestURI());
}
@Override
public final StringBuffer getRequestURL() {
return rewriteURL(super.getRequestURL());
}
@Override
public final String getServletPath() {
return rewriteURL(super.getServletPath());
}
private String getPossiblyNull(final String s) {
if (s == null) {
return null;
}
return rewriteURL(s);
}
/** Subclasses can override this if they can improve efficiency by
rewriting
* a StringBuffer. By default this calls the other method and creates
a new
* StringBuffer from the result.
*/
protected StringBuffer rewriteURL(final StringBuffer sB) {
return new StringBuffer(rewriteURL(sB.toString()));
}
protected abstract String rewriteURL(final String url);
@Override
public String toString() {
return super.toString() + " wrapping " +
getRequest().toString();
}
}package com.mbromley.util.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/** <p>Enables welcome-file configuration in web.xml to work with frameworks
* such as SpringMVC (and presumably Struts).</p>
*
* <p>welcome-file enables an application to configure default files that are
* accessed when somebody enters a URL such as www.domain.com/. It can be
* difficult to integrate this functionality with an MVC framework such as
* SpringMVC. The following are issues that complicate matters:</p>
*
* <ul>
* <li>welcome-file configuration is allowed to occur in a number of ways
* according to the servlet spec. "The container may send the request
* to the welcome resource with a forward, a redirect, or a container specific
* mechanism that is indistinguishable from a direct request."</li>
*
* <li>If there isn't a redirect, the ServletRequest can have the wrong
* parameters in its methods such as getRequestURI - this means that the e.g.
* DispatcherServlet can't figure out which page it's supposed to send the
* request. Tomcat certainly has this issue.</li>
*
* <li>Since servlet 2.4, a welcome-file is allowed to send to a servlet as well
* as a file (which is good). "The Web server must append each welcome file in
* the order specified in the deployment descriptor to the partial request and
* check whether a static resource or servlet in the WAR is mapped to that
* request URI."</li>
*
* <li>Testing with Tomcat 5.7 reveals that a map to a servlet occurs whether or
* not the servlet-mapping is an exact match (e.g. "/index.htm", or "/index", or
* "*.htm").</li>
*
* <li>So, if the welcome-file is listed as index.htm, and the SpringMVC
* DispatcherServlet (or equivalent) is matched to *.htm, the request will get
* routed there (or redirected). Explicit mappings would have to be made in
* SpringMVC to deal with a / request - if the welcome file has to be dealt with
* as an explicit case it's probably better to deal with it outside of SpringMVC
* so that any framework can handle it.</li>
*
* <li>It is possible to use a jsp file that forwards to the required URL
* (e.g. index.htm) that will reach the MVC controller servlet. However,
* the problem with that is that an MVC app would usually be set up to block
* direct access to *.jsp: because the welcome-file can happen with a redirect,
* it wouldn't be possible to block all jsp files (e.g. start.jsp, which would
* do the forwarding would have to be specified elsewhere). In Tomcat, for
* example, a filter set up to block access to all JSP files stops a
* welcome-file of start.jsp from working. This also means that the server
* would no longer be platform agnostic in the urls it exposed.
* This is especially concerning if a container redirected to start.jsp: a user
* might bookmark that implementation detail of the site.</li>
*
* <li>Tomcat web.xml defines default welcome-files that it looks for. They
* have no effect if the context web.xml defines a welcome-file-list.</li>
* </ul>
*
* <li>Using a url-pattern of / to map to a specific servlet (for Tomcat this
* required getting rid of the welcome-file-list in the Tomcat web.xml, and not
* putting one in the web.xml of the context) appears to cause problems in
* different containers. In Tomcat it certainly seemed to cause problems,
* although it seemed to work in the base directory.
* See <a href="http://forum.java.sun.com/thread.jspa?ageID=1131960">this
* thread</a> for problems with other containers.</li>
*
* <li>There was a
* <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=9016">bug in
* Tomcat</a> that meant that a real file had to exist for the welcome-file
* mapping to a servlet to work, but that was fixed in version 5. A hack was
* to create an empty real file (e.g. index.htm) for every directory in which
* the welcome file was supposed to work.</li>
*
* <p>This simple servlet offers a solution that works with Servlet 2.4+. It
* simply forwards onto another named servlet (specified in an init-parameter),
* and wraps the request so that any Url related methods ending in a "/" have
* the welcome-file appended to them (the welcome-file is specified in another
* init parameter).</p>
*
* <p>Guidance notes:</p>
*
* <ul>
* <li>web.xml must should contain a welcome-file (e.g. index.htm).</li>
*
* <li>The welcome-file init parameter to this servlet should be the same.</li>
*
* <li>An exact servlet-mapping should be made to every url for which this
* welcome-file is expected to work. For example, one to "/index.htm", one to
* "/user/index.htm" etc.</li>
* </ul>
*
* @author Martin Bromley
*
*/
public class WelcomeFileServlet extends HttpServlet {
private static final long serialVersionUID = 3761410819778163249L;
public static final String FORWARD_TO_SERVLET_NAME_INIT_PARAMETER =
"forward-to-servlet-name";
public static final String WELCOME_FILE_INIT_PARAMETER = "welcome-file";
private RequestDispatcher requestDispatcher;
private String welcomeFile;
@Override
public void init() throws ServletException {
final String servletName =
getInitParameter(FORWARD_TO_SERVLET_NAME_INIT_PARAMETER);
if (servletName == null) {
throw new ServletException("Init parameter "
+ FORWARD_TO_SERVLET_NAME_INIT_PARAMETER + "
not specified. "
+ "This servlet needs to forward onto another
one.");
}
requestDispatcher =
getServletContext().getNamedDispatcher(servletName);
if (requestDispatcher == null) {
throw new ServletException("RequestDispatcher could not
be "
+ "found with the name specified in the "
+ FORWARD_TO_SERVLET_NAME_INIT_PARAMETER + "
init parameter: "
+ servletName);
}
welcomeFile = getInitParameter("welcome-file");
if (welcomeFile == null) {
throw new ServletException("The init parameter "
+ WELCOME_FILE_INIT_PARAMETER + " is
required.");
}
}
@Override
protected void doGet(final HttpServletRequest request,
final HttpServletResponse response)
throws ServletException, IOException {
requestDispatcher.forward(new RequestWrapper(request),
response);
}
private class RequestWrapper extends URLRewritingRequestWrapper {
RequestWrapper(final HttpServletRequest request) {
super(request);
}
@Override
protected String rewriteURL(final String url) {
if (url.endsWith("/")) {
return url + welcomeFile;
} else {
return url;
}
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]