Java/Kotlin URLEncoder与Python urlencode输出不一致问题求助
urllib.parse.urlencode Behavior in Kotlin/Java I get it—your current Kotlin approach is encoding the entire parameter string as a single value, which is why you're seeing mismatches with Python's output: the = and & separators are getting encoded, and the * isn't being handled the same way as in Python. Let's fix this to produce an identical URL-encoded string.
The Root of the Difference
Python's urlencode works by:
- Taking a list of key-value pairs
- Encoding each key and value individually
- Joining them with
&(leaving=and&as unencoded separators) - Encoding characters like
*to%2A
Java/Kotlin's URLEncoder.encode, by contrast, treats the entire input string as a single URL parameter value—so it encodes separators like = and &, and doesn't encode * by default.
The Fix: Encode Key-Value Pairs Individually
Instead of building the parameter string first and then encoding it, we'll encode each key and value separately, then assemble the final string. We'll also manually handle the * encoding since Java's encoder skips it.
Here's the corrected Kotlin code:
import java.net.URLEncoder import java.nio.charset.StandardCharsets fun createVxttokenData(pathUri: String, expiry: Long, reuse: Int, sharedSecret: String) { // Match Python's list of key-value pairs structure val params = listOf( "pathURI" to pathUri, "expiry" to expiry.toString(), "reuse" to reuse.toString() ) // Encode each key-value pair and join with & separators val urlEncodedMessage = params.joinToString("&") { (key, value) -> val encodedKey = URLEncoder.encode(key, StandardCharsets.UTF_8.name()) // Encode value and replace * with %2A to match Python's encoding behavior val encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8.name()) .replace("*", "%2A") "$encodedKey=$encodedValue" } println(urlEncodedMessage) // ... rest of your token generation code } fun main() { val samplePathUri = "http://my.domain.net/*" val sampleExpiry = 1553937508L val sampleReuse = 0 createVxttokenData(samplePathUri, sampleExpiry, sampleReuse, "your-shared-secret") }
What This Does
- Individual encoding: By encoding each key and value separately, we ensure
=and&are treated as separators (not encoded), just like in Python. *handling: We manually replace*with%2Abecause Java'sURLEncoderdoesn't encode this character by default, while Python'surlencodedoes.
Test Output
Running this code will produce exactly the same string as your Python example:
pathURI=http%3A%2F%2Fmy.domain.net%2F%2A&expiry=1553937508&reuse=0
This should resolve the token authentication failure you're seeing, since the encoded string will now match what Python generates.
内容的提问来源于stack exchange,提问作者Hesam

