3

I am trying to create a URI in Java, where my query string has a : in it. However, no matter how I try to create the URI, I get an invalid response.

new URI("http", "localhost:1181", "/stream.mjpg", "part1:part2", null).toString(); gives me http://localhost:1181/stream.mjpg?part1:part2, without the : in the query string being escaped.

If I escape the query string before creating the URI, it escapes the % in the %3A, giving %253A, which is incorrect.

new URI("http", "localhost:1181", "/stream.mjpg", "part1%3Apart2", null).toString(); gives http://localhost:1181/stream.mjpg?part1%253Apart2

My result needs to be http://localhost:1181/stream.mjpg?part1%3Apart2 because my server requires : to be encoded in query strings`

Is there something I am missing, or am I going to have to manually create the query string?

Thad House
  • 133
  • 1
  • 7
  • 1
    "because my server requires `:` to be encoded in query strings" can you share what server are you using? – Pshemo Mar 03 '19 at 23:37
  • Its trying to connect to a custom mjpeg server written by an outside vendor. Its very non complaint, but we need to support it. It does other non complaint things as well, like requiring `%20` for spaces and not `+`. – Thad House Mar 03 '19 at 23:40
  • 2
    Well, URI doesn't see any need to encode `:` in *query* part since it doesn't represent any metacharacter in that or later sections of URI. Way around would be creating URI without query, convert it to string and then manually add encoded keys and values. – Pshemo Mar 04 '19 at 00:05
  • It is printing correctly for me that is "http://localhost:1181/stream.mjpg?part1:part2". Using Java 8 and URI from java.net package. May I ask what version of java and package you are using? – Parisana Ng Mar 03 '19 at 22:59
  • That is not correct. I need my result to be `http://localhost:1181/stream.mjpg?part1%3Apart2`. I edited my post to add this, because I realized I had forgotten it. – Thad House Mar 03 '19 at 23:03
  • replace part1:part2 with URLEncoder.encode("part1:part2", "UTF-8") – Parisana Ng Mar 03 '19 at 23:08
  • That doesn't work, the 2nd URI creator I posted was doing that, and that was also failing. That causes a double encoding of the %, giving `part1%253Apart2` – Thad House Mar 03 '19 at 23:10
  • The % is url encoded to %25 and thats why you are getting %253A, you can use URLDecoder to decode it to %3A again and vice versa – Parisana Ng Mar 03 '19 at 23:17
  • That's not a solution for me, I have a server that requires I encode any `:` as `%3A`, it doesn't handle either `:` or `%253A`. It requires `%3A`. – Thad House Mar 03 '19 at 23:20
  • https://stackoverflow.com/a/5330239/4412613 says Colon is a reserved character, so : will still remain a colon, after encoding. – Parisana Ng Mar 04 '19 at 00:04
  • 1
    @PariNgang `:` is reserved in URI but not in *all* its sections. It is reserved in `scheme://user:password@address.of.server:port` but after that it is no longer special, so `/path` can contain it, same as `?query=val` or `#fragment` which is why URI constructor doesn't encode it. – Pshemo Mar 04 '19 at 00:18

1 Answers1

1

It’s not pretty, but you can use URLEncoder on just the query part:

String query = URLEncoder.encode("part1:part2", StandardCharsets.UTF_8);
// Required by server.
query = query.replace("+", "%20");

String uri =
    new URI("http", "localhost:1181", "/stream.mjpg", null, null)
    + "?" + query;
VGR
  • 40,506
  • 4
  • 48
  • 63