Nos dois primeiros artigos, implementamos mensagens SMS de envio síncrono/assíncrono e limitando a frequência do envio de mensagens SMS. Neste artigo, apresentamos a limitação do número de vezes que enviamos mensagens SMS para o mesmo usuário (julgando com base no número de telefone celular e IP) todos os dias.
1. Estrutura da tabela de dados
Como precisamos registrar os registros de envio ao longo do dia, salvamos os dados no banco de dados aqui. A estrutura da tabela de dados é a seguinte:
Tipo é o tipo de código de verificação, como registro, senha de redefinição, etc.
O valor padrão do SendTime é o horário atual.
2. Limite o número de tempos de envio diário
Precisamos usar as classes de interface e entidade mencionadas no artigo anterior aqui.
DailyCountfilter.java
classe pública DailyCountFilter implementa smsfilter {private int ipdailymaxsendCount; Private Int MobiledAilyMaxSendCount; SMSDAO SMSDAO privado; // Algum código inútil é omitido @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); retornar true; }}O código principal é muito simples. Primeiro, determine se o número de vezes enviado para o número de telefone celular especificado atingiu o número máximo de tempos de envio e, em seguida, determine se o número de vezes enviado pela solicitação IP especificada atingiu o número máximo. Se nenhum deles for, salve o número do celular, o IP e outras informações enviadas desta vez ao banco de dados.
Obviamente, existem certos problemas com esta classe: outros threads podem ter salvo novos dados entre julgar se o número máximo excede o número máximo e os dados da entidade que estão sendo salvos. Isso resulta nos dois julgamentos acima não absolutamente precisos.
Podemos usar transações no nível de serialização para garantir que não haja erros, mas o custo é muito alto. Portanto, não faremos o processamento aqui. Porque implementamos a limitação da frequência de transmissão antes. Se usarmos o FrequencyFilter para filtrar uma vez e limitar a frequência de transmissão, o problema mencionado acima é basicamente impossível.
Há outro problema: com o tempo, esta tabela se tornará cada vez maior, resultando em um desempenho de consulta bastante ruim. Podemos excluir dados inúteis de vez em quando, como fizemos no artigo anterior; Também podemos criar tabelas dinamicamente e, em seguida, inserir dados na nova tabela.
3. Use tabelas dinâmicas
Aqui adotamos a segunda solução: o nome da tabela de dados é "SMS_FOUR-DIGIT Ano_Two-Digit Mês", como "SMS_2016_02". Ao inserir dados, obtenha o nome da tabela com base na hora atual e insira -os. Além disso, use quartzo para gerar a tabela de dados para o próximo mês e o próximo mês às 2 horas do dia 20 de cada mês:
Primeiro, modificamos a classe DailyCountFilter, adicionamos um plano de tarefas a esta classe e geramos tabelas de dados regularmente:
DailyCountfilter.java
// Com base no código acima, adicione a seguinte classe pública dailycountfilter implementa SMSFilter {Scheduler Scheduler privado; @Override public void init () lança schedulerexception {smsdao.createTable (0); // Crie a tabela de dados deste mês smsdao.createTable (1); // Crie a tabela de dados do próximo mês SchedulerFactory SF = new StdschedulerFactory (); programação = sf.getScheduler (); // Crie o contêiner de quartzo JobDatamap JobDatamap = new JobDatamap (); JobDatamap.put ("SMSDAO", SMSDAO); // Crie um mapa de dados que precise ser usado ao executar uma tarefa // Crie um objeto de emprego, que executa o trabalho de tarefa real jobDetail job = jobbuilder.newjob (CreateSmStableJob.class) .UsingJobData (JobDatamap) .WithIdidentity ("Criar trabalho da tabela SMS"). Build (); // Crie um objeto de gatilho, usado para descrever as regras de tempo para desencadear a execução do trabalho //, por exemplo, o crementador trigger = triggerbuilder.NewTrigger () .WithIdentity ("Criar tabela SMS" 02 *. Month.Build (); sched.schedulejob (trabalho, gatilho); // Registre a tarefa e acione o Scheding.start (); // Iniciar agendamento} @Override public void Destroy () {try {sched.shutdown (); } catch (scheduleRexception e) {}} classe estática pública CreateSmstablejob implementa Job {@Override public void Execute (contexto JobExecutionContext) lança JobExecutionException {JobDatamap DataMap = Context.getJobDetail (). Smsdao smsdao = (smsdao) datamap.get ("smsdao"); // Obtenha o objeto SMSDAO passado smsdao.createTable (1); // Crie a tabela de dados do próximo mês smsdao.createTable (2); // Crie a tabela de dados do próximo mês}}}Em seguida, vamos dar uma olhada em alguns dos códigos do SMSDAO:
Smsdao.java
public class smsdao { / *** Crie uma nova tabela de log** @Param MonthExcursion Número de meses deslocamento* / public void createTable (int MonthExcursion) {String sql = "Criar tabela se não existe" + gettableName (mensura) + "como sms"; // Execute o SQL Declarent}/ *** Salvar o objeto SMSENTITY Entity*/ public void saventity (smsentity smsentity) {string sql = "insert in" + getNowTableName () + "(valores móveis, ip, tipo) (?,?,?)"; // Execute a instrução SQL}/ *** Obtenha o número de celular especificado e solicite o SMS hoje** @param Mobile User Mobile Number* @return Número de vezes solicite o SMS hoje*/ public Long getMobilECount (String móvel) {String SQL = "Selecione count (id) de" + getNowTableName () + "onde // execute a instrução SQL e retorne o resultado da consulta} // O método getipCount é omitido/ *** Obtenha o nome da tabela usada agora*/ private string getNowTableName () {return gettableName (0); } Data privada Data DateFormat = new SimpleDateFormat ("yyyy_mm"); / *** Obtenha o nome da tabela do mês do mês** @param MonthExcursion Número de meses Offset* @Return Table Nome do mês correspondente*/ private string gettableName (int mêsexcursion) {calendário calendário = calendário.getInstance (); calendário.add (calendário.month, mensura mensal); Data data = calendário.gettime (); retornar "sms_" + dateFormat.format (data); }}Há um pré -requisito para a operação bem -sucedida do método CreateTable no SMSDAO, que é que existe uma tabela de dados SMS. O método CreateTable copiará a estrutura da tabela SMS para criar uma nova tabela de dados.
Mantemos os dados para enviar mensagens de texto (número do telefone celular, IP, tempo etc.) em vez de excluí -los diretamente, porque podemos precisar analisar esses dados no futuro para obter as informações que queremos, como julgar a taxa de chegada do SMS do provedor de serviços, se alguém enviou maliciosamente mensagens de texto, etc. Podemos até obter "surpresa".
O exposto acima é tudo sobre este artigo, espero que você possa continuar prestando atenção.