سؤال

لدينا قيم رقمية في قاعدة البيانات الخاصة بنا ، التي تمثل دولة ثنائية القيمة. بالطبع هذا من شأنه أن يتطابق تمامًا مع منطقية ، لكن Oracle ليس لديها مثل نوع البيانات. يتم مطابقة النوع (1،0) من قاعدة البيانات مع نوع java.lang.short في Java (في بعض الأحيان يستخدمون رقمًا (*، 0) لتمثيل المنطقات ، التي تتم مطابقة java.math.bigdecimal).

نظرًا لأنه واضح إلى حد ما ، أريد أن أقدم ICE: SelectBooleAncheckbox في العرض كتمثيل قيمة ومكون من المستخدمين. (أستخدم IceFaces كتطبيق JSF)

نظرًا لأن بعض الأشخاص الذين حددوا JSF يعتقدون أنه من الواضح دائمًا مطابقة قيمة الجليد: SelectBooleAncheckbox أو في JSF H: SelectBooleAncheckbox إلى منطقية في النموذج ، وبالتالي فإن عارض المكون لا يتصل أبدًا بأي محول ، حتى لو قمت بتحديد واحد:إصدار discused في java.net

لذلك جربت ما يلي:

لقد قمت بإنشاء محول لتحديده في UIComponent:

public class BooleanBigDecimalConverter implements Converter {

   public Object getAsObject(FacesContext context, UIComponent component, String str) {
     if (StringUtils.isEmptyString(str)) {
       return new BigDecimal(0);
     }
     if (str.equals("true")) {
       return new BigDecimal(1);
     } else {
       return new BigDecimal(0);
     }
   }

   public String getAsString(FacesContext context, UIComponent component, Object obj) {
     if (obj != null) {
       String str = obj.toString();
       if (str.equalsIgnoreCase("1")
       || str.equalsIgnoreCase("yes")
       || str.equalsIgnoreCase("true")
       || str.equalsIgnoreCase("on")) {
         return "true";
       } else {
         return "false";
       }
     }
     return "false";
   }
 }

يعمل المحول بشكل جيد في مرحلة التجسيد (تسمى GetAsstring-Method بشكل صحيح) ، ولكن طريقة getAsoBject (تجاهل أنها غير صحيحة في الوقت الحالي ، لأنه لا يطلق عليه على أي حال ، لذلك سيتم إصلاحه إذا تم استدعاؤه!) لا تسمى أبدًا ، لأنه في عارض UIComponent ، لا يتوقع المحول ، كما يمكنك أن ترى هنا (Snip من com.icesoft.faces.renderkit.dom_html_basic.checkboxrenderer):

 public Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object submittedValue)  throws ConverterException
 {
   if(!(submittedValue instanceof String))
     throw new ConverterException("Expecting submittedValue to be String");
   else
     return Boolean.valueOf((String)submittedValue);
 }

وبالتالي فإن هذا ينتج عنه وجود غير شرعي ، لأنه في مرحلة القيم المحدثة ، تحاول تطبيق منطقية على قيمة عددية (يرجى تجاهل الارتباك الكبير/القصير ... إنه مجرد نوع رقمي في أي حالة!).

لذلك حاولت الكتابة فوق العارض مع واحد جديد مثل هذا:

import com.icesoft.faces.component.ext.renderkit.CheckboxRenderer;

 public class CustomHtmlSelectBooleanCheckbox extends CheckboxRenderer {

   public Object getConvertedValue(FacesContext context, UIComponent component, Object submittedValue) throws ConverterException {
   Converter converter = ((ValueHolder) component).getConverter();
   return converter.getAsObject(context, component, (String) submittedValue);  
   }
 }

وسجلها مثل هذا في الوجوه config.xml:

 <render-kit>
   <renderer>
     <component-family>com.icesoft.faces.HtmlSelectBooleanCheckbox</component-family>
     <renderer-type>com.icesoft.faces.Checkbox</renderer-type>
     <renderer-class>com.myapp.web.util.CustomHtmlSelectBooleanCheckbox</renderer-class>
   </renderer>
 </render-kit>

أعتقد أن هذا يجب أن يكون صحيحًا ، لكن الطريقة المتجاوز "getConvertedValue" لا تسمى أبدًا ، كما أنه لا يتم توصيل GetasObject () ، لذلك أعتقد أنني ارتكبت خطأً في تسجيل العارض المخصص ، لكن لا يمكنني العثور على المزيد من الوثائق أو يلمح كيفية القيام بذلك بشكل صحيح وخاصة كيفية العثور على عائلة المكون الصحيحة (لقد بحثت عن تلك التي أستخدمها في Icefaces.taglib.xml) ونوع العارض الصحيح.

لا أريد تحرير النموذج الكامل بسبب هذا. أي تلميحات ، كيف يمكن حل هذا؟

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

المحلول

يمكننا إصلاح المشكلة وتسجيل العارض المخصص بشكل صحيح.

كانت المشكلة هي العثور على الخصائص الصحيحة للعارض المقصود. كانت محاولاتنا خاطئة ، لأنني اكتشفت كيفية الحصول على المعلومات المناسبة. إنه القليل من العمل والبحث ، لكنه قام أخيرًا بالخدعة.

ما عليك سوى تشغيل الحاوية في وضع التصحيح وأضف نقطة توقف على مستوى الفصل إلى الفئة المشتقة ، يعتمد العارض المخصص (في حالتي com.icesoft.faces.renderkit.dom_html_basic.checkboxrenderer).

أثناء بدء تشغيل الحاوية ، سيتم الوصول إلى نقطة الإيقاف هذه ، وفي StackTrace ستجد مكالمة للطريقة FaceSconFigurator.ConfigurerenderKits ().

يحتوي هذا الكائن على قائمة ArrayList من العارضين المسجلين. لقد بحثت في القائمة عن العارض الذي كنت أحب الكتابة فوقها ويمكن أن أجد المعلومات التي أحتاجها لتسجيل العارض المخصص الخاص بي. في حالتي ، هذا هو الإدخال الصحيح في الوجوه config.xml:

<render-kit>
    <description>The ICEsoft Renderers.</description>
    <render-kit-id>ICEfacesRenderKit</render-kit-id>
    <render-kit-class>com.icesoft.faces.renderkit.D2DRenderKit</render-kit-class>
    <renderer>
            <component-family>javax.faces.SelectBoolean</component-family>
            <renderer-type>com.icesoft.faces.Checkbox</renderer-type>
            <renderer-class>com.myapp.web.util.CustomHtmlSelectBooleanCheckbox</renderer-class>
    </renderer>
 </render-kit>

الآن يتم استدعاء الطريقة getAsoBject ()-في المحول بواسطة العارض المخصص. تأكد من تجاوز الطريقة بشكل صحيح ، في حال كنت لا تريد محولًا على كل كائن SelectBooleAncheckbox:

public Object getConvertedValue(FacesContext context,
        UIComponent component, Object submittedValue)
        throws ConverterException {
    Converter converter = ((ValueHolder) component).getConverter();
    if (converter == null) {
        if(!(submittedValue instanceof String))
            throw new ConverterException("Expecting submittedValue to be String");
        else
            return Boolean.valueOf((String)submittedValue);
    }
    return converter.getAsObject(context, component,
            (String) submittedValue);
}

وإلا ستحصل على nullpointerxception.

ملاحظة: هناك بالتأكيد طريقة أكثر ذكاءً لتحقيق هذه المعلومات ، لكنني لست ذكيًا بما فيه الكفاية. ؛-)

نصائح أخرى

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

انظر الى هذا الموضوع من منتديات السبات

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top