Jenkins classes are bound to URLs by using Stapler.
The singleton jenkins.model.Jenkins instance is bound to the context root (most of the time "/") URL, and the rest of the objects are bound according to their reachability from this root object.
Stapler uses reflection to recursively determine how to process any given URL.
A few examples of how the URL /foo/bar could be processed:
A getFoo(String) is defined on the Jenkins object, and Stapler passes bar as a parameter.
The object returned has a method called doIndex(…) that gets called and renders the response.
getFoo() is defined and returns an object that has a getBar or doBar method.
The object returned from that has an associated index.jelly or index.groovy view.
getFoo() is defined and the returned object has a view named bar.jelly or bar.groovy defined.
doFoo() is defined.
As a real-world example, the URL /job/foo/ is bound to the object returned by Hudson#getJob("foo"), which is the TopLevelItem named foo (for example, a Freestyle project or a Pipeline job).
A number of additional ways to handle requests exist, but these are the most common.
Additionally, objects can implement interfaces to further control how Stapler processes URLs:
org.kohsuke.stapler.StaplerProxy allows delegating URL processing to another object. If a getter returns an object that implements StaplerProxy, Stapler calls getTarget() and continues processing the rest of the URL on that target. This has the highest priority among URL processing options.
org.kohsuke.stapler.StaplerFallback allows delegating URL processing to another object as a fallback when no standard routing match is found. This has the lowest priority among URL processing options.
Jenkins' model objects have multiple views that are used to render HTML pages about each object. Views are written in Jelly or Groovy and can be composed of a number of different partial views (or view fragments).
Views are like methods and each of them works against a particular class.
Views are organized in resource directories corresponding to the classes they belong to (e.g. under src/main/resources/ mirroring the package and class name).
Just like methods are defined on classes, views are defined on model classes to render different representations (such as index.jelly for the main view or configure.jelly for the configuration page).
Jenkins defines several Jelly tag libraries to encourage views to have a consistent look and feel and shared structure:
Layout tags define the basic page layout of Jenkins, including headers, navigation sidepanels, task links, and page footers.
Form tags define form controls, input fields, and validation behaviors used in configuration pages.
See Taglibs for references to the available Jelly tag libraries.