需求:我们需要在请求某些特定的URL(URL格式为Restful格式)时添加拦截器,以实现进行权限控制。

如:/ResourcePlan/projectCode/P1503127828/PROJECT_TYPE_MSMS/2052/00018785

前台的Controller:

     @ApiOperation("获取单个项目的****信息")
@ApiImplicitParams({
@ApiImplicitParam(paramType="path",name="projectCode",dataType="String",required=true,value="项目编码"),
@ApiImplicitParam(paramType="path",name="projectType",dataType="String",required=true,value="项目类型"),
@ApiImplicitParam(paramType="path",name="cultureNo",dataType="String",required=false,defaultValue="2052",value="语言类型"),
@ApiImplicitParam(paramType="path",name="empIdUi",dataType="String",required=true,value="人员工号")
})
@ApiResponses({
@ApiResponse(code=400,message="请求参数没填好"),
@ApiResponse(code=404,message="请求路径没有或页面跳转路径不对")
})
@RequestMapping(value="/projectCode/{projectCode}/{projectType}/{cultureNo}/{empIdUi}",method= RequestMethod.GET)
@ResponseBody
//@UrlPattern(value="^/ResourcePlan/projectCode/([a-zA-z0-9]{1,})/([a-zA-z0-9]{1,})/([0-9]{1,4})/([0-9]{1,})")
public ServiceData<ResourcePlan> getResourcePlan(@PathVariable("projectCode") String projectCode,
@PathVariable("projectType") String projectType,
@PathVariable("cultureNo") String cultureNo,
@PathVariable("empIdUi") String empIdUi){
ServiceData<ResourcePlan> ret = new ServiceData<ResourcePlan>();
try {
ResourcePlan resourcePlan= rps.getResourcePlan(projectCode, projectType, cultureNo);
ret.setBo(resourcePlan);
} catch (Exception e) {
RetCode code =RetCode.BusinessError;
ret.setCode(code,e.getMessage());
}
return ret;
}

为了拦截这个URL,将拦截器注册到拦截器配置器,代码如下:

 1 @Configuration
2 public class UrlInterceptConfig extends WebMvcConfigurerAdapter {
3
4 @Override
5 public void addInterceptors(InterceptorRegistry registry) {
6 System.out.println("进入拦截器配置器");
7
8 //注册拦截器
9 InterceptorRegistration iRegistration=registry.addInterceptor(new ProjectAuthInterceptor());
10 iRegistration.addPathPatterns("/ResourcePlan/projectCode/**");
11 //super.addInterceptors(registry);
12 }
13 }

拦截到这个格式的URL以后,我们实现了以下的拦截器来做业务控制:

 public class ProjectAuthInterceptor implements HandlerInterceptor {

     @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception { } @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub } @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception { } }

我们需要在拦截器中解析出Restful格式的URL中相应的参数,preHandle的第3个参数指的是拦截的那相方法的相应信息,可以得到这个方法的签名,但得不到相应传递进来的参数值。

因而,要想得到相应的参数值,我们必须得另想办法。

我实现的思路是

1、使用正则表达式来匹配URL,为了项目的更易维护,我决定把正则表达式通过注解的方式放在Controller的上面,就如第一段代码注释掉的那一行。

注解如下:

 @Retention(RetentionPolicy.RUNTIME)
@Target({ java.lang.annotation.ElementType.METHOD })
public @interface UrlPattern { String value(); }

正则如下

@UrlPattern(value="^/ResourcePlan/projectCode/([a-zA-z0-9]{1,})/([a-zA-z0-9]{1,})/([0-9]{1,4})/([0-9]{1,})")

2、通过正则将所有的参数都匹配出来,然后进行业务逻辑判断,下面是实现preHandle的代码

     @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("开始校验****权限");

//根据正则从URL中提取参数值
HandlerMethod method= ((HandlerMethod)handler);
UrlPattern urlPatternAnno= method.getMethodAnnotation(UrlPattern.class);
String urlPattern=urlPatternAnno.value();
ApplicationConfig app= (ApplicationConfig)SpringContextUtil.getBean("applicationConfig");
String urlRequest=request.getRequestURI();
if(request.getRequestURI().indexOf(app.getContext())>) {
urlRequest=request.getRequestURI().substring(app.getContext().length());
}
Matcher mathcer = Pattern.compile(urlPattern).matcher(urlRequest);
List<String> paraValue=new ArrayList<String>();
if (mathcer.find()) {
for (int i = ; i <= mathcer.groupCount(); i++) {
paraValue.add(mathcer.group(i));
}
}

//获取参数名称
MethodParameter[] methodParameters= method.getMethodParameters();
if(paraValue.size()!=methodParameters.length) {
throw new Exception("参数个数不匹配");
} //整理参数名&参数值的键值对
Dictionary<String, String> params=new Hashtable<>() ;
for (int i = ; i < methodParameters.length; i++) {
params.put(methodParameters[i].getParameterName(), paraValue.get(i));
}

//业务上校验业务逻辑
String projectCode=params.get("projectCode");
String projectType=params.get("projectType");
String empIdUi=params.get("empIdUi");
AuthService authService= (AuthService)SpringContextUtil.getBean("authService");
boolean hasRight= authService.checkAuth(projectCode, projectType, empIdUi);
if(!hasRight) {
throw new Exception("没有*****的权限!");
}
return hasRight;
}

这里还需要在Controller上配置注解,其实更简单的方法是直接分析@RequestMapping这个注解,这样就不用配置自定义注解了,而且也不用编写正则表达式了,感兴趣的同学可以自己尝试下。

参考文档

http://blog.csdn.net/linzhiqiang0316/article/details/52671709  //实现了postHandle

http://blog.csdn.net/Jalon2015/article/details/71423974

最新文章

  1. AutoCAD安装失败
  2. Zebra_Dialog 弹出层插件
  3. 提取安卓手机的recovery
  4. ssh命令:使用密钥文件进行登陆
  5. C# 通过线程来控制进度条(转)--讲解多线程对界面的操作
  6. 【HDOJ】1448 The Treasure
  7. 标准C++中的string类的用法总结(转)
  8. iOS 集合的深复制与浅复制
  9. POJ 2175 Evacuation Plan (费用流,负环,消圈法,SPFA)
  10. servlet上传图片 服务器路径(转)
  11. Ubuntu安装pyenv实现多版本控制
  12. Java泛型之自限定类型
  13. Alpha冲刺! Day6 - 砍柴
  14. DAY1 计算机组成和操作系统
  15. 小程序-setData
  16. Docker初次使用与安装过程
  17. 008-ant design roadhogrc 打包
  18. (转)Java 中关于String的空对象(null) ,空值(empty),空格
  19. Hibernate关联关系(二) Cascade级联
  20. Alcor(安国)AU6387量产修复(u盘修复)

热门文章

  1. 去除git版本控制
  2. MySQL8的注意点
  3. Spark ML逻辑回归
  4. Jquery获取当前页面中的复选框选中的内容
  5. Python实例---模拟微信网页登录(day5)
  6. CentOS7安装搭建.Net Core 2.0环境-详细步骤
  7. Activity声明周期2
  8. D - Milking Time 动态规划
  9. Robberies HDU - 2955
  10. mascara-2(MetaMask/mascara本地实现)-连接线上钱包