- 拦截器
- 自定义注解
- 篡改警告
一、拦截器
配置拦截器
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*"/>
<bean class="com.xmg.p2p.base.util.LoginCheckInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
-
继承
HandlerInterceptorAdapter
类- 重写
preHandle
方法:在进行访问页面前执行此方法 - 重写
postHandle
方法:在进行访问页面后执行此方法,如果没有执行完毕访问的页面,此方法不会执行 - 重写
afterCompletion
方法:在访问完页面后进行清理操作,如果没有执行完毕访问的页面,此方法仍然会执行
- 重写
-
HandlerMethod
Spring的方法处理器,其中包括了这次请求里的具体方法-
if (handler instanceof HandlerMethod) { //HandlerMethod包装了我这次请求要访问的controller里的具体方法 HandlerMethod hm = (HandlerMethod) handler;
-
进行向下转型叫hm
-
-
RequireLogin rl = hm.getMethodAnnotation(RequireLogin.class);
- 获取到当前方法上是否有注解
-
Logininfo current = UserContext.getCurrent();
- 获取是否已经登陆过了
-
if (rl != null && UserContext.getCurrent() == null)
- 如果结果为true代表访问这个接口时没有登录
-
response.sendRedirect("/login.html"); return false; //阻止继续执行
- 重定向到登录页面
-
return super.preHandle(request, response, handler); //正常的放行
- 如果结果为false代表访问这个接口时已经登录,进行放行操作!
-
扩展:获取当前请求的所有注解
- 获取当前请求的Method:
Method method = hm.getMethod();
- 获取请求的所有注解:
Annotation[] annotation = method.getAnnotations();
Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
- 获取当前请求的Method:
二、自定义注解
@Target(ElementType.METHOD) //标签贴在哪个位置上
@Retention(RetentionPolicy.RUNTIME) //保留到什么时候
public @interface RequireLogin {}
-
定义此注解在什么地方使用:
@Target(ElementType.xxx)
。- 方法的声明:
METHOD
- 类的声明:
TYPE
- 参数声明:
PARAMETER
- 字段声明(包括枚举常量):
FIELD
- 构造函数声明:
CONSTRUCTOR
- 局部变量声明:
LOCAL_VARIABLE
- 注释类型声明:
ANNOTATION_TYPE
- 包声明:
PACKAGE
- 类型参数声明:
TYPE_PARAMETER
- 类型的使用:
TYPE_USE
- 方法的声明:
-
定义保留级别:
@Retention(RetentionPolicy.xxx)
- 注解将在编译器时被抛弃:
SOURCE
- 默认在记录在类文件,运行Java虚拟机时抛弃(默认):
CLASS
- 记录在类文件中,运行Java虚拟机时保留,可以反射地读取它们:
RUNTIME
- 注解将在编译器时被抛弃:
-
定义注解的参数:参数类型 参数名()
- 一旦定义了参数,使用这个注解的时候必须赋给参数。
- 参数可以默认为空,
default ""
String value() default ""
-
获取注解上的参数
-
获取当前方法上的注解
RequireLogin rl = hm.getMethodAnnotation(RequireLogin.class);
-
获取参数
String value = rl.value();
-
三、防止恶意篡改
private String verify;
在用户账户表被创建时,就会生成一个字段(verify
),这个字段由,ID+账户可用金额+冻结金额,进行MD5的转换生成的,
public String getVerify(){
return MD5.encode((this.id+" "+this.usableAmount.hashCode()+""+this.freezedAmount.hashCode()));
}
登录时进行核对。
if (!account.getIsValidate()){ // 判断当前账户是否可以校验通过,如果不通过 进入if
throw new RuntimeException("账户"+id+"可能被恶意篡改");
}
getIsValidate()
,核对创建用户时生成的信息,和现在的信息是否匹配,
// 防止恶意篡改
public boolean getIsValidate(){
return MD5.encode((this.id+" "+this.usableAmount.hashCode()+""+this.freezedAmount.hashCode())).equals(this.verify);
}