users@servlet-spec.java.net

[servlet-spec users] Re: [jsr369-experts] Re: From JSF Expert Group: String HttpServletRequest.getMapping()

From: arjan tijms <arjan.tijms_at_gmail.com>
Date: Thu, 10 Sep 2015 14:00:57 +0200

Hi,

On Thu, Sep 10, 2015 at 12:59 PM, Mark Thomas <markt_at_apache.org> wrote:
> Exactly what would this method do?

The request is described in somewhat more detail here:

https://java.net/jira/browse/SERVLET_SPEC-73

> What are the use cases?

*** Usecase 1 ***

Simplifying web framework (e.g. JSF) implementation code that now
tries to find out
mapping. Specifically this should make it easier to support additional
mapping types.

For the JSF RI this is specifically referring to the code in
com.sun.faces.lifecycle.RestoreViewPhase.execute,
com.sun.faces.application.view.MultiViewHandler.derivePhysicalViewId
and com.sun.faces.util.Util.getFacesMapping/getMappingForRequest/isPrefixMapped

E.g.

 private static String getMappingForRequest(String servletPath, String
pathInfo) {

        if (servletPath == null) {
            return null;
        }
        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.log(Level.FINE, "servletPath " + servletPath);
            LOGGER.log(Level.FINE, "pathInfo " + pathInfo);
        }
        // If the path returned by HttpServletRequest.getServletPath()
        // returns a zero-length String, then the FacesServlet has
        // been mapped to '/*'.
        if (servletPath.length() == 0) {
            return "/*";
        }

        // presence of path info means we were invoked
        // using a prefix path mapping
        if (pathInfo != null) {
            return servletPath;
        } else if (servletPath.indexOf('.') < 0) {
            // if pathInfo is null and no '.' is present, assume the
            // FacesServlet was invoked using prefix path but without
            // any pathInfo - i.e. GET /contextroot/faces or
            // GET /contextroot/faces/
            return servletPath;
        } else {
            // Servlet invoked using extension mapping
            return servletPath.substring(servletPath.lastIndexOf('.'));
        }
    }



*** Usecase 2 ***

Handle virtual resources by using both default and other (e.g. exact)
mapping. If a filter for the faces servlet can determine via which
mapping it was invoked, it can take a special action first, and then
continue the chain.

For example, map the faces servlet to /foo and /. If it's invoked via
/foo, just continue the chain. If it's invoked via /bar, do something
special, then continue the chain.



*** Signature of the proposed method ***

/**
* Returns details regarding the mapping that the servlet container used
* to map the current client request to a servlet.
*
**/
public Mapping getMapping();

Definition of Mapping:

public interface Mapping {
     MappingType getMappingType(); // See Servlet spec 12.2
     String getMatch();
     String getPatern();
     boolean isImplicit(); // see Servlet spec 12.2.1
}

Definition of MappingType:

public enum MappingType {
    PATH, EXTENSION, CONTEXT_ROOT, DEFAULT, EXACT
}


Some examples:

FacesServlet mapped to /faces/*, /bar/*, *.xhtml and /foo

Request = /faces/mypage.jsf

getMappingType() - PATH
getMatch() = /mypage.jsf
getPattern() = /faces/*


Request = /bar/mypage.jsf

getMappingType() - PATH
getMatch() = /mypage.jsf
getPattern() = /bar/*


Request = /mypage.xhtml

getMappingType() - EXTENSION
getMatch() = /mypage
getPattern() = *.xhtml


Request = /foo

getMappingType() - EXACT
getMatch() = /foo
getPattern() = /foo

Hope this makes it more clear.

Kind regards,
Arjan Tijms