1:記錄用戶操作記錄
實現思路: 利用aop,可以攔截每個用戶調用的滅個接口,將每個接口的名稱,用戶ip 用戶名記錄下來
1.1:定義切點
private RedisDao redisDao;
@Pointcut("execution(* kainian.wu.demoweb.controller.*.*(..))")
public void pointCkeck(){}
1.2:獲取操作數據,將數據存入數據
@Before("pointCkeck()")
public void beforeSleep(JoinPoint joinPoint) throws CMSException {
//1:方式名稱
String methodName = joinPoint.getSignature().getName();
System.out.println("方式名"+methodName);
//2:\
String reqParam = "";
String reqParam21 = "";
String[] reqParam1 = null;
String[] reqParam2 = null;
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method targetMethod = methodSignature.getMethod();
Annotation[] annotations = targetMethod.getAnnotations();
for (Annotation annotation : annotations) {
//此處可以改成自定義的註解
if (annotation.annotationType().equals(NoRepeatSubmit.class)) {
NoRepeatSubmit apiOperation4 = (NoRepeatSubmit) annotation;
reqParam21 = apiOperation4.vaue();
continue;
}
if (annotation.annotationType().equals(ApiOperation.class)) {
ApiOperation apiOperation = (ApiOperation) annotation;
reqParam = apiOperation.value();
continue;
}
if (annotation.annotationType().equals(GetMapping.class)) {
GetMapping getMapping = (GetMapping) annotation;
reqParam1 = getMapping.value();
continue;
}
if (annotation.annotationType().equals(PostMapping.class)) {
PostMapping getMapping = (PostMapping) annotation;
reqParam2 = getMapping.value();
continue;
}
}
System.out.println("攔截的註解的參數:");
System.out.println("方法名稱"+reqParam);
//3:接口路徑
System.out.println("方法路徑"+JSON.toJSON(reqParam1));
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 當前IP地址
String ipAddr = getRemoteHost(request);
System.out.println("IP地址"+ipAddr);
String url = request.getRequestURL().toString();
log.info("請求URL{}:",url);
//4;參數
List<Object> args1 = Arrays.asList( joinPoint.getArgs() ) ;
User user = JSONObject.parseObject(JSONObject.toJSONString(args1.get(0)), User.class);
System.out.println("參數!"+user);
System.out.println(user.getName());
if(user.getName().equals("dd")) {
throw new CMSException("1","攔截") ;
}
}
/**
* 獲取目標主機的ip
* @param request
* @return
*/
private String getRemoteHost(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
}
1.3:攔截的數據
2:限制接口的調用次數,防止重複提交
實現思路:單一的直接通過token限制某個用戶的接口調用次數是有問題,可以通過自定義註解去指定需要限制的接口
2.1: 自定義註解類
package kainian.wu.demoweb.advice;
import java.lang.annotation.*;
/**
* * * GOOK LUCK * *
*
* @Author by wukainian,
* @Date on 2019/8/28.
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NoRepeatSubmit {
String notes();
String vaue();
}
2.2:限制含有該註解的接口調用次數
/**
*
*/
@RestController
@RequestMapping(value = "user")
@Api(value = "DemoController",tags = "用戶控制類響應結果")
@SuppressWarnings("unchecked")
public class UserController {
Logger logger = LoggerFactory.getLogger( UserService.class );
@Autowired
private UserService userService;
/**
* 查詢用戶列表
* @return
*/
@NoRepeatSubmit(notes = "REPEAT",vaue = "防止重複提交")
@ApiOperation(value = "查詢用戶列表", notes = "List類型")
@PostMapping(value = "/all")
@ResponseBody
public ClientResponse list(@Validated @RequestBody User user) {
return ClientResponse.ok(userService.findAll( 1L ));
}
2.3:測試
@Before("pointCkeck()")
public void beforeSleep(JoinPoint joinPoint) throws CMSException {
//1:方式名稱
String methodName = joinPoint.getSignature().getName();
System.out.println("方式名"+methodName);
//2:\
String reqParam = "";
String reqParam21 = "";
String[] reqParam1 = null;
String[] reqParam2 = null;
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method targetMethod = methodSignature.getMethod();
Annotation[] annotations = targetMethod.getAnnotations();
for (Annotation annotation : annotations) {
//此處可以改成自定義的註解
if (annotation.annotationType().equals(NoRepeatSubmit.class)) {
NoRepeatSubmit apiOperation4 = (NoRepeatSubmit) annotation;
reqParam21 = apiOperation4.vaue();
continue;
}
if (annotation.annotationType().equals(ApiOperation.class)) {
ApiOperation apiOperation = (ApiOperation) annotation;
reqParam = apiOperation.value();
continue;
}
if (annotation.annotationType().equals(GetMapping.class)) {
GetMapping getMapping = (GetMapping) annotation;
reqParam1 = getMapping.value();
continue;
}
if (annotation.annotationType().equals(PostMapping.class)) {
PostMapping getMapping = (PostMapping) annotation;
reqParam2 = getMapping.value();
continue;
}
}
if(null != reqParam21) {
//具體可以通過時間來限制每個接口的調用
throw new CMSException("1","攔截") ;
}
System.out.println("攔截的註解的參數:");
System.out.println("方法名稱"+reqParam);
//3:接口路徑
System.out.println("方法路徑"+JSON.toJSON(reqParam1));
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 當前IP地址
String ipAddr = getRemoteHost(request);
System.out.println("IP地址"+ipAddr);
String url = request.getRequestURL().toString();
log.info("請求URL{}:",url);
//4;參數
List<Object> args1 = Arrays.asList( joinPoint.getArgs() ) ;
User user = JSONObject.parseObject(JSONObject.toJSONString(args1.get(0)), User.class);
System.out.println("參數!"+user);
System.out.println(user.getName());
if(user.getName().equals("dd")) {
throw new CMSException("1","攔截") ;
}
}
2.4:測試結果