special example convertir characters acentos java javascript unicode utf-8

example - unicode javascript acentos



¿Java equivalente al encodeURIComponent de JavaScript que produce resultados idénticos? (11)

Al observar las diferencias de implementación, veo que:

encodeURIComponent :

  • caracteres literales (representación [-a-zA-Z0-9._*~''()!] regulares): [-a-zA-Z0-9._*~''()!]

Documentación de Java 1.5.0 en URLEncoder :

  • caracteres literales (representación [-a-zA-Z0-9._*] regulares): [-a-zA-Z0-9._*]
  • el carácter de espacio " " se convierte en un signo más "+" .

Básicamente, para obtener el resultado deseado, use URLEncoder.encode(s, "UTF-8") y luego realice un postprocesamiento:

  • reemplace todas las apariciones de "+" con "%20"
  • reemplace todas las ocurrencias de "%xx" representan cualquiera de [~''()!] vuelta a sus contrapartes literales

He estado experimentando con varios bits de código Java tratando de encontrar algo que codificará una cadena que contenga comillas, espacios y caracteres Unicode "exóticos" y produzca una salida idéntica a la función encodeURIComponent de JavaScript.

Mi cadena de prueba de tortura es: "A" B ± "

Si ingreso la siguiente declaración de JavaScript en Firebug:

