Эта статья является второй частью отправки текстовых сообщений. Здесь мы представляем, как ограничить частоту отправки текстовых сообщений одному и тому же пользователю (на основе номера мобильного телефона и IP).
1. Используйте сеанс
Если это веб -программа, также можно записать в последний раз, отправляемый в сессию, но она может быть обойденной. Самое простое - напрямую перезапустить браузер или очистить кэш и другие данные, которые могут отметить сеанс, чтобы записи в сеансе могут быть обойдены. Хотя многие люди не являются профессиональными в компьютерах и не узнали их. Но мы должны отметить, что причина ограничения частоты отправки состоит в том, чтобы предотвратить «SMS -бомбы», то есть кто -то злонамеренно и часто просит отправлять текстовые сообщения на номер мобильного телефона. Поэтому этот человек может понять это знание.
Затем мы используем «глобальный» ограничение данных для отправки частоты одному и тому же пользователю. Давайте сначала сделаем работу «подготовки».
2. Определите интерфейсы и классы сущности
Классы сущности, которые нам нужны, следующие:
Smsentity.java
открытый класс Smsentity {Private Integer ID; частная строка Mobile; частная строка IP; частное целочисленное тип; Частное время даты; частная строка Captcha; // Опустите метод конструктора и методы Getter и Setter}Интерфейс фильтрации выглядит следующим образом:
Smsfilter.java
Public Interface smsfilter { / *** Инициализировать фильтр* / void init () бросает исключение; /*** Определите, можно ли отправить текстовое сообщение. * @param smsentity Содержание текстового сообщения, которое будет отправлено * @return, если его можно отправить, оно вернет true, в противном случае он вернет false */ boolean -фильтр (Smsentity Smsentity); / *** Уничтожить фильтр*/ void destress ();}3. Основной код
Чтобы ограничить частоту отправки, вам необходимо записать определенный номер мобильного телефона (IP) и время в последний раз, когда вы отправили текстовое сообщение. Это очень подходит для завершения карты. Здесь мы сначала используем concurrentMap для его реализации:
Частотафильтер. Java
Public Class Clatefilter реализует SMSFilter { / *** Интервал отправки, единица: миллисекунды* / private Long SendInterval; private concurrentMap <string, long> sendddressmap = new concurrenthashmap <> (); // какой -то бесполезный код пропущен @override public boolean filter (smsentity smsentity) {if (setsendtime (smsentity.getmobile ()) && setsendtime (smsentity.getip ())) {return true; } вернуть false; } /*** Измените время отправки в текущее время. * Если интервал времени из последнего отправки больше, чем {@Link #SendInterval}, установите время отправки в текущее время. В противном случае, контент не будет изменен. * * @param id Отправить номер мобильного телефона или ip * @return Если время отправки успешно изменено в текущее время, он вернет true. В противном случае он вернет false */ private boolean setsendtime (string id) {long currenttime = system.currenttimemillis (); Long sendtime = sendddressmap.putifabsent (id, currenttime); if (sendtime == null) {return true; } long nextcansendtime = sendtime + sendinterval; if (CurrentTime <nextCansendtime) {return false; } return sendDdressMap.replace (id, sendtime, currenttime); }}Здесь основная логика реализована в методе SetSendtime :
Строки 25-28: Во-первых, предполагая, что пользователь отправляет SMS в первый раз, затем текущее время должно быть помещено в SendAdDressMap. Если Putifabsent возвращает NULL, это означает, что пользователь действительно отправляет SMS в первый раз, и текущее время было помещено в карту, и его можно отправить.
Строки 30-33: Если пользователь не отправляет SMS в первый раз, то необходимо определить, является ли время и текущий интервал отправки SMS в прошлый раз и интервал времени меньше интервала времени отправки. Если это меньше, чем интервал времени отправки, то его нельзя отправить.
Строка 35: Если интервал времени достаточно велик, вам нужно попытаться установить время отправки в текущее время.
1) Затем вы можете повторить строки 25-35, чтобы убедиться, что они абсолютно правиль.
2) Вы также можете напрямую подумать, что его нельзя отправить, потому что, хотя теоретическое время для «выполнения строк 26-35» может быть больше, чем «интервал отправки», сколько стоит вероятность? Это в основном можно игнорировать.
Этот код реализует частоту ограничения, но если есть только «в», но не «выходить», то содержание, занятое SendAddressMap, станет больше и больше, пока не будет создано исключение OutfmemoryError. Затем мы добавим код для регулярной очистки данных с истекшим сроком действия.
4. Очистка
Частотафильтер. Java
/*** На основе вышеуказанного кода добавьте следующий код*/public class clatefilter, реализует SMSFilter {Private Long CleanMapInterval; частный таймер timer = new Timer ("sms_frequency_filter_clear_data_thread"); @Override public void init () {timer.schedule (new timertask () {@override public void run () {changeSendAddressMap ();}}, CleanMapinterval, CleanMapinterval); } / *** Удалить все истекшие данные в SendAdDressMap* / private void changeSendDDressMap () {long CurrentTime = System.currentTimeMillis (); Long ExciresendTime = CurrentTime - SendInterval; для (String Key: SendDdressMap.keySet ()) {long SendTime = sendDdressMap.get (key); if (sendtime <expiresendtime) {sendddressmap.remove (key, sendtime); }}} @Override public void destry () {timer.cancel (); }}Эта программа не сложна. Запустите таймер и выполните метод очистки adendAddressmap каждые миллисекунд чистого мапинтервала для очистки истекших данных.
Сначала метод очистки adendAddressmap получает текущее время и получает значение времени на основе текущего времени: все текстовые сообщения отправляются после этого времени, SMS не может быть отправлено снова. Затем удалите все пары клавиш со значением меньше этого времени, чем это время, со всей карты.
Конечно, после добавления вышеуказанного кода у начальной кода есть еще одна ошибка: когда последняя строка SendDdressMap.Replace (ID, SendTime, CurrentTime) не выполняется, не обязательно заменена другие потоки, но также возможно, что поток чистки удалил данные. Поэтому нам нужно изменить последние несколько строк метода SetSendtime:
Частотафильтер. Java
Private Boolean SetSendTime (идентификатор строки) {// Опустите предыдущий код if (sendDdressmap.replace (id, sendtime, currenttime)) {return true; } return sendDdressMap.putifabsent (id, currentTime) == null;}Если замена здесь успешна, верните истину напрямую.
Если замена не является успешной, то может быть, что другие потоки были заменены сначала (в первом случае); Возможно, они были удалены очищенной нитью (во втором случае); Возможно, даже сначала они были удалены очищенным потоком, а другие потоки вставили новые значения времени (в третьем случае).
На этом этапе код, ограничивающий время отправки, завершен. Конечно, эта программа имеет небольшую ошибку или «функцию»:
Если клиент с IP "192.168.0.1" запросится на отправку текстового сообщения на номер мобильного телефона "12345678900", а затем просит отправить текстовое сообщение на номер мобильного телефона "12345678900" в SendInterval на машине с IP "192.168.0.2". Затем текстовое сообщение не будет отправлено, и последний раз на номере мобильного телефона «12345678900» устанавливается на текущее время.
5. Примеры использования
Ниже мы предоставляем уровень сервера, чтобы показать, как интегрировать код в предыдущей статье и в этой статье:
Smsservice.java
открытый класс SMSService {Private SMS SMS; Частный список <msfilter> фильтры; Шаблон частных свойств; // Некоторые коды опущены/*** Отправить код проверки** @param smsentity Основные данные для отправки текстовых сообщений* @return Если отправка успешна, верните 0. В противном случае верните другие значения. */ public int sendcaptcha (smsentity smsentity) {for (smsfilter filter: filters) {if (! filter.filter (smsentity)) {return 1; }} if (smsentity.register_type.equals (smsentity.gettype ())) {sendregistersms (smsentity); } else {return 2; } return 0; } / *** Отправить код проверки регистрации*** @param Smsentity Основные данные для отправки текстовых сообщений* / private void sendergistersmss (smsentity smsentity) {sms.sendmessage (smsentity.getmobile (), template.getproperty ("regired"). Заменить ("{captcha}", smplate.getproperty ("regired"). Заменить ("{captcha}", smplate.getproperty ("regired"). }}Затем, «инъекция» частотфильтра и асинкссмсмпл в предыдущей статье с помощью метода SET.
Выше приведено все об этой статье, я надеюсь, что для всех будет полезно изучать программирование Java.