开发网页游戏过程记录13-用户身份认证信息处理的拦截器

本文介绍了一种使用注解实现RESTful API方法拦截的技术,通过检查方法和类上的特定注解来决定是否对方法进行拦截,简化了配置并提供了更灵活的控制。实现了对方法级别的拦截逻辑,包括处理匿名用户请求、判断请求是否合法以及执行额外的安全检查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用户进行访问官网或者游戏需要对用户的操作进行相应的拦截,可是有时候需要对用户各个行为进行分开拦截,有的操作不必对其进行拦截。这时候容易想到的是使用MethodFilterInterceptor类来进行对各个方法进行是否拦截的操作。可是当一个应用非常复杂,这时就会在struts的配置文件配置多个excludeMethods,这样看起来就会很臃肿,一时也想不起使用什么更好的方法来进行对方法的拦截,后来发现使用注解是一个不错的选择:在某个action类的某个具体方法上写上对应的注解,根据注解的值来确定是否进行拦截。这时遇到的问题是如何检测当前请求的action方法是否有此注解,并且注解也有在类上也有在方法上的,这时又是如何区分呢,参考了一些资料,写成了这样:

//RestMethod这个注解是注解在方法上private boolean isRestMethod(Method actionMethod) { boolean annotationPresent = actionMethod.isAnnotationPresent(RestMethod.class);//检查某个方法是否是注解方法,RestMethod是自己定义的注解类 if (annotationPresent) { RestMethod restMethod = actionMethod.getAnnotation(RestMethod.class);//如果是注解的方法,则得到注解类的实例 return restMethod.intercept();//调用注解实例的intercept方法 } return false; } //AnonymousRedirect这个注解是注解在方法和类上的 private boolean isAnonymousRedirect(Class<?> actionClass, Method actionMethod) { Class<Redirection> rclass = Redirection.class;//Redirection是自己定义的注解类 boolean annotationPresent = actionMethod.isAnnotationPresent(rclass); Redirection redirection = null; if (annotationPresent) { redirection = actionMethod.getAnnotation(rclass);//获得方法上的注解类实例 return redirection.value(); } else { annotationPresent = actionClass.isAnnotationPresent(rclass); if (annotationPresent) { redirection = actionClass.getAnnotation(rclass);//获得类上的注解类实例 return redirection.value(); } else { return false; } } }这样的话我们就可以写一个继承了MethodFilterInterceptor这个类的拦截类。在这个类的doIntercept方法里实现具体的拦截过程并转发视图,具体代码如下:

protected String doIntercept(ActionInvocation invocation) throws Exception { final Object action = invocation.getAction();//得到拦截起拦截的action类 ActionContext context = invocation.getInvocationContext(); HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST); // HttpServletResponse response = (HttpServletResponse) // context.get(HTTP_RESPONSE); String clientIp = ServletUtils.getClientIp(request); Class<?> actionClass = action.getClass(); Method currentMethod = null; try { currentMethod = getActionMethod(actionClass, invocation.getProxy().getMethod()); } catch (NoSuchMethodException ex) { return GLOBAL_VIEW_404; } String format = ServletUtils.getParameter(request, PARAM_FORMAT, AjaxResult.FORMAT_JSON); SessionBean session = SessionManager.getConcurrentSession(); Authentication authToken = session == null ? Authentication.ANONYMOUS : session.getAuthToken(); if (authToken.isAnonymous()) {//如果是匿名用户则使用action类注解来进行相应的拦截 if (isAnonymousRedirect(actionClass, currentMethod)) { if (action instanceof IndexAction) { return ConstantConfig.GLOBAL_VIEW_LOGIN; } return ConstantConfig.GLOBAL_VIEW_LOGIN; } if (isRestMethod(currentMethod)) { String referer = request.getHeader("Referer"); if (isIllegalReferer(referer)) { StringBuffer buf = new StringBuffer("Illegal request referer: "); buf.append(referer).append(" @").append(actionClass.getName()).append("#"); buf.append(currentMethod.getName()).append(" request client IP:").append(clientIp); LOGGER.error(buf.toString()); if (AjaxResult.FORMAT_JSON.equalsIgnoreCase(format)) { String jsonResult = AjaxResult.getErrorJson("Illegal Request Referer."); request.setAttribute(AjaxResult.RESULT_KEY, jsonResult); return GLOBAL_VIEW_JSON; } else { return GLOBAL_VIEW_ERROR; } } } } if (action instanceof AuthenticationAware) { AuthenticationAware authAware = (AuthenticationAware) action; authAware.setAuthentication(session == null ? Authentication.ANONYMOUS : session.getAuthToken()); } return invocation.invoke(); } //获得action中定义的方法 private Method getActionMethod(Class<?> actionClass, String methodName) throws NoSuchMethodException { Method method = null; try { method = actionClass.getMethod(methodName, new Class[0]); } catch (NoSuchMethodException ex) { // 未打到指定的方法,试试 找父类方法。 Class<?> superClass = actionClass.getSuperclass(); try { method = superClass.getMethod(methodName, new Class[0]); } catch (NoSuchMethodException nsme) { throw nsme; } } return method; } /** 访问方是否为非法来源。 */ private boolean isIllegalReferer(String referer) { return false; }然后将该类配置在struts配置文件当中,这样就可以实现对具体方法进行具体拦截的功能了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值