src/main/java/js/servlet/RequestPreprocessor.java
@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		String requestURI = httpRequest.getRequestURI();
		String contextPath = httpRequest.getContextPath();
		String requestPath = requestURI.substring(contextPath.length());

		// request-uri = context-path request-path
		// context-path = "/" path-component
		// request-path = 1*("/" path-component)

		File file = new File(request.getServletContext().getRealPath(requestPath));
		if (file.exists()) {
			chain.doFilter(request, response);
			return;
		}

		// request-path = ["/" locale] ["/" security-domain] 1*("/" path-component)

		RequestContext context = container.getInstance(RequestContext.class);

		String queryString = httpRequest.getQueryString();
		context.setRequestURL(queryString != null ? Strings.concat(requestURI, '?', queryString) : requestURI);

		if (!locales.isEmpty()) {
			for (String locale : locales) {
				if (startsWith(requestPath, locale)) {
					requestPath = requestPath.substring(locale.length() + 1);
					context.setLocale(new Locale(locale));
					break;
				}
			}
		}

		for (String securityDomain : securityDomains) {
			if (startsWith(requestPath, securityDomain)) {
				requestPath = requestPath.substring(securityDomain.length() + 1);
				context.setSecurityDomain(securityDomain);
				break;
			}
		}

		context.setRequestPath(requestPath);
		request.getRequestDispatcher(requestPath).forward(request, response);
	}
@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		String requestURI = httpRequest.getRequestURI();
		String contextPath = httpRequest.getContextPath();
		String requestPath = requestURI.substring(contextPath.length());

		// request-uri = context-path request-path
		// context-path = "/" path-component
		// request-path = 1*("/" path-component)

		File file = new File(request.getServletContext().getRealPath(requestPath));
		if (file.exists()) {
			chain.doFilter(request, response);
			return;
		}

		// request-path = ["/" locale] ["/" security-domain] 1*("/" path-component)

		RequestContext context = container.getInstance(RequestContext.class);

		String queryString = httpRequest.getQueryString();
		context.setRequestURL(queryString != null ? Strings.concat(requestURI, '?', queryString) : requestURI);

		if (!locales.isEmpty()) {
			for (String locale : locales) {
				if (startsWith(requestPath, locale)) {
					requestPath = requestPath.substring(locale.length() + 1);
					context.setLocale(new Locale(locale));
					break;
				}
			}
		}

		for (String securityDomain : securityDomains) {
			if (startsWith(requestPath, securityDomain)) {
				requestPath = requestPath.substring(securityDomain.length() + 1);
				context.setSecurityDomain(securityDomain);
				break;
			}
		}

		context.setRequestPath(requestPath);
		request.getRequestDispatcher(requestPath).forward(request, response);
	}
Search request URI for locale and security domain, by comparing with internal lists, and remove found values. Update
locale, security domain and request path on context request from current thread, see
{@link RequestContext#setLocale(Locale)}, {@link RequestContext#setSecurityDomain(String)} and
{@link RequestContext#setRequestPath(String)}.
<p>
Remove locale and security context from current request URI and forward it. If current request URI is for a static
resource, that is, an existing file this filter does nothing.
<p>
It is considered a resource not found and rejected with 404 if a request URI contains a locale code that is not listed
into filter parameter. If <code>locale</code> filter parameter is not declared all locale code that may be present into
request URI are passed unprocessed. If request URI contains a security domain that is not listed into
<code>security-domain</code> filter parameter, it is forwarded unprocessed.

@param request servlet request,
@param response servlet response,
@param chain filter chain.
@throws IOException for failure on underlying request and response streams.
@throws ServletException if filter chaining or request forwarding fails.