需求:我们需要在请求某些特定的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

在SpringMVC中使用HandlerInterceptor来实现拦截器功能的更多相关文章

  1. SSM框架之SpringMVC(6)异常处理及拦截器

    SpringMVC(6)异常处理及拦截器 1.异常处理 1.1.异常处理的思路 ​ 系统中异常包括两类:预期异常和运行时异常 RuntimeException,前者通过捕获异常从而获取异常信息,后者主 ...

  2. SpringBoot中过滤器、监听器以及拦截器

    属于javax.servlet所提供的Api 拦截器原理 简单来讲是通过动态代理实现,被访问的目标方法通过代理类(方法)来执行,这样我们就可以在真正要执行的方法执行前.后做一些处理: 通过拦截器这种方 ...

  3. SpringMVC源码情操陶冶-InterceptorsBeanDefinitionParser拦截器解析器

    解析mvc:interceptors节点 观察下InterceptorsBeanDefinitionParser的源码备注 /** * {@link org.springframework.beans ...

  4. SpringMVC初写(五)拦截器

    在系统开发过程中,拦截器的使用可以使我们实现一些需求.如:登录认证,权限管理等,拦截器的工作核心就是将一些工作流程进行统一处理 拦截器和过滤器的区别: 过滤器过滤的是请求路径,拦截器拦截的各层方法的映 ...

  5. 【SpringMVC配置失效】Springboot2.x拦截器配置不无生效

    一.环境 maven springboot版本2.x <parent> <groupId>org.springframework.boot</groupId> &l ...

  6. SpringMVC归纳-2(Session会话、拦截器)

    要点: 1.HttpSession:一个session的建立是从一个用户向服务器发第一个请求开始,而以用户显式结束或session超时为结束,借助session能在一定时间内记录用户状态. 2.Mod ...

  7. springMVC整理04--文件上传 & 拦截器 & 异常处理

    1.  文件上传 SpringMVC 的文件上传非常简便,首先导入文件上传依赖的 jar: <!-- 文件上传所依赖的 jar 包 --> <dependency> <g ...

  8. Java 中的过滤器Filter 和拦截器 Interceptor

    1.先说拦截器 Interceptor 本项目以springboot为例: 新建 InterceptorConfig package com.opendev.mystudy.MyInterceptor ...

  9. java中过滤器、监听器、拦截器的区别

    1.过滤器:所谓过滤器顾名思义是用来过滤的,在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的actio ...

随机推荐

  1. 三. Redis 主从复制

    特点 1. Master可以拥有多个Slave 2. 多个Slave除可以连接一个Master外,还可以连接多个Salve(避免Master挂掉不能同步,当Master挂掉,其中一个Slave会立即变 ...

  2. Fiddler抓包使用教程-Https

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/72956016 本文出自[赵彦军的博客] 开启 Https 抓包 Fiddler 默 ...

  3. Nodejs 安装 on centos7

    本文演示如何在CentOS7上安装Nodejs. 1 准备工作 1.1 浏览器访问安装包下载地址: https://nodejs.org/dist/ 找到需要安装的版本,以8.11.3版本为例,地址为 ...

  4. weblogic系列漏洞整理 -- 4. weblogic XMLDecoder 反序列化漏洞(CVE-2017-10271、CVE-2017-3506)

    目录 四. weblogic XMLDecoder 反序列化漏洞(CVE-2017-10271) 0. 漏洞分析 1. 利用过程 2. 修复建议 一.weblogic安装 http://www.cnb ...

  5. XP环境下C# 调用Pocess.start()时提示文件找不到的错误解决办法

    错误提示如下: System.ComponentModel.Win32Exception (0x80004005): 系统找不到指定的文件. 在 System.Diagnostics.Process. ...

  6. 洗礼灵魂,修炼python(19)--文件I/O操作,linecache,fileinput模块

    文件I/O操作 1.什么是文件I/O操作 首先I/O(input/output),即输入/输出端口,然后文件,大家应该都是是什么,一个数据,一个txt或者html文档就是一个文件.文件操作就是对文件进 ...

  7. CentOS7:搭建配置SVN服务器

    1. 安装 CentOS通过yum安装subversion. $ sudo yum install subversion subversion安装在/bin目录: $ which svnserve / ...

  8. Spring系列(1)--IOC 和 DI

    IOC 和 DI IOC 原理 xml 配置文件配置 bean dom4j 读取配置文件 工厂设计模式 反射机制创建对象 applicationContext.xml 配置文件,该配置文件名可自定义: ...

  9. web页面中快速找到html对应元素两种方法

    一.第一种方法(通过先进入开发模式然后再去选择网页元素) 1.打开IE.Chrome.FireFox等,按 F12 键进入开发模式 2.在打开的控制窗口左上角有个  箭头 按钮,点击它之后,此时将鼠标 ...

  10. VS Code 快捷键使用小技巧

    相关文档 官方文档(英文版):Documentation for Visual Studio Code 中文文档(未完成):GitHub - jeasonstudio/CN-VScode-Docs: ...