最初の2つの記事では、SMSメッセージを送信し、SMSメッセージを送信する頻度を制限する同期/非同期の送信を実装しました。この記事では、SMSメッセージを同じユーザーに送信する回数(携帯電話番号とIPに基づいて審査)を毎日紹介します。
1。データテーブル構造
送信レコードを1日を通して記録する必要があるため、ここでデータをデータベースに保存します。データテーブルの構造は次のとおりです。
タイプは、登録、リセットパスワードなど、検証コードのタイプです。
SendTimeのデフォルト値は現在の時刻です。
2。毎日の送信時間の数を制限します
ここで前の記事で説明したインターフェイスとエンティティのクラスを使用する必要があります。
dailycountfilter.java
パブリッククラスdailycountfilterはsmsfilter {private int ipdailymaxsendcount; private int mobiledailymaxsendcount;プライベートSMSDAO SMSDAO; //いくつかの役に立たないコードは省略されています@Override public booleanフィルター(smsentity smsentity){if(smsdao.getMobileCount(smsentity.getMobile())> = MobileDailyMaxSendCount){return false; } if(smsdao.getipcount(smsentity.getip())> = ipdailymaxsendcount){return false; } smsdao.saveEntity(smsentity); trueを返します。 }}メインコードは非常に簡単です。まず、指定された携帯電話番号に送信された回数が送信時間の最大数に達したかどうかを判断し、指定されたIP要求によって送信された回数が最大数に達したかどうかを判断します。いずれもない場合は、携帯電話番号、IP、その他の情報を保存して、今回はデータベースに送信されます。
もちろん、このクラスには特定の問題があります。他のスレッドは、最大数が最大数を超えるかどうかを判断することと、保存されているエンティティデータを判断する間に新しいデータを保存した可能性があります。これにより、上記の2つの判断が絶対に正確ではありません。
シリアル化レベルのトランザクションを使用して、エラーがないことを確認できますが、コストが高すぎます。したがって、ここでは処理を行いません。以前に伝送周波数を制限することを実装したためです。 FuelchedFilterを使用して1回フィルタリングして送信周波数を制限する場合、上記の問題は基本的に不可能です。
別の問題があります。時間が経つにつれて、このテーブルはより大きくなり、クエリのパフォーマンスがかなり低くなります。前の記事で行ったように、時々役に立たないデータを削除できます。テーブルを動的に作成してから、新しいテーブルにデータを挿入することもできます。
3.動的テーブルを使用します
ここでは、2番目のソリューションを採用します。データテーブルの名前は、「sms_2016_02」などの「sms_four-digit year_two-digit month」です。データを挿入するときは、現在の時刻に基づいてテーブル名を取得し、挿入します。さらに、Quartzを使用して、来月の2時に来月と来月のデータテーブルを生成します。
最初にDailyCountFilterクラスを変更し、このクラスにタスク計画を追加し、定期的にデータテーブルを生成します。
dailycountfilter.java
//上記のコードに基づいて、次のコードを追加しますpublic class dailycountfilterを実装しましたsmsfilter {private scheduler schedy; @Override public void init()Throws schedulerexception {smsdao.createtable(0); //今月のデータテーブルSMSDAO.createtable(1); //来月のデータテーブルSchedulerFactory sf = new StdschedulerFactory(); sched = sf.getscheduler(); // Quartz Container jobdatamap jobdatamap = new jobdatamap(); jobdatamap.put( "smsdao"、smsdao); //タスクを実行するときに使用する必要があるデータマップを作成する//ジョブオブジェクトを作成します。これは実際のタスクを実行しますjobdetail job = jobbuilder.newjob(createsmstablejob.class).usingjobdata(jobdatamap).withidentity( "create sms table job")。 //ジョブの実行をトリガーするための時間ルールを説明するために使用されるトリガーオブジェクトを作成します//たとえば、crontriggerトリガー= triggerbuilder.newtrigger().withidentity( "create smsテーブルトリガー").withschedule(cronschedulebuilderdedule.clonschedule on 20 * ")")毎月のbuild(); sched.schedulejob(job、trigger); //タスクを登録し、ルールSched.start()をトリガーします。 //スケジューリングを開始} @Override public void Destroy(){try {sched.shutdown(); } catch(schedulerexception e){}} public static class createsmstablejobを実装{@Override public void execute(jobexecutioncontext context)throws jobexecutionexception {jobdatamap datamap = context.getjobdatail()。getjobdatamap(); smsdao smsdao =(smsdao)datamap.get( "smsdao"); //渡されたsmsdaoオブジェクトsmsdao.createtable(1)を取得します。 //翌月のデータテーブルSMSDAO.CREATETABLE(2)を作成します。 //翌月のデータテーブルを作成}}}次に、SMSDAOのコードのいくつかを見てみましょう。
smsdao.java
パブリッククラスSMSDAO { / ***新しいログテーブルの作成** @param MonthExcursion数offset* / public void createTable(int moneexcursion){string sql = "存在しない場合はテーブルの作成" + gettablename(moneexcursion) + "like sms"; // SQLステートメントを実行}/ *** SMSENTITYエンティティオブジェクトを保存*/ public void saveEntity(smsentity smsentity){string sql = "inserting into" + getNowTableName() + "(モバイル、IP、タイプ)値(?、?、?)"; // SQLステートメントを実行}/ ***指定された携帯電話番号を取得し、今日SMSをリクエストします** @paramモバイルユーザー携帯電話番号* @return数はSMSをリクエストします// sqlステートメントを実行してクエリ結果を返します} // getIpCountメソッドは省略/ ***今使用されているテーブルの名前を取得*/ private文字列getNowTableName(){return getTableName(0); } private dateformat dateformat = new SimpledateFormat( "yyyy_mm"); / ***月のテーブル名を取得しますcalendar.add(calendar.month、monthexcursion);日付date = calendar.getTime(); "sms_" + dateformat.format(date); }}SMSDAOで作成されたメソッドの操作を成功させるための前提条件があります。これは、SMSデータテーブルがあるということです。作成可能なメソッドは、SMSテーブルの構造をコピーして新しいデータテーブルを作成します。
直接削除する代わりに、テキストメッセージ(携帯電話番号、IP、時間など)を送信するデータ(携帯電話番号、IP、時間など)を保持します。これは、サービスプロバイダーのSMSの到着率を判断するなど、将来的にこれらのデータを分析するためにこれらのデータを分析する必要があるため、悪意のあるテキストメッセージなどを判断するなどです。
上記はすべてこの記事についてです。私はあなたが引き続き注意を払うことができることを願っています。