En los dos primeros artículos, implementamos enviando mensajes SMS sincrónicos/asíncronos y limitando la frecuencia del envío de mensajes SMS. En este artículo, presentamos la limitación de la cantidad de veces que enviamos mensajes SMS al mismo usuario (a juzgar en función del número de teléfono móvil y la IP) todos los días.
1. Estructura de la tabla de datos
Como necesitamos grabar los registros de envío durante todo el día, guardamos los datos en la base de datos aquí. La estructura de la tabla de datos es la siguiente:
El tipo es el tipo de código de verificación, como el registro, la contraseña de restablecimiento, etc.
El valor predeterminado de SendTime es la hora actual.
2. Limite el número de tiempos de envío diarios
Necesitamos usar las clases de interfaz y entidad mencionadas en el artículo anterior aquí.
DailyCountFilter.java
Public Class DailyCountFilter implementa SMSFILTER {private int ipDailyMaxSendCount; privado int mobilellyyMaxSendCount; SMSDAO privado SMSDAO; // Se omite algún código inútil @Override Public Boolean Filter (SMSEntity smsEntity) {if (smsdao.getMobileCount (smsEntity.getMobile ())> = mobiledailyMaxSendCount) {return false; } if (smsdao.getipCount (smsentity.getip ())> = ipDailyMaxSendCount) {return false; } smsdao.saveEntity (smsentity); devolver verdadero; }}El código principal es muy simple. Primero, determine si el número de veces enviado al número de teléfono móvil especificado ha alcanzado el número máximo de tiempos de envío, y luego determine si el número de veces enviado por la solicitud IP especificada ha alcanzado el número máximo. Si ninguno de ellos lo es, guarde el número de teléfono móvil, la IP y otra información enviadas este tiempo a la base de datos.
Por supuesto, hay ciertos problemas con esta clase: otros hilos pueden haber guardado nuevos datos entre juzgar si el número máximo excede el número máximo y los datos de entidad que se están guardando. Esto da como resultado los dos juicios anteriores no absolutamente precisos.
Podemos usar transacciones de nivel de serialización para garantizar que no haya errores, pero el costo es demasiado alto. Por lo tanto, no haremos el procesamiento aquí. Porque hemos implementado limitar la frecuencia de transmisión antes. Si usamos FrecuenciaFilter para filtrar una vez y limitar la frecuencia de transmisión, entonces el problema mencionado anteriormente es básicamente imposible.
Hay otro problema: con el tiempo, esta tabla se volverá cada vez más grande, lo que dará como resultado un rendimiento de consulta bastante pobre. Podemos eliminar datos inútiles de vez en cuando como lo hicimos en el artículo anterior; También podemos crear tablas dinámicamente y luego insertar datos en la nueva tabla.
3. Use tablas dinámicas
Aquí adoptamos la segunda solución: el nombre de la tabla de datos es "SMS_Four-Digit Year_Two-Digit Mes", como "SMS_2016_02". Al insertar datos, obtenga el nombre de la tabla en función de la hora actual y luego inserte. Además, use cuarzo para generar la tabla de datos para el próximo mes y el próximo mes a las 2 en punto del 20 de cada mes:
Primero modificamos la clase DailyCountFilter, agregamos plan de tareas a esta clase y generamos tablas de datos regularmente:
DailyCountFilter.java
// Basado en el código anterior, agregue el siguiente código Public Class DailyCountFilter implementa SMSFilter {Scheduler Scheduler; @Override public void init () lanza SchedulerException {smsdao.createTable (0); // crear la tabla de datos de este mes smsdao.createTable (1); // Cree la tabla de datos del próximo mes SchedulerFactory SF = New STDSChedulerFactory (); sched = sf.getScheduler (); // Crear contenedor de cuarzo JobDatamap JobDatamap = new JobDatamap (); JobDatamap.put ("SMSDAO", SMSDAO); // Cree un mapa de datos que debe usarse al ejecutar una tarea // Crear un objeto de trabajo, que ejecuta la tarea real JobDetail Job = JobBuilder.newJob (CreateSMstableJob.Class) .UsingJobData (JobDatamap) .WithIdentity ("Crear trabajo de tabla SMS"). Build (); // Cree un objeto de activación, que se utiliza para describir las reglas de tiempo para activar la ejecución del trabajo // por ejemplo, Crontrigger Trigger = TriggerBuilder.newTrigger () .WithIdentity ("Crear disparador de tabla SMS") .withSchedule (cronscheduleBuilder.cronsChedule ("0 0 2 20 *?)))) mes.build (); sched.scheduleJob (trabajo, disparador); // registrar la tarea y activar las reglas program.start (); // Comienza a programar} @Override public void destruir () {try {sched.shutdown (); } catch (SchedulerException e) {}} public static class createSmStableJob implementa el trabajo {@Override public void ejecute (JobExecutionContext context) lanza JobExecutionException {JobDatamap dataMap = context.getJobDetail (). GetJobDatamap (); Smsdao smsdao = (smsdao) datamap.get ("smsdao"); // Obtenga el objeto smsdao pasado smsdao.createTable (1); // Cree la tabla de datos del próximo mes SMSDAO.CreateTable (2); // Crear la tabla de datos del próximo mes}}}A continuación, echemos un vistazo a algunos de los códigos de SMSDAO:
Smsdao.java
clase pública smsdao { / *** Crear una nueva tabla de registro** @param MessExcursion Número de meses Offset* / public void CreateTable (int mesExCursion) {String sql = "Crear tabla si no existe" + getTableName (mesExCursion) + "como SMS"; // Ejecutar la instrucción SQL}/ *** Guardar objeto de entidad SMSEntity*/ public void savoD SaveEntity (smsEntity smsEntity) {string sql = "insertar en" + getNowtableName () + "(móvil, ip, type) valores (?,?)"; // Ejecutar la instrucción SQL}/ *** Obtenga el número de móvil especificado y solicite el SMS hoy** @param Número móvil del usuario móvil* @@return Número de veces Solicitar el SMS hoy*/ public Long getMobilecount (String mobile) {String sql = "select Count (id) de" + getNowTableName () + "where mobile =? And Time> = curdate ()"; ";"; "; // Ejecute la instrucción SQL y devuelva el resultado de la consulta} // El método getIPCount se omite/ *** Obtenga el nombre de la tabla utilizada ahora*/ private String getNowtableName () {return getTableName (0); } private dateFormat dateFormat = new SimpleDateFormat ("yyyy_mm"); / *** Obtenga el nombre de la tabla del mes de compensación del mes** @param Montexcursion Número de meses Offset* @return Nombre de la tabla del mes correspondiente*/ String privado getTableName (int mesexcursion) {calendario calendar = calendar.getInstance (); calendario.add (calendario. Month, messcursion); Fecha fecha = calendar.gettime (); return "sms_" + dateFormat.format (fecha); }}Existe un requisito previo para la operación exitosa del método creable en SMSDAO, que es que hay una tabla de datos SMS. El método CreateTable copiará la estructura de la tabla SMS para crear una nueva tabla de datos.
Mantenemos los datos para enviar mensajes de texto (número de teléfono móvil, IP, tiempo, etc.) en lugar de eliminarlos directamente, porque es posible que necesitemos analizar estos datos en el futuro para obtener la información que queremos, como juzgar la tasa de llegada del SMS del proveedor de servicios, ya sea que alguien envíe mensajes de texto maliciosamente, etc., etc. incluso podemos obtener una "sorpresa" inesperada.
Lo anterior se trata de este artículo, espero que puedas continuar prestando atención.