Btw that still requires catching exceptions, unlike Jetty's URIUtil all commons URIUtil encode/decode methods throw URIException, which is lame since most people want standard byte-by-byte encoding.
Please elaborate because I'm not sure I follow your reasoning... Why would byte-for-byte be desirable? Perhaps I'm misunderstanding, but if the client uses a different local charset to encode special chars, then server-side decoding will fail. Why should this preclude the exception?
Assuming the exception is masked, are you going to change the callers to check for null and throw an exception? Putting a literal "null" in a URI when there's an encoding problem is not acceptable. That's messy to handle in the caller, which is why I think the exception shouldn't be masked.
Preconditions.checkArgument(request.getRequestURI().startsWith(servletName)). Otherwise the substring might chop something else off if the function is misused.
Should this be startsWith(servletName+"/") to avoid accidently matching a servlet prefix? Ie. something like "getItem" vs "getItem(s)".