Continuum

Continuum

Continuum Chile: Agilistas y Desarrolladores Web en Java, Ruby, Rails ..Java, Python, Ruby, Javascript, Ajax, Web 2.0, ESB, SOA…
Continuum

function JQuery (o no) para calcular Dígito Verificador.

Aquí va !

/*
 * Calcula digito verificador
 */
$.calculaDigitoVerificador = function (rut) {
	// type check
	if (!rut || !rut.length || typeof rut !== 'string') {
		return -1;
	}
	// serie numerica
	var secuencia = [2,3,4,5,6,7,2,3];
	var sum = 0;
	//
	for (var i=rut.length - 1; i >=0; i--) {
		var d = rut.charAt(i)
		sum += new Number(d)*secuencia[rut.length - (i + 1)];
	};
	// sum mod 11
	var rest = 11 - (sum % 11);
	// si es 11, retorna 0, sino si es 10 retorna K,
	// en caso contrario retorna el numero
	return rest === 11 ? 0 : rest === 10 ? "K" : rest;
};

Su uso es trivial: jQuery.calculaDigitoVerificador(“4678982″) retorna “2″

Igual pueden quitar el namespace “jQuery” de la declaración de la function, no afecta  !.

El código es más confiable bajarlo de aquí (calcula-digito.jquery.js).

(Un)regular expressions en Java.

Quizás haya una forma más fácil de usar expresiones regulares en Java, pero yo no la encuentro. Usarlas en JavaScript, Python o Ruby es de las cosas que hacen atractivos estos lenguajes, pero en Java cuesta hacer natural lo natural.

Mi problematica es que tengo un servicio que retorna contenido HTML, y necesito dos cosas:

1. Saber cuantos caracteres del contenido pertenecen a TAGS HTML.

2. Retornar el contenido sin HTML, o sea en texto plano.

Por ejemplo, del texto:

"Presione <b><a href="javascript:void(0)">Aqui</a></b>..."

Debo retornar ["Presione Aqui", 40]. (40 es la cantidad de caracteres dentro de los tags).

Luce sencillo a simple vista, parsear el texto en busca de patrones que se corresponden con TAGS HTML substituyendo el patrón por un caracter blanco para eliminar los TAGS y contando el length de cada patrón devuelto. O sea se hace evidente el uso de Expresiones Regulares.

A continuación mi solución para que noten lo complicado que se hace programar con expresiones regulares en Java. Si alguien encuentra una forma más natural por favor no dude en enviarmela a través de un comentario.

Primero un contenedor de expresiones regulares compiladas

// regular expression Patterns (HTML TAGS) container
private static final Pattern[] HTML_TAG_REXP;
// init
static {
    HTML_TAG_REXP = new Pattern[] {
        Pattern.compile("<(a|A).*?>"),
        Pattern.compile("</(a|A)>"),
        Pattern.compile("<(b|B).*?>"),
        Pattern.compile("</(b|B)>"),
        Pattern.compile("<(i|I).*?>"),
        Pattern.compile("</(i|I)>"),
        Pattern.compile("<(p|P).*?>"),
        Pattern.compile("</(p|P)>"),
        Pattern.compile("<(img|IMG).*?>"),
        Pattern.compile("</(img|IMG)>"),
        Pattern.compile("<(stong|STRONG).*?>"),
        Pattern.compile("</(strong|STRONG)>"),
        Pattern.compile("<(h1|H1).*?>"),
        Pattern.compile("</(h1|H1)>"),
        Pattern.compile("<(h2|H2).*?>"),
        Pattern.compile("</(h2|H2)>"),
        Pattern.compile("<(h3|H3).*?>"),
        Pattern.compile("</(h3|H3)>"),
    };
}

Al compilarlas mejoramos la performance vs usar expresiones regulares literales. (Solo coloque algunos TAGS, pero basta con agregar más a la lista).

Y a continuación el método que pasado el contenido en HTML retorna un arreglo de objetos; donde en la primera posición va el contenido en texto plano (sin los TAGS HTML) y en la segunda posición la cantidad de caracteres que pertenecen a los TAGS.

...
/**
 * @param content
 * @return [String, Integer]
 */
private Object[] removeAndCountHtmlTags(String content) {
	String result = content;
	int htmlCharCount = 0;
	for (int i = 0; i < HTML_TAG_REXP.length; i++) {
		// create the matcher against the result
		Matcher m = HTML_TAG_REXP[i].matcher(result);
		// while send a message to find a match group is true
		while (m.find()) {
			LOG.info("matcher group - " + m.group(0));
			// count the number of chars that match
                        // the group
			htmlCharCount += m.group(0).length();
			// replace first ocurrence (eliminate tags)
			result = m.replaceFirst("");
                        // and send the message again to find the next
			m = HTML_TAG_REXP[i].matcher(result);
		}
	}
	return new Object[] {result, new Integer(htmlCharCount)};
}
...

Generar una respuesta JSON desde Java en UTF-8

He visto en varios forums que algunas personas se quejan de que cuando generan objetos en notación JavaScript (JSON) y que tienen caracteres del latín como los acentados (ñ, á, ü, etc) usando HttpServletResponse desde un servlet el browser les muestra caracteres extraños y preguntan por la solución.

La respuesta es sencilla. Antes de hacer el getWriter() del HttpServletResponse se debe setear el tipo de encoding que usarán para mapear los caracteres de forma que el browser los pueda interpretar y convertir de vuelta.

Hay dos formas de hacer esto:

1. Mediante el método setContentType(), que envía el tipo de contenido al cliente (browser) y donde puede setearse el charset.

response.setContentType("application/x-json;charset=UTF-8");
...

2. Mediante el método setCharacterEncoding(), que si es usado sobre-escribe la acción de setContentType().

response.setCharacterEncoding("UTF-8");
...

A continuación un ejemplo completo del envio de modelos de objetos en notación JavaScript hacia el browser desde un clase que hereda de org.springframework.web.servlet.view.AbstractView de Spring

...
    protected void renderMergedOutputModel(Map model, HttpServletRequest req,
            HttpServletResponse resp) throws Exception {
        JSONObject json = (JSONObject) model.get("json");
        resp.setCharacterEncoding("UTF-8");
        if (null != json) {
            resp.getWriter().write(json.toString());
        } else {
            resp.getWriter().write("{}");
        }
    }

Para mayor referencia, Tim Bray explica porque Unicode y UTF-8 son excelentes. Es una lectura obligatoria para entender de estos temas.

« Entradas Anteriores Entradas Siguientes »

 
Copyright © 2012 Continuum Ltda. Coronel Pereira 72. Oficina 903. Las Condes. Santiago. Chile
Tel: +56 2 9341951