Dieser Artikel ist der zweite Teil des Sendens von Textnachrichten. Hier stellen wir vor, wie Sie die Häufigkeit des Sendens von Textnachrichten an denselben Benutzer (basierend auf Mobiltelefonnummer und IP) einschränken.
1. Verwenden Sie Sitzung
Wenn es sich um ein Webprogramm handelt, ist es auch möglich, das letzte Mal in der Sitzung aufzuzeichnen, aber es kann umgangen werden. Am einfachsten ist es, den Browser oder den Cache und andere Daten, die die Sitzung markieren können, direkt neu zu starten, sodass die Datensätze in der Sitzung umgangen werden können. Obwohl viele Menschen nicht professionell in Computern sind und diese nicht gelernt haben. Wir müssen jedoch beachten, dass der Grund für die Begrenzung der Sendungsfrequenz darin besteht, "SMS -Bomben" zu verhindern, dh eine bösartige und häufig anliege Anfragen, Textnachrichten an eine Mobiltelefonnummer zu senden. Daher kann diese Person dieses Wissen verstehen.
Als nächstes verwenden wir das "globale" Datenlimit, um die Häufigkeit an denselben Benutzer zu senden. Lassen Sie uns zuerst einige "Vorbereitungsarbeiten" machen.
2. Definieren Sie Schnittstellen und Entitätsklassen
Die Entitätsklassen, die wir brauchen, sind wie folgt:
Smsentity.java
öffentliche Klasse SMSEntity {private Integer id; private String Mobile; private Zeichenfolge IP; privater Ganzzahltyp; Privatdatum; private String captcha; // Die Konstruktormethode sowie die Getter- und Setter -Methoden auslassen}Die Filteroberfläche lautet wie folgt:
Smsfilter.java
öffentliche Schnittstelle SMSFilter { / *** Initialisieren Sie den Filter* / void init () Ausnahme; /*** Bestimmen Sie, ob die Textnachricht gesendet werden kann. * @Param smSentity Der Inhalt der zugesandten Textnachricht * @return Wenn sie gesendet werden kann, wird er true zurückgegeben, andernfalls wird der falsche */ boolesche Filter zurückgegeben (SMSEntity SMSEntity); / *** Zerstöre den Filter*/ void Destroy ();}3. Hauptcode
Um die Sendungshäufigkeit zu begrenzen, müssen Sie eine bestimmte Mobiltelefonnummer (IP) und die Zeit des letzten Mals, als Sie eine SMS gesendet haben, aufzeichnen. Es ist sehr geeignet, um die Karte zu vervollständigen. Hier verwenden wir zuerst ConcurrentMap, um es zu implementieren:
Frequenzfilter.java
öffentliche Klasse FrequencyFilter implementiert SMSFilter { / *** Sendenintervall, Einheit: Millisekunden* / private long sendInterval; private concurrentmap <string, long> sendAddressMap = new ConcurrentHasMap <> (); // Ein nutzloser Code @Override public boolean filter (smsEntity smsentity) {if (setSendTime (smsEntity.getMobile ()) && setSendTime (smsEntity.getIp ())) {return true; } return false; } /*** Ändern Sie die Sendungszeit in die aktuelle Zeit. * Wenn das Zeitintervall des letzten gesendeten Senders größer als {@link #SendInterval} ist, setzen Sie die Sendungszeit auf die aktuelle Zeit. Andernfalls wird kein Inhalt geändert. * * @Param ID Senden Sie Handynummer oder IP * @return Wenn die Sendungszeit erfolgreich in die aktuelle Zeit geändert wird, wird true zurückgegeben. Andernfalls gibt es false */ private boolean setSendTime (String -ID) {Long CurrentTime = System.currentTimemillis () zurück; Long sendTime = sendAddressMap.putiFabSent (ID, Currentime); if (sendTime == null) {return true; } long NextCansendTime = sendTime + sendInterval; if (currentTime <NextCansendTime) {return false; } return sendAddressMap.replace (id, sendTime, currentime); }}Hier wird die Hauptlogik in der SetsendTime -Methode implementiert:
Zeilen 25-28: Erstens unter der Annahme, dass der Benutzer zum ersten Mal eine SMS sendet, sollte die aktuelle Zeit in die sendAddressmap eingebracht werden. Wenn Putifabsent NULL zurückgibt, bedeutet dies, dass der Benutzer zum ersten Mal tatsächlich eine SMS sendet und die aktuelle Zeit in die Karte gesteckt wurde und diese gesendet werden kann.
Zeilen 30-33: Wenn der Benutzer zum ersten Mal keine SMS sendet, muss festgestellt werden, ob das Zeit- und das aktuelle Intervall des Sendens der SMS letztes Mal und das Zeitintervall geringer sind als das Sendezeitintervall. Wenn es geringer ist als das Sendungszeitintervall, kann es nicht gesendet werden.
Zeile 35: Wenn das Zeitintervall groß genug ist, müssen Sie versuchen, die Sendungszeit auf die aktuelle Zeit einzustellen.
1) Dann können Sie die Zeilen 25-35 wiederholen, um sicherzustellen, dass sie absolut korrekt sind.
2) Sie können auch direkt glauben, dass es nicht gesendet werden kann, denn obwohl die theoretische Zeit für die "Ausführung der Zeilen 26-35" größer ist als das "Sendintervall", wie viel ist die Wahrscheinlichkeit? Es kann im Grunde ignoriert werden.
Dieser Code implementiert die Frequenzbeschränkung, aber wenn es nur "in" aber nicht "out" gibt, wird der von SendAddressMap besetzte Inhalt immer größer und größer, bis eine Ausnahme aus dem MemoryError erstellt wird. Als nächstes werden wir den Code hinzufügen, um abgelaufene Daten regelmäßig aufzuräumen.
4. Die abgelaufenen Daten bereinigen
Frequenzfilter.java
/*** Basierend auf dem obigen Code fügen Sie den folgenden Code hinzu. private timer timer = new timer ("sms_frequency_filter_clear_data_thread"); @Override public void init () {timer.Schedule (neuer TimerTask () {@Override public void run () {CleanSendadDressMap ();}}, CleanMapinterval, CleanMapinterval); } / *** Alle abgelaufenen Daten in sendAddressMap löschen* / private void CleanSendAddressMap () {Long Currentime = System.currentTimemillis (); Long expiresendTime = currentTime - sendInterval; für (String -Schlüssel: sendAddressMap.keyset ()) {long sendTime = sendAddressMap.get (Schlüssel); if (sendTime <expiresendTime) {sendAddressMap.remove (Schlüssel, sendTime); }}} @Override public void destroy () {timer.cancel (); }}Dieses Programm ist nicht kompliziert. Starten Sie einen Timer und führen Sie die CleanSendAddressMap -Methode aus, um alle Millisekunden von CleanMapinterval zu säubern, um abgelaufene Daten zu beseitigen.
Die CleanSendAddressMap -Methode erhält zunächst die aktuelle Zeit und erhält einen Zeitwert, der auf der aktuellen Zeit basiert: Alle Textnachrichten werden nach dieser Zeit gesendet, SMS können nicht erneut gesendet werden. Löschen Sie dann alle Schlüsselwertpaare mit einem Wert, der kleiner als dieser Zeitwert von der gesamten Karte ist.
Nach dem Hinzufügen des oben genannten Codes hat der Anfangscode natürlich einen weiteren Fehler: Wenn die letzte Zeile sendAddressMap.replace (ID, SendTime, Currentime) nicht ausführen kann, sind nicht unbedingt andere Threads ersetzt, aber es ist auch möglich, dass der Reinigungs -Thread die Daten gelöscht hat. Daher müssen wir die letzten Zeilen der SetSendTime -Methode ändern:
Frequenzfilter.java
private boolean setSendTime (String -ID) {// Der vorherige Code weglassen, wenn (sendAddressMap.replace (id, sendTime, currentime)) {return true; } return sendAddressMap.putiFababSent (ID, Currentime) == NULL;}Wenn der Ersatz hier erfolgreich ist, kehren Sie direkt zurück.
Wenn der Ersatz nicht erfolgreich ist, kann es sein, dass zuerst andere Threads (im ersten Fall) ersetzt wurden. Es kann auch sein, dass sie durch den gereinigten Faden gelöscht wurden (im zweiten Fall); Es kann sogar sein, dass sie zuerst vom gereinigten Faden gelöscht wurden und andere Threads neue Zeitwerte eingefügt haben (im dritten Fall).
Zu diesem Zeitpunkt wird der Code, der die Sendungszeit einschränkt, abgeschlossen. Natürlich hat dieses Programm einen kleinen Fehler oder eine "Funktion":
Wenn ein Kunde mit IP "192.168.0.1" Anfragen zum Senden einer Textnachricht an die Mobiltelefonnummer "12345678900" anfordert und dann Anfragen zum Senden einer Textnachricht an die Handynummer "12345678900" innerhalb des SendInterval auf dem Computer mit IP "192.168.0.2" ". Dann wird die Textnachricht nicht gesendet, und das letzte Mal der Mobiltelefonnummer "12345678900" wird auf die aktuelle Zeit eingestellt.
5. Beispiele des Gebrauchs
Im Folgenden geben wir eine Serverebene zur Verfügung, um anzuzeigen, wie der Code in den vorherigen Artikel und diesen Artikel integriert wird:
SmsService.java
öffentliche Klasse SMSService {private SMS SMS; private Liste <SmsFilter> Filter; private Eigenschaften Vorlage; // Einige Codes werden weggelassen/*** Verifizierungscode senden** @param smsentity grundlegende Daten zum Senden von Textnachrichten* @return Wenn die Einreichung erfolgreich ist, senden Sie 0 zurück. Ansonsten senden Sie andere Werte zurück. */ public int sendcaptcha (smsentity smsentity) {für (SMSFilter filter: filter) {if (! filter.filter (smsentity)) {return 1; }} if (smsentity.register_type.equals (smsentity.ettype ())) {sendErregisterss (smsentity); } else {return 2; } return 0; } /** * Send registration verification code* * @param smsEntity Basic data for sending text messages*/ private void sendRegisterSms(SmsEntity smsEntity) { sms.sendMessage(smsEntity.getMobile(), template.getProperty("register").replace("{captcha}", smsEntity.getCaptcha())); }}Dann "Inject" FrequencyFilter und AsyncsmSmpl im vorherigen Artikel durch die festgelegte Methode.
Das obige dreht sich alles um diesen Artikel. Ich hoffe, dass es für alle hilfreich sein wird, Java -Programme zu lernen.