在SpringMVC中使用HandlerInterceptor来实现拦截器功能
2024-08-30 15:11:16
需求:我们需要在请求某些特定的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
最新文章
- AutoCAD安装失败
- Zebra_Dialog 弹出层插件
- 提取安卓手机的recovery
- ssh命令:使用密钥文件进行登陆
- C# 通过线程来控制进度条(转)--讲解多线程对界面的操作
- 【HDOJ】1448 The Treasure
- 标准C++中的string类的用法总结(转)
- iOS 集合的深复制与浅复制
- POJ 2175 Evacuation Plan (费用流,负环,消圈法,SPFA)
- servlet上传图片 服务器路径(转)
- Ubuntu安装pyenv实现多版本控制
- Java泛型之自限定类型
- Alpha冲刺! Day6 - 砍柴
- DAY1 计算机组成和操作系统
- 小程序-setData
- Docker初次使用与安装过程
- 008-ant design roadhogrc 打包
- (转)Java 中关于String的空对象(null) ,空值(empty),空格
- Hibernate关联关系(二) Cascade级联
- Alcor(安国)AU6387量产修复(u盘修复)