获取用户真实IP地址
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class IPUtil {
/**
* 获取请求的ip
*
* @return
*/
public static String getIp(HttpServletRequest request) {
String ipAddress = null;
ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null || ipAddress.length() == 0
|| "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0
|| "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0
|| "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if (ipAddress.equals("127.0.0.1")) {
// 根据网卡取本机配置的IP
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress = inet.getHostAddress();
}
}
//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15
if(ipAddress.indexOf(",")>0){
ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));
}
}
return ipAddress;
}
}
获取配置文件属性值
//application中IP数量限制
@Value("${phone.msg.ip.limit}")
private String ipLimitNum;
//application中系统数量限制
@Value("${phone.msg.sys.limit}")
private String sysLimitNum;
redis目录设置
//IP地址次数限制key(1自然天10次)
private static final String USER_PHONEMSG_IP_LIMIT = "USER_PHONEMSG_IP_LIMIT" + ":";
//系统次数限制key(1小时内50条)
private static final String USER_PHONEMSG_SYSTEM_LIMIT = "USER_PHONEMSG_SYSTEM_LIMIT" + ":";
判断当前IP是否达到发送限制
/**
* 判断当前IP是否达到发送限制
*
* @param ip
* @return
*/
public boolean checkIPLimit(String ip) {
Jedis jedis = jedisPool.getResource();
Calendar c = Calendar.getInstance();
//获取当前几号
int datenum = c.get(Calendar.DATE);
//今天是否有发送记录
String value = jedis.get(USER_PHONEMSG_IP_LIMIT + ip + ":" + datenum);
jedis.close();
if (StringUtils.isNotBlank(value)) {
int num = Integer.valueOf(value);
return num < Integer.valueOf(ipLimitNum) ? true : false;
} else {
return true;
}
}
判断当前系统是否达到发送限制
/**
* 判断当前系统是否达到发送限制
*
* @return
*/
public boolean checkSysLimit() {
Jedis jedis = jedisPool.getResource();
Calendar c = Calendar.getInstance();
//获取当前是几时
int hournum = c.get(Calendar.HOUR_OF_DAY);
//当前小时是否有发送记录
String value = jedis.get(USER_PHONEMSG_SYSTEM_LIMIT + hournum);
jedis.close();
if (StringUtils.isNotBlank(value)) {
int num = Integer.valueOf(value);
return num < Integer.valueOf(sysLimitNum) ? true : false;
} else {
return true;
}
}
当前IP发送短信数加1
/**
* 当前IP发送短信数加1
*
* @param ip
* @return
*/
public void setIPLimit(String ip) {
Jedis jedis = jedisPool.getResource();
Calendar c = Calendar.getInstance();
//获取当前几号
int datenum = c.get(Calendar.DATE);
String key = USER_PHONEMSG_IP_LIMIT + ip + ":" + datenum;
//今天是否有发送记录
String value = jedis.get(key);
//更新发送记录
if (StringUtils.isNotBlank(value) /*&& Integer.valueOf(value) < Integer.valueOf(ipLimitNum)*/) {//不需要判断是否超数
int num = Integer.valueOf(value);
//计数加1
num += 1;
//获取上次所剩时间
int time = Integer.parseInt(String.valueOf(jedis.ttl(key)));
//此次赋值会使生命周期丢失
jedis.set(key, String.valueOf(num));
//延续上次的生命周期
jedis.expire(key, time);
} else {
jedis.set(key, String.valueOf(1));
//生命周期为60*60*24秒,24小时为间隔,保证业务及释放
jedis.expire(key, 60 * 60 * 24);
}
jedis.close();
}
判断当前系统是否达到发送限制
/**
* 判断当前系统是否达到发送限制
*
* @return
*/
public void setSysLimit() {
Jedis jedis = jedisPool.getResource();
Calendar c = Calendar.getInstance();
//获取当前时刻
int hournum = c.get(Calendar.HOUR_OF_DAY);
String key = USER_PHONEMSG_SYSTEM_LIMIT + hournum;
//当前小时是否有发送记录
String value = jedis.get(key);
//更新发送记录
if (StringUtils.isNotBlank(value) /*&& Integer.valueOf(value) < Integer.valueOf(sysLimitNum)*/) {//不需要判断是否超数
int num = Integer.valueOf(value);
//计数加1
num += 1;
//获取上次所剩时间
int time = Integer.parseInt(String.valueOf(jedis.ttl(key)));
//此次赋值会使生命周期丢失
jedis.set(key, String.valueOf(num));
//延续上次的生命周期
jedis.expire(key, time);
} else {
jedis.set(key, String.valueOf(1));
//生命周期为60*60秒,最小1小时为间隔,保证业务及释放
jedis.expire(key, 60 * 60);
}
jedis.close();
}
发送短信方法中调用
//判断是否达到该时间段短信发送限制(系统、IP限制)
if(!(redisService.checkIPLimit(ip) && redisService.checkSysLimit())){
responseEntity.setting(CodeEnum.PHONE_LIMIT);
RequestContext.setResponseEntity(responseEntity);
return;
}
redisService.setIPLimit(ip);
redisService.setSysLimit();