es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Obteniendo un IllegalArgumentException: No se puede convertir un String a AtomicInteger al intentar agregar datos que contienen un int de tipo AtomicInteger en la caché de Redis.

Estoy tratando de agregar un modelo de datos a una caché de Redis. Cuando saco el modelo, obtengo la excepción

org.springframework.core.convert.ConversionFailedException: No se pudo convertir desde el tipo [byte[]] al tipo [java.util.concurrent.atomic.AtomicInteger] para el valor '{53}'; la excepción anidada es java.lang.IllegalArgumentException: No se puede convertir la cadena [5] a la clase de destino [java.util.concurrent.atomic.AtomicInteger]] con causa raíz

El modelo es

@RedisHash(value = "ThottleRate", timeToLive = 5)

<p>public class ThottleRate implements Serializable  {</p>

<pre><code>   private static final long serialVersionUID = 1L;

   @Id
   private String url;
   private AtomicInteger rate;

   public ThottleRate(String url, int rate) {
         super();
         this.url = url;
         this.rate = new AtomicInteger(rate);
   }

   public boolean isAllowed(){
       if(this.rate.decrementAndGet() <= 0) {
                return false;
         }
         return true;
   }
</code></pre>

<p><code>
El código de llamada es
</code>
try {
                    option = throttleRateRepository.findById(url);
                    ThottleRate rate = option.get();
                    allow = rate.isAllowed();
             } catch(NoSuchElementException e) {
                throttleRateRepository.save(new ThottleRate(url, 5));
                    allow = true;
             }

Lo que estoy tratando de hacer es la funcionalidad de limitación de frecuencia, usando la caché de Redis. Tiene un tiempo de vida, y dentro de ese tiempo un número de veces que una URL puede ser accedida.

Pero cuando se hace la llamada

option = throttleRateRepository.findById(url);

esto genera la IllegalArgumentException

Esto parece la forma más simple de usar la caché de Redis con un tiempo de vida y un número de tasas.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El problema parece estar en la conversión del tipo de dato de byte[] a AtomicInteger. Cuando se recupera el modelo de Redis, el campo rate se devuelve como byte[] en lugar de AtomicInteger. Esto hace que se produzca una ConversionFailedException al intentar convertirlo de nuevo a AtomicInteger.

    Para solucionar este problema, es necesario implementar un RedisSerializer personalizado para AtomicInteger. Este serializer convertirá el objeto AtomicInteger a byte[] antes de guardarlo en Redis, y lo volverá a convertir en AtomicInteger al recuperarlo de Redis.

    Aquí hay un ejemplo de implementación del RedisSerializer personalizado para AtomicInteger:

    public class AtomicIntegerSerializer implements RedisSerializer<atomicinteger> {
    
        @Override
        public byte[] serialize(AtomicInteger atomicInteger) throws SerializationException {
            return Integer.toString(atomicInteger.get()).getBytes();
        }
    
        @Override
        public AtomicInteger deserialize(byte[] bytes) throws SerializationException {
            return new AtomicInteger(Integer.parseInt(new String(bytes)));
        }
    }
    

    Para utilizar este serializer personalizado, se debe registrar con el RedisTemplate utilizado para interactuar con Redis. Esto puede hacerse añadiendo el siguiente código:

    RedisSerializer<atomicinteger> atomicIntegerSerializer = new AtomicIntegerSerializer();
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setValueSerializer(atomicIntegerSerializer);
    

    Este código establece el serializer de clave en el StringRedisSerializer predeterminado y el serializer de valor en el AtomicIntegerSerializer personalizado.

    Con este serializer personalizado en su lugar, el modelo ThrottleRate debería poder recuperarse de Redis sin que se produzca ningún ConversionFailedException.

Comments are closed.