urlencoder urldecoder example java decoding query-string

urldecoder - Decodificación de la cadena de consulta URI en Java



urlencoder encode utf-8 example java (4)

Necesito descifrar un URI que contiene una cadena de consulta; El comportamiento esperado de entrada / salida es algo como lo siguiente:

abstract class URIParser { /** example input: * something?alias=pos&FirstName=Foo+A%26B%3DC&LastName=Bar */ URIParser(String input) { ... } /** should return "something" for the example input */ public String getPath(); /** should return a map * {alias: "pos", FirstName: "Foo+A&B=C", LastName: "Bar"} */ public Map<String,String> getQuery(); }

He intentado usar java.net.URI , pero parece que decodifica la cadena de consulta, así que en el ejemplo anterior me quedo con "alias = pos & FirstName = Foo + A & B = C & LastName = Bar", por lo que hay ambigüedad sobre si un "& "es un separador de consulta o es un carácter en un componente de consulta.

Edición: Acabo de probar URI.getRawQuery() y no hace la codificación, por lo que puedo dividir la cadena de consulta con un & , pero ¿qué hago? Javascript tiene decodeURIComponent , parece que no puedo encontrar el método correspondiente en Java.

¿Alguna sugerencia? Preferiría no usar ninguna nueva biblioteca.


Respecto al tema con el signo +:

Hice una clase de ayuda que envuelve la función URLDecoder basada en la respuesta de @janb

import android.net.Uri; import android.support.annotation.Nullable; import android.text.TextUtils; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; public class DateDecoder { private static final String KEY_DATE = "datekey"; private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd''T''HH:mm:ssZZZZZ", Locale.US); public static void main(String[] args) throws UnsupportedEncodingException { try { Uri uri = Uri.parse("http://asdf.com?something=12345&" + KEY_DATE +"=2016-12-24T12:00:00+01:00"); System.out.println("parsed date: " + DateDecoder.createDate(uri)); // parsed date: Sat Dec 24 12:00:00 GMT+01:00 2016 } catch (Exception e) { e.printStackTrace(); } } @Nullable public static Date createDate(@Nullable Uri data) { if (data != null) { try { String withPlus = decodeButKeepPlus(KEY_DATE, data.getEncodedQuery()); if (!TextUtils.isEmpty(withPlus)) { return SIMPLE_DATE_FORMAT.parse(withPlus); } } catch (Exception e) { e.printStackTrace(); } } return null; } /** * copied from android.net.Uri.java */ @Nullable public static String decodeButKeepPlus(String encodedKey, String completeEncodedQuery) throws UnsupportedEncodingException { final int length = completeEncodedQuery.length(); int start = 0; do { int nextAmpersand = completeEncodedQuery.indexOf(''&'', start); int end = nextAmpersand != -1 ? nextAmpersand : length; int separator = completeEncodedQuery.indexOf(''='', start); if (separator > end || separator == -1) { separator = end; } if (separator - start == encodedKey.length() && completeEncodedQuery.regionMatches(start, encodedKey, 0, encodedKey.length())) { if (separator == end) { return ""; } else { String encodedValue = completeEncodedQuery.substring(separator + 1, end); if (!TextUtils.isEmpty(encodedValue)) { return URLDecoder.decode(encodedValue.replace("+", "%2B"), "UTF-8").replace("%2B", "+"); } } } // Move start to end of name. if (nextAmpersand != -1) { start = nextAmpersand + 1; } else { break; } } while (true); return null; } }


Utilizar

URLDecoder.decode(proxyRequestParam.replace("+", "%2B"), "UTF-8") .replace("%2B", "+")

para simular decodeURIComponent . El URLDecoder de Java decodifica el signo más a un espacio, que no es lo que desea, por lo que necesita las declaraciones de reemplazo.

Advertencia: el .replace("%2B", "+") al final dañará sus datos si el original (pre-x-www-form-urlencoded) contenía esa cadena, como lo señaló @xehpuk.



var reqParam = URLDecoder.decode(reqParam, "UTF-8")