獲取用戶真實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();