In Java, percent-encoded URLs are decoded with a single call: URLDecoder.decode(percentEncodedString, StandardCharsets.UTF_8), which lives in java.net and converts every %XX sequence back into its original UTF-8 character. The two arguments matter: the input string that holds the percent groups and an explicit character set, almost always UTF-8 so emoji, accented letters, and CJK text survive the round trip. Older code that passes no charset relies on the platform default, which silently corrupts anything beyond ASCII when the server and client disagree. The newer URLDecoder.decode(String, Charset) overload makes the encoding part of the contract so the decode behaves the same on every machine. There is no need to write that throwaway snippet, however, if the goal is just to read a percent-encoded link for debugging, copy a value into an API request, or sanity-check what an OAuth callback parameter really says — a browser-based URL Decoder performs the exact same UTF-8 round trip in the page, with copy-to-clipboard and a clear error when the input is malformed.

how to decode url in java
Decode URL Strings in Java: Code and a Browser Tool

What URL Decoding Actually Means in a Java Program

URL decoding is the reverse of percent-encoding, the process that replaces unsafe characters in a web address with a percent sign followed by two hexadecimal digits. The string Hello%20World%21 becomes Hello World! after decoding, and a Chinese greeting such as %E4%BD%A0%E5%A5%BD becomes the two characters 你好 once the percent groups are read as UTF-8 bytes. RFC 3986 defines exactly which characters are reserved in a URL and which must be escaped, and that document is the authoritative reference for both the Java standard library and any third-party decoder you might use.

Java represents the encoded text as an ordinary String — there is no special URL type in the core library — and the decode happens as a string-to-string transformation. That is why the character set has to be passed in: a String is already Unicode internally, but the bytes that produced it were interpreted using some encoding on the way in, and you have to tell the decoder which one to use when it groups the percent sequences back into characters.

The Exact Java Code to Decode a Percent-Encoded URL

The minimum working snippet is three lines. The first line is the input, the second line does the work, the third line is the result.

StepCode
1. Define the encoded inputString encoded = "Hello%20World%21%F0%9F%91%8B";
2. Decode with UTF-8String decoded = URLDecoder.decode(encoded, StandardCharsets.UTF_8);
3. Result// decoded == "Hello World! 👋"

The third line shows the round trip: a space, an exclamation mark, and a four-byte emoji each came back intact. The newer two-argument form of URLDecoder.decode takes a Charset object, which removes any ambiguity about which encoding is in use. If you are working with pre-Java 10 code, the older one-argument form URLDecoder.decode(String) still exists but is deprecated precisely because it falls back to the platform default charset, which is rarely what you want on a server.

For an entire URL string rather than a single value, you can decode the whole thing the same way.

StepCode
1. Define the encoded URLString fullUrl = "https%3A%2F%2Fexample.com%2Fsearch%3Fq%3Djava%20url%20decode";
2. Decode with UTF-8String readable = URLDecoder.decode(fullUrl, StandardCharsets.UTF_8);
3. Result// readable == "https://example.com/search?q=java url decode"

Notice that %3A became :, %2F became /, and %3F became ?. The decoder does not know or care that the result looks like a URL — it just turns percent groups into characters. If you decode the structural characters of a URL, you lose the ability for code to parse the result as an address; that is one reason a Component mode versus Full URL mode distinction exists in browser tools.

When a Browser Tool Saves You From Writing Java

Writing Java has a cost even for a one-line decode. You need a JDK, a project, a main class, a build step, and an IDE or at least a terminal. If you just want to read a percent-encoded link someone pasted in chat, decode an OAuth callback value to see what it really contains, or confirm that the percent groups in a query string match the original search term, none of that overhead is justified. A browser tool that runs the same UTF-8 decode in JavaScript gives you the answer in the time it takes to paste the string.

The URL Decoder runs entirely in the browser, which means percent-encoded tokens, callback URLs with embedded secrets, and internal links never leave the device. There is no upload, no account, no server-side log of your input, and the page keeps working once it has loaded so you can use it offline. It also surfaces errors honestly: a stray percent sign or a truncated multi-byte sequence produces a clear message instead of a corrupted string, which mirrors the behavior of the Java decode method when it throws IllegalArgumentException.

