Registrando nuevo valor predeterminadoConverter para doble como un grano en los grados 4

Por lo tanto, aparentemente Grails realiza la unión local de datos conscientes, y como utilizamos un local danés como predeterminado, enviando dobles como "123.123" a un punto final lo convierte a "123123.0". Así que he encontrado algunas otras preguntas sobre esto y parece que puedo crear una clase que se extiende ValueConverter y convertir explícitamente todos los dobles entrantes. El problema es que el convert() método nunca parece ser llamado. Vi en este post Valores de número real vinculantes para los atributos de dominio Grails (valores enviados por los widgets Dojo), que podría tener que registrarlo como un plugin para especificar un orden de carga. Ahora me gustaría evitar eso ya que parece mucho más trabajo (y nunca he implementado mi propio plugin antes).

Así que mis preguntas son:

  1. ¿Tengo que registrar esta funcionalidad como un plugin para que funcione?
  2. Si no, ¿por qué no funciona?
  3. ¿Cuál de mis formatos de registro de frijoles es correcto?

Aquí está mi convertidor:

import grails.databinding.converters.ValueConverter

class DoubleValueConverter implements ValueConverter {

    @Override
    boolean canConvert(Object value) {
        return value instanceof String
    }

    @Override
    Object convert(Object value) { // <- Is never called :(
        Double d = Double.parseDouble(value as String)
        return d
    }

    @Override
    Class getTargetType() { // <- Is called
        return Double
    }
}

y aquí está resources.groovy

import dk.erst.plandata.integration.converters.DoubleValueConverter
import grails.util.Holders
import org.springframework.web.servlet.i18n.SessionLocaleResolver

beans = {

    defaultGrailsDoubleConverter (DoubleValueConverter) { bean ->
        bean.autowire = 'byName'
    }

    defaultGrailsdoubleConverter(DoubleValueConverter) { bean ->
        bean.autowire = 'byName'
    }

    "defaultGrailsjava.lang.DoubleConverter"(DoubleValueConverter) { bean ->
        bean.autowire = 'byName'
    }

    // This is the reason the converter is needed in the first place. 
    localeResolver(SessionLocaleResolver) { 
            defaultLocale = new Locale('da')
    }
}

Pregunta hecha hace 3 años, 4 meses, 27 días - Por byteexplorer


3 Respuestas:

  • Finalmente encontré una solución a mi problema. Mi convertidor está registrado correctamente. Sin embargo, no se utiliza como el convertidor predeterminado tiene precedencia.

    Para arreglar esto, tuve que añadir el @Order(-1) anotación (de este tema https://github.com/grails/grails-core/issues/11404) a mi DoubleValueConverter clase para que tenga mayor precedencia que el predeterminado (0?). Además, este cambio fue introducido en Grails 4.0.2, así que tuve que actualizar desde 4.0.1. Espero que esto ayude a alguien :)

    Respondida el Dec 18, 2020 a las 15:21 - por binarybrainiac

    Votos positivos: 0 | Votos negativos: 0

  • Para solucionar el problema que estás experimentando con tu convertidor personalizado en Grails, puedes intentar lo siguiente:

    • Asegúrate de que estás registrando correctamente tu convertidor en el archivo `resources.groovy`. Parece que tienes varias definiciones para el mismo convertidor, lo cual puede causar conflicto. Elimina las definiciones duplicadas y deja solo una de ellas. Por ejemplo, puedes mantener la definición como `defaultGrailsDoubleConverter`.
    • En el método `canConvert` de tu convertidor, verifica si el valor es un tipo `Double` en lugar de un tipo `String`, ya que es posible que los datos se estén bindeando como `Double` en lugar de `String`. También puedes probar a imprimir un mensaje de depuración para verificar si el método `convert` realmente nunca es llamado.
    • Asegúrate de que el nombre del paquete y la clase del convertidor estén correctamente definidos. En tu caso, parece ser `dk.erst.plandata.integration.converters.DoubleValueConverter`, así que asegúrate de que el nombre del paquete y la clase coincidan con el nombre del archivo fuente y la ubicación del archivo.

    Una vez que hayas realizado estos ajustes, intenta probar nuevamente tu aplicación para ver si el convertidor personalizado ahora se llama correctamente. Recuerda también reiniciar tu aplicación después de realizar cambios en los archivos de configuración.

    Respondida el Dec 19, 2020 a las 15:21 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • ¿Tengo que registrar esta funcionalidad como un plugin para que funcione?

    No, no es necesario registrar la funcionalidad como un plugin para que funcione.

    Si no, ¿por qué no funciona?

    Hay un error tipográfico en tu código:

    groovy
    defaultGrailsdoubleConverter(DoubleValueConverter) {...}
    

    Debería ser:

    groovy
    defaultGrailsDoubleConverter(DoubleValueConverter) {...}
    

    ¿Cuál de mis formatos de registro de frijoles es correcto?

    El formato de registro de frijoles correcto es:

    groovy
    defaultGrailsDoubleConverter(DoubleValueConverter) {...}
    

    Razón por la que el método convert() no se llama:

    El método convert() se llama cuando se produce el enlace de datos. Para que se llame a tu convertidor, debes asegurarte de que se esté utilizando durante el enlace de datos. Puedes hacer esto anotando la propiedad del dominio con @BindingFormat, por ejemplo:

    groovy
    class MyDomain {
    
        @BindingFormat('myDoubleValueConverter')
        Double myDouble
    
    }
    

    Donde myDoubleValueConverter es el nombre del bean del convertidor (defaultGrailsDoubleConverter).

    Código corregido:

    groovy
    import grails.databinding.converters.ValueConverter
    
    class DoubleValueConverter implements ValueConverter {
    
        @Override
        boolean canConvert(Object value) {
            return value instanceof String
        }
    
        @Override
        Object convert(Object value) {
            Double d = Double.parseDouble(value as String)
            return d
        }
    
        @Override
        Class getTargetType() {
            return Double
        }
    }
    
    beans = {
    
        defaultGrailsDoubleConverter(DoubleValueConverter) {
            bean.autowire = 'byName'
        }
    
        localeResolver(SessionLocaleResolver) { 
                defaultLocale = new Locale('da')
        }
    }
    

    En el dominio:

    groovy
    class MyDomain {
    
        @BindingFormat('defaultGrailsDoubleConverter')
        Double myDouble
    
    }
    

    Respondida el Dec 19, 2020 a las 15:35 - por Gemini

    Votos positivos: 0 | Votos negativos: 0