encodeURIComponent(''"A" B ± "'');

-Entonces obtengo:

"%22A%22%20B%20%C2%B1%20%22"

Aquí está mi pequeño programa de prueba de Java:

import java.io.UnsupportedEncodingException; import java.net.URLEncoder; public class EncodingTest { public static void main(String[] args) throws UnsupportedEncodingException { String s = "/"A/" B ± /""; System.out.println("URLEncoder.encode returns " + URLEncoder.encode(s, "UTF-8")); System.out.println("getBytes returns " + new String(s.getBytes("UTF-8"), "ISO-8859-1")); } }

-Este programa produce:

URLEncoder.encode returns %22A%22+B+%C2%B1+%22 getBytes returns "A" B ± "

Cerca, ¡pero no cigarro! ¿Cuál es la mejor manera de codificar una cadena UTF-8 usando Java para que produzca el mismo resultado que encodeURIComponent de JavaScript?

EDITAR: Estoy usando Java 1.4 moviéndome a Java 5 en breve.



Esta es la clase que se me ocurrió al final:

import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; /** * Utility class for JavaScript compatible UTF-8 encoding and decoding. * * @see http://.com/questions/607176/java-equivalent-to-javascripts-encodeuricomponent-that-produces-identical-output * @author John Topley */ public class EncodingUtil { /** * Decodes the passed UTF-8 String using an algorithm that''s compatible with * JavaScript''s <code>decodeURIComponent</code> function. Returns * <code>null</code> if the String is <code>null</code>. * * @param s The UTF-8 encoded String to be decoded * @return the decoded String */ public static String decodeURIComponent(String s) { if (s == null) { return null; } String result = null; try { result = URLDecoder.decode(s, "UTF-8"); } // This exception should never occur. catch (UnsupportedEncodingException e) { result = s; } return result; } /** * Encodes the passed String as UTF-8 using an algorithm that''s compatible * with JavaScript''s <code>encodeURIComponent</code> function. Returns * <code>null</code> if the String is <code>null</code>. * * @param s The String to be encoded * @return the encoded String */ public static String encodeURIComponent(String s) { String result = null; try { result = URLEncoder.encode(s, "UTF-8") .replaceAll("//+", "%20") .replaceAll("//%21", "!") .replaceAll("//%27", "''") .replaceAll("//%28", "(") .replaceAll("//%29", ")") .replaceAll("//%7E", "~"); } // This exception should never occur. catch (UnsupportedEncodingException e) { result = s; } return result; } /** * Private constructor to prevent this class from being instantiated. */ private EncodingUtil() { super(); } }


Este es un ejemplo sencillo de la solución de Ravi Wallau:

public String buildSafeURL(String partialURL, String documentName) throws ScriptException { ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); ScriptEngine scriptEngine = scriptEngineManager .getEngineByName("JavaScript"); String urlSafeDocumentName = String.valueOf(scriptEngine .eval("encodeURIComponent(''" + documentName + "'')")); String safeURL = partialURL + urlSafeDocumentName; return safeURL; } public static void main(String[] args) { EncodeURIComponentDemo demo = new EncodeURIComponentDemo(); String partialURL = "https://www.website.com/document/"; String documentName = "Tom & Jerry Manuscript.pdf"; try { System.out.println(demo.buildSafeURL(partialURL, documentName)); } catch (ScriptException se) { se.printStackTrace(); } }

Salida: https://www.website.com/document/Tom%20%26%20Jerry%20Manuscript.pdf

También responde a la pregunta pendiente en los comentarios de Loren Shqipognja sobre cómo pasar una variable String a encodeURIComponent() . El método scriptEngine.eval() devuelve un Object , por lo que puede convertirse a String a través de String.valueOf() entre otros métodos.


He utilizado con éxito la clase java.net.URI así:

public static String uriEncode(String string) { String result = string; if (null != string) { try { String scheme = null; String ssp = string; int es = string.indexOf('':''); if (es > 0) { scheme = string.substring(0, es); ssp = string.substring(es + 1); } result = (new URI(scheme, ssp, null)).toString(); } catch (URISyntaxException usex) { // ignore and use string that has syntax error } } return result; }


Inventé mi propia versión del encodeURIComponent, porque la solución publicada tiene un problema, si había un + presente en el String, que debería codificarse, se convertiría en un espacio.

Así que aquí está mi clase:

import java.io.UnsupportedEncodingException; import java.util.BitSet; public final class EscapeUtils { /** used for the encodeURIComponent function */ private static final BitSet dontNeedEncoding; static { dontNeedEncoding = new BitSet(256); // a-z for (int i = 97; i <= 122; ++i) { dontNeedEncoding.set(i); } // A-Z for (int i = 65; i <= 90; ++i) { dontNeedEncoding.set(i); } // 0-9 for (int i = 48; i <= 57; ++i) { dontNeedEncoding.set(i); } // ''()* for (int i = 39; i <= 42; ++i) { dontNeedEncoding.set(i); } dontNeedEncoding.set(33); // ! dontNeedEncoding.set(45); // - dontNeedEncoding.set(46); // . dontNeedEncoding.set(95); // _ dontNeedEncoding.set(126); // ~ } /** * A Utility class should not be instantiated. */ private EscapeUtils() { } /** * Escapes all characters except the following: alphabetic, decimal digits, - _ . ! ~ * '' ( ) * * @param input * A component of a URI * @return the escaped URI component */ public static String encodeURIComponent(String input) { if (input == null) { return input; } StringBuilder filtered = new StringBuilder(input.length()); char c; for (int i = 0; i < input.length(); ++i) { c = input.charAt(i); if (dontNeedEncoding.get(c)) { filtered.append(c); } else { final byte[] b = charToBytesUTF(c); for (int j = 0; j < b.length; ++j) { filtered.append(''%''); filtered.append("0123456789ABCDEF".charAt(b[j] >> 4 & 0xF)); filtered.append("0123456789ABCDEF".charAt(b[j] & 0xF)); } } } return filtered.toString(); } private static byte[] charToBytesUTF(char c) { try { return new String(new char[] { c }).getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { return new byte[] { (byte) c }; } } }


La biblioteca de Guava tiene PercentEscaper:

Escaper percentEscaper = new PercentEscaper("-_.*", false);

"-_. *" son caracteres seguros

falso dice PercentEscaper para escapar del espacio con ''% 20'', no ''+''



Usando el motor de javascript incluido con Java 6:

import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; public class Wow { public static void main(String[] args) throws Exception { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("JavaScript"); engine.eval("print(encodeURIComponent(''/"A/" B ± /"''))"); } }

Salida:% 22A% 22% 20B% 20% c2% b1% 20% 22

El caso es diferente, pero está más cerca de lo que quieres.


Yo uso java.net.URI#getRawPath() , por ejemplo

String s = "a+b c.html"; String fixed = new URI(null, null, s, null).getRawPath();

El valor de fixed será a+b%20c.html , que es lo que desea.

El procesamiento posterior de la salida de URLEncoder.encode() borrará cualquier ventaja que se supone que está en el URI. Por ejemplo

URLEncoder.encode("a+b c.html").replaceAll("//+", "%20");

le dará a%20b%20c.html , que se interpretará como ab c.html .


para mí esto funcionó:

import org.apache.http.client.utils.URIBuilder; String encodedString = new URIBuilder() .setParameter("i", stringToEncode) .build() .getRawQuery() // output: i=encodedString .substring(2);

o con un UriBuilder diferente

import javax.ws.rs.core.UriBuilder; String encodedString = UriBuilder.fromPath("") .queryParam("i", stringToEncode) .toString() // output: ?i=encodedString .substring(3);

En mi opinión, usar una biblioteca estándar es una mejor idea en lugar de postprocesar manualmente. También la respuesta de @Chris se veía bien, pero no funciona para las URL, como " http://a+b c.html"