How to Decode a URL in Your Browser with the URL Decoder

  1. Open the URL Decoder page in your browser.
  2. Pick a scope. Choose URL component when the input is a single query value, path segment, or fragment — every reserved character will be handled correctly. Choose Full URL when the input is a complete web address whose structure (colon, slashes, question mark, hash) you want preserved while only the genuinely unsafe characters get escaped or unescaped.
  3. Pick a direction. For decoding, select Decode so the tool reverses percent-encoding rather than applies it.
  4. Paste your percent-encoded text into the input box. The output updates as you type, so you can watch each percent group turn back into its original character the moment it is recognized.
  5. If the input is malformed — a lone %, a percent sign followed by non-hex characters, or a cut-off multi-byte sequence — the tool stops and shows a specific error message pointing at the problem rather than producing a corrupted string.
  6. Click Copy to put the decoded result on your clipboard, ready to paste into an editor, a chat message, an API request body, or a Java source file.

Component Mode vs Full URL Mode for Decoding

The two scopes matter because the same percent-encoded string can mean different things depending on context. A Component is a single piece of a URL such as one q= value or one path segment; a Full URL is the whole address. The table below shows how the choice changes what the decoder does.

AspectComponent modeFull URL mode
Input typeOne query value, path segment, or fragmentA complete web address
Reserved charactersAll escaped on encode, all reversed on decodePreserved (colon, slashes, ?, #)
Typical input examplejava%20url%20decode%21https%3A%2F%2Fexample.com%2Fpath%3Fa%3D1
Typical output examplejava url decode!https://example.com/path?a=1
Best forOne value inside a query string or pathCleaning up or reading a whole link

Pick Component mode when the percent-encoded text is only the value side of key=value, the contents of a single path segment, or the fragment after #. Pick Full URL mode when the input already has the shape of an address — scheme://host/path?query#fragment — and you want that structure preserved. For pure Java decoding of a full URL string, you can call URLDecoder.decode the same way; the tool just makes the choice explicit and visible.

Why Decoding Errors Surface (and How to Fix Them)

The Java decoder throws IllegalArgumentException when it encounters a percent sign that is not followed by two hexadecimal digits. The browser tool produces the same outcome as a readable error message. The common culprits are: a string that was double-encoded somewhere upstream, a manually edited link where someone deleted two characters and left a stray %, a UTF-8 sequence that was truncated because of a buffer size limit, or non-standard hex like %zz introduced by a buggy client. The fix is to look upstream at whatever produced the encoded string and re-encode it cleanly, rather than trying to patch the decoded output.

According to RFC 3986, the two hex digits after a percent sign must come from the set 0-9 A-F a-f. Anything outside that set is, by definition, malformed. The Java decoder and the browser tool both treat malformed input as a hard failure for that reason: returning a broken string would let corrupted data flow downstream into a database, an analytics pipeline, or an API request.

Java Code vs Browser Tool: Choosing the Right Approach

Both paths produce the same correct output for valid input. The decision is about where the work belongs. The table below summarizes the practical differences.

AspectJava URLDecoder.decodeBrowser URL Decoder
Where it runsInside a JVM, in your applicationInside the browser tab, in plain JavaScript
Setup neededJDK, project, build, IDE or terminalOpen the page
NetworkNone — runs locallyNone — runs locally after the page loads
Character setExplicit Charset argument (UTF-8 recommended)UTF-8 by default
Error behaviorThrows IllegalArgumentExceptionShows a clear inline error
Best forProduction code, automated pipelines, testsDebugging, one-off checks, reading shared links
Data handlingStays on the machine where the JVM runsStays in the browser; nothing uploaded

For application code that processes user input or API responses, stick with java.net.URLDecoder.decode in the JVM — that is where the work belongs. For ad-hoc debugging, decoding a URL someone pasted into a ticket, or inspecting a tracking parameter, the URL Decoder tool is faster than spinning up a Java project and gives the same UTF-8-correct answer.

One last practical note: when decoding in Java, prefer the two-argument decode(String, Charset) form and pass StandardCharsets.UTF_8 explicitly. The single-argument form is deprecated and uses the platform default, which on a server is rarely UTF-8 and quietly mangles non-ASCII characters. The browser tool already does the equivalent — every percent group is interpreted as UTF-8 — so you do not have to think about it. The MDN documentation for encodeURIComponent and decodeURIComponent describes the same UTF-8 contract for the underlying browser functions.