To URL encode a value in Java, use URLEncoder.encode(value, StandardCharsets.UTF_8) for query-string parameters — but never assume it produces a correct full URL, because URLEncoder is built for application/x-www-form-urlencoded form data, not for encoding an entire address. That single misunderstanding is behind most of the broken links, double-encoded parameters, and open-redirect bugs that show up when developers URL encode in Java. This guide covers how to encode a URL in Java the right way and where the sharp edges are.
The one method most people reach for
If you learn to url encode java values from Stack Overflow, you land on this:
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
String raw = "hello world & friends";
String encoded = URLEncoder.encode(raw, StandardCharsets.UTF_8);
// hello+world+%26+friends
The StandardCharsets.UTF_8 overload arrived in Java 10; before that you passed the string "UTF-8" and caught a checked exception. Always specify UTF-8 explicitly. Relying on the platform default charset is how the same code produces different output on a developer's laptop and a Linux server, which turns into intermittent, hard-to-reproduce bugs.
Why URLEncoder is not a URL encoder
Here is the trap that makes people who want to java encode url values pull their hair out: URLEncoder encodes a space as +, not %20. That is correct for the body of an HTML form submission, but it is wrong inside the path of a real URL, where + is a literal plus sign and a space must be %20.
So if you do this:
String url = "https://example.com/search?q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
the query-string portion is fine. But if you ever feed URLEncoder output into a path segment, or you encode an already-complete URL, you corrupt it. URLEncoder.encode("https://example.com/a b") will happily turn the :// and / into percent sequences, giving you a string that is no longer a usable address. URLEncoder does not know about URL structure — it just percent-encodes everything that is not in its allow-list.
Encoding the parts, not the whole
The correct mental model for how to encode url in java is: a URL has parts (scheme, host, path, query, fragment), each with its own encoding rules, and you encode each part for its own context. Do not encode a URL; build it from encoded components.
For query parameters, URLEncoder is acceptable as long as you understand the + behavior. For assembling a whole URL — especially paths — prefer java.net.URI, which is aware of URL structure:
import java.net.URI;
URI uri = new URI("https", "example.com", "/reports/2025 Q1", "type=pdf&lang=en", null);
String safe = uri.toASCIIString();
// https://example.com/reports/2025%20Q1?type=pdf&lang=en
Notice the space in the path became %20, exactly as it should. This multi-argument URI constructor encodes each component according to its role, which is why it is the safer choice when you need to encode a url java-side and produce something that will actually resolve. In Spring applications, UriComponentsBuilder gives you the same part-aware encoding with a fluent API.
Where encoding becomes a security problem
Encoding is not just cosmetic. Get it wrong and you create injection surface. Three patterns recur.
Failing to encode user input in a redirect. If you build a Location header by concatenating unencoded user input, an attacker can inject CRLF sequences or steer the redirect to an external host. Encode the value, and validate that the destination is on an allow-list of hosts — encoding alone does not stop an open redirect if you let the user control the whole target.
Double encoding. When a value is encoded twice, %20 becomes %2520. Some downstream systems decode once, some decode twice, and the mismatch is a classic filter-bypass technique. The fix is to be explicit about how many times a value crosses an encode boundary and to encode exactly once at the point of URL construction. If you need to java url encode string data that may already be partly encoded, decode to a canonical form first, then re-encode once.
Trusting encoding as validation. Encoding makes a value safe to transport; it does not make the value legitimate. A URL-encoded SQL payload is still a SQL payload once your backend decodes it. Encoding belongs at the boundary where you construct requests; parameterized queries and output escaping still belong at the database and the view. Treating "I encoded it" as "I sanitized it" is a common false sense of safety that an SCA and code-analysis tool will flag when tainted input reaches a sink without real validation.
A checklist for encoding URLs in Java
When you need to encode url java code cleanly, run through this:
- Use
URLEncoder.encode(value, StandardCharsets.UTF_8)only for individual query-parameter values, and remember spaces become+. - Use
java.net.URI(orUriComponentsBuilderin Spring) to assemble complete URLs, so each component is encoded for its own context. - Never call
URLEncoder.encodeon a whole URL string. - Encode exactly once; hunt down accidental double-encoding.
- Validate redirect and callback targets against an allow-list; encoding is not authorization.
- Always specify the charset explicitly — never depend on the platform default.
Follow those and the everyday task of how to encode url in java stops producing the broken links and subtle bypasses that make it a recurring support ticket.
FAQ
What is the difference between URLEncoder and URI in Java?
URLEncoder percent-encodes a string for application/x-www-form-urlencoded content and encodes spaces as +. java.net.URI understands URL structure and encodes each component (path, query, fragment) according to its own rules, so it is the right tool for building a complete, valid URL.
Why does URLEncoder.encode turn spaces into plus signs?
Because it implements form encoding, where + is the defined representation of a space. That is correct in a form body but wrong in a URL path, where a space must be %20. This mismatch is the most common Java URL-encoding bug.
Does URL encoding protect against injection attacks?
No. Encoding makes a value safe to transmit inside a URL, but the receiver decodes it back to the original bytes. You still need parameterized queries, output escaping, and allow-list validation at the destination. Encoding is transport hygiene, not input sanitization.
Which charset should I use when I URL encode a string in Java?
Always UTF-8, passed explicitly via StandardCharsets.UTF_8. Relying on the JVM's default charset makes output environment-dependent and causes inconsistent behavior between machines.