UrlEncoder is a simple defensive library to encode/decode URL components.
This library was adapted from the RIFE2 Web Application Framework.
A pure Java version can also be found at https://github.com/gbevin/urlencoder.
The rules are determined by combining the unreserved character set from RFC 3986 with the percent-encode set from application/x-www-form-urlencoded.
Both specs above support percent decoding of two hexadecimal digits to a
binary octet, however their unreserved set of characters differs and
application/x-www-form-urlencoded
adds conversion of space to +
,
that has the potential to be misunderstood.
This class encodes with rules that will be decoded correctly in either case.
Additionally, this library allocates no memory when encoding isn't needed and
does the work in a single pass without multiple loops. Both of these
optimizations have a significantly beneficial impact on performance of encoding
compared to other solutions like the standard URLEncoder
in the JDK or
UriUtils
in Spring.
UrlEncoderUtil.encode("a test &") // -> a%20test%20%26
UrlEncoderUtil.encode("%#okékÉȢ smile!😁") // -> %25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81
UrlEncoderUtil.encode("?test=a test", allow = "?=") // -> ?test=a%20test
UrlEncoderUtil.endode("foo bar", spaceToPlus = true) // -> foo+bar
UrlEncoderUtil.decode("a%20test%20%26") // -> a test &
UrlEncoderUtil.decode("%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81") // -> %#okékÉȢ smile!😁
UrlEncoderUtil.decode("foo+bar", plusToSpace = true) // -> foo bar
To use with Gradle, include the following dependency in your build file:
repositories {
mavenCentral()
// only needed for SNAPSHOT
maven("https://oss.sonatype.org/content/repositories/snapshots") {
name = "SonatypeSnapshots"
mavenContent { snapshotsOnly() }
}
}
dependencies {
implementation("net.thauvin.erik.urlencoder:urlencoder-lib:1.6.0")
}
Adding a dependency in Maven requires specifying the JVM variant by adding a -jvm
suffix
to the artifact URL.
<dependency>
<groupId>net.thauvin.erik.urlencoder</groupId>
<artifactId>urlencoder-lib-jvm</artifactId>
<version>1.6.0</version>
</dependency>
Instructions for using with Ivy, etc. can be found on Maven Central.
UrlEncoder can be used on the command line also, both for encoding and decoding.
You have two options:
- run it with Gradle
- build the jar and launch it with Java
The usage is as follows:
Encode and decode URL components defensively.
-e encode (default)
-d decode
./gradlew run --quiet --args="-e 'a test &'" # -> a%20test%20%26
./gradlew run --quiet --args="%#okékÉȢ" # -> %25%23ok%C3%A9k%C3%89%C8%A2
./gradlew run --quiet --args="-d 'a%20test%20%26'" # -> a test &
First build the jar file:
./gradlew fatJar
Then run it:
java -jar urlencoder-app/build/libs/urlencoder-*all.jar -e "a test &" # -> a%20test%20%26
java -jar urlencoder-app/build/libs/urlencoder-*all.jar "%#okékÉȢ" # -> %25%23ok%C3%A9k%C3%89%C8%A2
java -jar urlencoder-app/build/libs/urlencoder-*all.jar -d "a%20test%20%26" # -> a test &
Apart for being quite inefficient, some URL components encoded with URLEncoder.encode
might not be able to be properly decoded.
For example, a simple search query such as:
val u = URLEncoder.encode("foo +bar", StandardCharsets.UTF_8)
would be encoded as:
foo+%2Bbar
Trying to decode it with Spring, for example:
UriUtils.decode(u, StandardCharsets.UTF_8)
would return:
foo++bar
Unfortunately, decoding with Uri.decode on Android, decodeURI in Javascript, etc. would yield the exact same result.