獲取用戶真實(shí)IP地址
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class IPUtil {
/**
* 獲取請(qǐng)求的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")) {
// 根據(jù)網(wǎng)卡取本機(jī)配置的IP
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress = inet.getHostAddress();
}
}
//對(duì)于通過(guò)多個(gè)代理的情況猛铅,第一個(gè)IP為客戶端真實(shí)IP,多個(gè)IP按照','分割
if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15
if(ipAddress.indexOf(",")>0){
ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));
}
}
return ipAddress;
}
}
獲取配置文件屬性值
//application中IP數(shù)量限制
@Value("${phone.msg.ip.limit}")
private String ipLimitNum;
//application中系統(tǒng)數(shù)量限制
@Value("${phone.msg.sys.limit}")
private String sysLimitNum;
redis目錄設(shè)置
//IP地址次數(shù)限制key(1自然天10次)
private static final String USER_PHONEMSG_IP_LIMIT = "USER_PHONEMSG_IP_LIMIT" + ":";
//系統(tǒng)次數(shù)限制key(1小時(shí)內(nèi)50條)
private static final String USER_PHONEMSG_SYSTEM_LIMIT = "USER_PHONEMSG_SYSTEM_LIMIT" + ":";
判斷當(dāng)前IP是否達(dá)到發(fā)送限制
/**
* 判斷當(dāng)前IP是否達(dá)到發(fā)送限制
*
* @param ip
* @return
*/
public boolean checkIPLimit(String ip) {
Jedis jedis = jedisPool.getResource();
Calendar c = Calendar.getInstance();
//獲取當(dāng)前幾號(hào)
int datenum = c.get(Calendar.DATE);
//今天是否有發(fā)送記錄
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;
}
}
判斷當(dāng)前系統(tǒng)是否達(dá)到發(fā)送限制
/**
* 判斷當(dāng)前系統(tǒng)是否達(dá)到發(fā)送限制
*
* @return
*/
public boolean checkSysLimit() {
Jedis jedis = jedisPool.getResource();
Calendar c = Calendar.getInstance();
//獲取當(dāng)前是幾時(shí)
int hournum = c.get(Calendar.HOUR_OF_DAY);
//當(dāng)前小時(shí)是否有發(fā)送記錄
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;
}
}
當(dāng)前IP發(fā)送短信數(shù)加1
/**
* 當(dāng)前IP發(fā)送短信數(shù)加1
*
* @param ip
* @return
*/
public void setIPLimit(String ip) {
Jedis jedis = jedisPool.getResource();
Calendar c = Calendar.getInstance();
//獲取當(dāng)前幾號(hào)
int datenum = c.get(Calendar.DATE);
String key = USER_PHONEMSG_IP_LIMIT + ip + ":" + datenum;
//今天是否有發(fā)送記錄
String value = jedis.get(key);
//更新發(fā)送記錄
if (StringUtils.isNotBlank(value) /*&& Integer.valueOf(value) < Integer.valueOf(ipLimitNum)*/) {//不需要判斷是否超數(shù)
int num = Integer.valueOf(value);
//計(jì)數(shù)加1
num += 1;
//獲取上次所剩時(shí)間
int time = Integer.parseInt(String.valueOf(jedis.ttl(key)));
//此次賦值會(huì)使生命周期丟失
jedis.set(key, String.valueOf(num));
//延續(xù)上次的生命周期
jedis.expire(key, time);
} else {
jedis.set(key, String.valueOf(1));
//生命周期為60*60*24秒,24小時(shí)為間隔揖庄,保證業(yè)務(wù)及釋放
jedis.expire(key, 60 * 60 * 24);
}
jedis.close();
}
判斷當(dāng)前系統(tǒng)是否達(dá)到發(fā)送限制
/**
* 判斷當(dāng)前系統(tǒng)是否達(dá)到發(fā)送限制
*
* @return
*/
public void setSysLimit() {
Jedis jedis = jedisPool.getResource();
Calendar c = Calendar.getInstance();
//獲取當(dāng)前時(shí)刻
int hournum = c.get(Calendar.HOUR_OF_DAY);
String key = USER_PHONEMSG_SYSTEM_LIMIT + hournum;
//當(dāng)前小時(shí)是否有發(fā)送記錄
String value = jedis.get(key);
//更新發(fā)送記錄
if (StringUtils.isNotBlank(value) /*&& Integer.valueOf(value) < Integer.valueOf(sysLimitNum)*/) {//不需要判斷是否超數(shù)
int num = Integer.valueOf(value);
//計(jì)數(shù)加1
num += 1;
//獲取上次所剩時(shí)間
int time = Integer.parseInt(String.valueOf(jedis.ttl(key)));
//此次賦值會(huì)使生命周期丟失
jedis.set(key, String.valueOf(num));
//延續(xù)上次的生命周期
jedis.expire(key, time);
} else {
jedis.set(key, String.valueOf(1));
//生命周期為60*60秒蹄梢,最小1小時(shí)為間隔,保證業(yè)務(wù)及釋放
jedis.expire(key, 60 * 60);
}
jedis.close();
}
發(fā)送短信方法中調(diào)用
//判斷是否達(dá)到該時(shí)間段短信發(fā)送限制(系統(tǒng)、IP限制)
if(!(redisService.checkIPLimit(ip) && redisService.checkSysLimit())){
responseEntity.setting(CodeEnum.PHONE_LIMIT);
RequestContext.setResponseEntity(responseEntity);
return;
}
redisService.setIPLimit(ip);
redisService.setSysLimit();