سؤال

تحتوي صفحة تسجيل الدخول في تطبيق Tapestry على خاصية يتم فيها تخزين كلمة المرور التي يكتبها المستخدم، والتي تتم بعد ذلك مقارنتها بالقيمة من قاعدة البيانات.إذا قام المستخدم بإدخال كلمة مرور تحتوي على أحرف متعددة البايت، مثل:

áéíóú

يعطي فحص القيمة المرجعة لـ getPassword() (الطريقة المجردة للخاصية المقابلة):

áéíóú

من الواضح أن هذا لم يتم ترميزه بشكل صحيح.ومع ذلك، أفاد Firebug أن الصفحة قد تم تقديمها بترميز UTF-8، لذلك من المفترض أن يتم ترميز طلب إرسال النموذج أيضًا بترميز UTF-8.يؤدي فحص القيمة كما تأتي من قاعدة البيانات إلى إنتاج السلسلة الصحيحة، لذلك لن يبدو أنها مشكلة في نظام التشغيل أو IDE.لم أتجاوز القيمة الافتراضية لـ Tapestry لـ org.apache.tapestry.output-encoding في ملف .application، وTapestry 4 توثيق يشير إلى أن القيمة الافتراضية للخاصية هي UTF-8.

فلماذا يبدو أن Tapestry يفسد الترميز عند تعيين الخاصية؟

الكود ذو الصلة يتبع:

تسجيل الدخول.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>

صفحة تسجيل الدخول

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

تسجيل الدخول.جافا

...
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، وTapestry 4 توثيق يشير إلى أن القيمة الافتراضية لهذه الخاصية هي UTF-8.لقد قمت بتحديث الوصف أعلاه ليعكس الإجابات على أسئلتك.

@نفسي:تم العثور على الحل.

هل كانت مفيدة؟

المحلول 2

لقد وجدت المشكلة.كان Tomcat يشوه المعلمات قبل أن يتعرض Tapestry أو فئة صفحتي للكسر.تم إصلاحه من خلال إنشاء مرشح servlet الذي يفرض ترميز الأحرف المطلوب.

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>

نصائح أخرى

يبدو أن كل شيء صحيح.

أنت متأكد حقا getPassword() إرجاع القمامة؟أليس شخصًا آخر (المحرر، نظام التشغيل، قاعدة البيانات،...) لا يعرف أنها سلسلة Unicode عندما يعرضها لك بينما قد تكون كلمة المرور جيدة تمامًا؟ماذا بالضبط يجعلك تعتقد أنها القمامة؟

أود أيضًا التأكد من عدم وجود أي ترميز غريب في ملف تكوين التطبيق

<meta key="org.apache.tapestry.output-encoding" value="some strange encoding"/>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top