Dans les deux premiers articles, nous avons mis en œuvre des messages SMS synchrones / asynchrones et limitant la fréquence de l'envoi de messages SMS. Dans cet article, nous introduisons la limitation du nombre de fois que nous envoyons des messages SMS au même utilisateur (à en juger sur la base du numéro de téléphone mobile et de l'IP).
1. Structure de la table de données
Étant donné que nous devons enregistrer les enregistrements d'envoi tout au long de la journée, nous enregistrons les données dans la base de données ici. La structure de la table de données est la suivante:
Le type est le type de code de vérification, tel que l'enregistrement, la réinitialisation du mot de passe, etc.
La valeur par défaut de Sendtime est l'heure actuelle.
2. Limiter le nombre de temps d'envoi quotidien
Nous devons utiliser les cours d'interface et d'entité mentionnés dans l'article précédent ici.
DailyCountFilter.java
La classe publique DailyCountFilter implémente SMSFilter {private int ipDailyMaxSendCount; private int mobiledailymaxsendCount; SMSDAO privé SMSDAO; // Un code inutile est omis @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); Retour Vrai; }}Le code principal est très simple. Tout d'abord, déterminez si le nombre de fois envoyé au numéro de téléphone mobile spécifié a atteint le nombre maximum de temps d'envoi, puis déterminer si le nombre de fois envoyé par la demande IP spécifiée a atteint le nombre maximum. Si aucun d'entre eux ne le est, enregistrez le numéro de téléphone mobile, l'IP et d'autres informations envoyées cette fois à la base de données.
Bien sûr, il y a certains problèmes avec cette classe: d'autres threads peuvent avoir enregistré de nouvelles données entre juger si le nombre maximum dépasse le nombre maximum et les données d'entité enregistrées. Il en résulte que les deux jugements ci-dessus ne sont pas absolument exacts.
Nous pouvons utiliser les transactions au niveau de sérialisation pour nous assurer qu'il n'y aura pas d'erreurs, mais le coût est trop élevé. Par conséquent, nous ne ferons pas le traitement ici. Parce que nous avons mis en œuvre la limitation de la fréquence de transmission auparavant. Si nous utilisons Frequencyfilter pour filtrer une fois et limiter la fréquence de transmission, le problème mentionné ci-dessus est fondamentalement impossible.
Il y a un autre problème: au fil du temps, ce tableau deviendra de plus en plus grand, ce qui entraînera une performance de requête assez médiocre. Nous pouvons supprimer des données inutiles de temps en temps comme nous l'avons fait dans l'article précédent; Nous pouvons également créer des tableaux dynamiquement, puis insérer des données dans la nouvelle table.
3. Utilisez des tables dynamiques
Ici, nous adoptons la deuxième solution: le nom de la table de données est "SMS_Four-Digit Year_TWO-Digit Mois", tel que "SMS_2016_02". Lorsque vous insérez des données, obtenez le nom du tableau en fonction de l'heure actuelle, puis insérez-les. De plus, utilisez le quartz pour générer le tableau de données pour le mois prochain et le mois prochain à 2 heures le 20 de chaque mois:
Nous modifions d'abord la classe DailyCountFilter, ajoutons un plan de tâche à cette classe et générons régulièrement des tables de données:
DailyCountFilter.java
// Sur la base du code ci-dessus, ajoutez le code suivant Classe publique DailyCountFilter implémente SMSFilter {Private Scheduler Sched; @Override public void init () lève ScheduleReXception {smsdao.createTable (0); // Créer le tableau de données de ce mois-ci SMSDAO.CreateTable (1); // Créer des données du mois prochain SchedulerFactory SF = new StdsCheDulerFactory (); sched = sf.getscheduler (); // Créer un conteneur de quartz jobdatamap jobdatamap = new JobDataMap (); jobdatamap.put ("smsdao", smsdao); // Créer une carte de données qui doit être utilisée lors de l'exécution d'une tâche // Créer un objet Job, qui exécute la tâche réelle JobDetail Job = jobBuilder.newjob (créeSmStableJob.class) .usingJobdata (jobDataMap) .WithIdentity ("Créer un travail de table SMS"). Build (); // Créer un objet de déclenchement, qui est utilisé pour décrire les règles de temps pour déclencher l'exécution du travail // par exemple, CronTrigger Trigger = TriggerBuilder.NewTrigger () .WithIdentity (Créer un déclencheur de table SMS ") .WithSchedule (ConscheduleBuilder.Cronschedule (" 0 0 2 20 * ") // 2 o'Clock mois.build (); sched.scheduleJob (travail, déclencheur); // enregistrer la tâche et déclencher les règles sched.start (); // Démarrer la planification} @Override public void destrement () {try {sched.shutdown (); } catch (scheduleRexception e) {}} public static class static CreateSMStableJob implémente Job {@Override public void execute (jobExecution Context) lève JobExEcutionException {jobDataMap dataMap = context.getJobDetail (). getJobDataMap (); Smsdao smsdao = (smsdao) dataMap.get ("smsdao"); // Obtenez l'objet SMSDAO passé SMSDAO.CreateTable (1); // Créer le tableau de données du mois suivant smsdao.createTable (2); // Créer le tableau de données du mois suivant}}}Ensuite, jetons un coup d'œil à certains des codes de SMSDAO:
Smsdao.java
classe publique smsdao {/ ** * Créer une nouvelle table de journal * * @param MoneExcursion Nombre de mois Offset * / public void CreateTable (int menscursion) {String sql = "Create Table If Not Exist" + GetTableName (MoneExCursion) + "Like Sms"; // Exécuter l'instruction SQL} / ** * SAVE SMSENSITY ENTITY Object * / public void Saveentity (smSentity smSentity) {String SQL = "INSERT IN" + GetNowtABLename () + "(mobile, ip, type) valeurs (?,?,?)"; // Exécuter l'instruction SQL} / ** * Obtenez le numéro de mobile spécifié et demandez le numéro de mobile SMS aujourd'hui * * @Param Mobile User * @return Nombre de fois Demandez aux SMS aujourd'hui * / public long getMobileCount (String Mobile) {String SQL = "Select Count (id) from" + getNowTABLeName () + "Where Mobile =? And Time> = Curdate ()"; // Exécutez l'instruction SQL et renvoyez le résultat de la requête} // La méthode getIPCount est omise / ** * Obtenez le nom de la table utilisé maintenant * / private String getNowtableName () {return getTableName (0); } private dateFormat dateFormat = new SimpledateFormat ("yyyy_mm"); / ** * Obtenez le nom de la table du mois du mois du mois * * @param MoneExcursion Numéro de mois Offset * @return Nom de la table du mois correspondant * / private String getTableName (int menscursion) {calendar calendar = calendar.getInSitance (); Calendar.Add (Calendar.month, MoneExcursion); Date de date = calendar.getTime (); return "sms_" + dateformat.format (date); }}Il existe une condition préalable pour le fonctionnement réussi de la méthode de création dans SMSDAO, à savoir qu'il existe un tableau de données SMS. La méthode CreateTable copiera la structure de la table SMS pour créer une nouvelle table de données.
Nous conservons les données pour l'envoi de messages texte (numéro de téléphone mobile, IP, temps, etc.) au lieu de les supprimer directement, car nous devrons peut-être analyser ces données à l'avenir pour obtenir les informations que nous voulons, comme juger le taux d'arrivée du SMS du fournisseur de services, que quelqu'un ait envoyé des messages texte malveillante, etc., nous pouvons même être inattendus "surprise".
Ce qui précède concerne cet article, j'espère que vous pourrez continuer à faire attention.