Интернационализированные свойства страницы в Tapestry 4.1.2 - PullRequest
4 голосов
/ 04 сентября 2008

Страница входа в мое приложение Tapestry имеет свойство, в котором хранится пароль, который вводит пользователь, который затем сравнивается со значением из базы данных. Если пользователь вводит пароль с многобайтовыми символами, такими как:

áéíóú

... проверка возвращаемого значения getPassword () (абстрактный метод для соответствующего свойства) дает:

áéíóú

Очевидно, что это не закодировано должным образом. Тем не менее Firebug сообщает, что страница обслуживается в UTF-8, поэтому предположительно запрос на отправку формы также будет закодирован в UTF-8. Проверка значения, полученного из базы данных, дает правильную строку, поэтому она не будет проблемой для кодировки ОС или IDE. Я не переопределил значение по умолчанию для Tapestry для org.apache.tapestry.output-encoding в файле .application, а документация по Tapestry 4 указывает, что значением по умолчанию для свойства является UTF-8.

Так почему же, по-видимому, Tapestry неправильно устанавливает кодировку при установке свойства?

Соответствующий код следует:

login.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>

Login.page

<?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>

Login.java

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

Обновление

@ Ян Солтис: Хорошо, если я проверю значение, полученное из базы данных, оно отобразит правильную строку, поэтому может показаться, что мой редактор, ОС и база данных все правильно кодируют значение. Я также проверил мой файл .application; он не содержит запись org.apache.tapestry.output-encoding, а документация Tapestry 4 указывает, что значением по умолчанию для этого свойства является UTF-8. Я обновил описание выше, чтобы отразить ответы на ваши вопросы.

@ себя: решение найдено.

Ответы [ 2 ]

2 голосов
/ 06 сентября 2008

Я нашел проблему. Tomcat исправлял параметры еще до того, как Tapestry или класс моей страницы даже взломали его. Создание фильтра сервлета, который принудительно применял желаемую кодировку символов, исправило его.

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>
2 голосов
/ 04 сентября 2008

Кажется, все правильно.

Вы действительно уверены, getPassword () возвращает мусор? Разве это не кто-то другой (ваш редактор, ОС, база данных, ...), который не знает, что это строка в кодировке Unicode, когда он отображает ее вам, в то время как пароль может быть в порядке? Что точно заставляет вас думать, что это мусор?

Я бы также удостоверился, что в конфигурационном файле .application нет странной кодировки.

<meta key="org.apache.tapestry.output-encoding" value="some strange encoding"/>
...