Pregunta

La página de inicio de sesión en mi aplicación Tapestry tiene una propiedad en la que se almacena la contraseña que ingresa el usuario, que luego se compara con el valor de la base de datos.Si el usuario ingresa una contraseña con caracteres de varios bytes, como:

áéíóú

...una inspección del valor de retorno de getPassword() (el método abstracto para la propiedad correspondiente) da:

áéíóú

Claramente, eso no está codificado correctamente.Sin embargo, Firebug informa que la página se muestra en UTF-8, por lo que presumiblemente la solicitud de envío del formulario también estaría codificada en UTF-8.La inspección del valor tal como proviene de la base de datos produce la cadena correcta, por lo que no parecería ser un problema de codificación del sistema operativo o IDE.No he anulado el valor predeterminado de Tapestry para org.apache.tapestry.output-encoding en el archivo .application y Tapestry 4 documentación indica que el valor predeterminado de la propiedad es UTF-8.

Entonces, ¿por qué parece que Tapestry falla en la codificación al configurar la propiedad?

El código relevante es el siguiente:

Iniciar sesión.html

<html jwcid="@Shell" doctype='html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"' ...>
    <body jwcid="@Body">
        ...
        <form jwcid="@Form" listener="listener:attemptLogin" ...>
            ...
            <input jwcid="password"/>
            ...
        </form>
        ...
     </body>
</html>

Página de inicio de sesión

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE page-specification
    PUBLIC "-//Apache Software Foundation//Tapestry Specification 4.0//EN"
    "http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">

<page-specification class="mycode.Login">
    ...
    <property name="password" />
    ...
    <component id="password" type="TextField">
        <binding name="value" value="password"/>
        <binding name="hidden" value="true"/>
        ...
    </component>
    ...
</page-specification>

Iniciar sesión.java

...
public abstract class Login extends BasePage {
    ...
    public abstract String getPassword();
    ...
    public void attemptLogin() {
        // At this point, inspecting getPassword() returns
        // the incorrectly encoded String.
    }
    ...
}

Actualizaciones

@Jan Soltis:Bueno, si inspecciono el valor que proviene de la base de datos, muestra la cadena correcta, por lo que parecería que mi editor, sistema operativo y base de datos están codificando el valor correctamente.También revisé mi archivo .application;no contiene una entrada org.apache.tapestry.output-encoding y el Tapestry 4 documentación indica que el valor predeterminado para esta propiedad es UTF-8.He actualizado la descripción anterior para reflejar las respuestas a sus preguntas.

@mí mismo:Solución encontrada.

¿Fue útil?

Solución 2

Encontré el problema.Tomcat estaba alterando los parámetros antes de que Tapestry o mi clase de página siquiera lo intentaran.Se solucionó al crear un filtro de servlet que imponía la codificación de caracteres deseada.

CharacterEncodingFilter.java

package mycode;

import java.io.IOException;

import javax.servlet.*;

/**
 * Allows you to enforce a particular character encoding on incoming requests.
 * @author Robert J. Walker
 */
public class CharacterEncodingFilter implements Filter {
    private static final String ENCODINGPARAM = "encoding";

    private String encoding;

    public void init(FilterConfig config) throws ServletException {
        encoding = config.getInitParameter(ENCODINGPARAM);

        if (encoding != null) {
            encoding = encoding.trim();
        }
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        request.setCharacterEncoding(encoding);
        chain.doFilter(request, response);
    }

    public void destroy() {
        // do nothing
    }
}

web.xml

<web-app>
    ...
    <filter>
        <filter-name>characterEncoding</filter-name>
        <filter-class>mycode.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncoding</filter-name>
        <url-pattern>/app/*</url-pattern>
    </filter-mapping>
    ...
</web-app>

Otros consejos

Todo parece estar correcto.

Eres realmente seguro getPassword() devuelve basura?¿No es alguien más (su editor, sistema operativo, base de datos,...) que no sabe que es una cadena Unicode cuando se la muestra, mientras que la contraseña puede estar perfectamente bien?Qué exactamente ¿Te hace pensar que es una basura?

También me aseguraría de que no haya ninguna codificación extraña configurada en el archivo de configuración .application

<meta key="org.apache.tapestry.output-encoding" value="some strange encoding"/>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top