zoukankan      html  css  js  c++  java
  • 在SpringMVC中使用HandlerInterceptor来实现拦截器功能

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

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

    前台的Controller:

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

    为了拦截这个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以后,我们实现了以下的拦截器来做业务控制:

     1 public class ProjectAuthInterceptor implements HandlerInterceptor {
     2 
     3     @Override
     4     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
     5             throws Exception {
     6          
     7     }
     8 
     9     @Override
    10     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
    11             ModelAndView modelAndView) throws Exception {
    12         // TODO Auto-generated method stub
    13         
    14     }
    15 
    16     @Override
    17     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    18             throws Exception {
    19         
    20         
    21     }
    22     
    23 }

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

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

    我实现的思路是

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

        注解如下:    

    1 @Retention(RetentionPolicy.RUNTIME)
    2 @Target({ java.lang.annotation.ElementType.METHOD })
    3 public @interface UrlPattern {
    4 
    5     String value();
    6     
    7 }

       正则如下

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

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

     1     @Override
     2     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
     3             throws Exception {
     4           System.out.println("开始校验****权限");
     5           
    //根据正则从URL中提取参数值 6 HandlerMethod method= ((HandlerMethod)handler); 7 UrlPattern urlPatternAnno= method.getMethodAnnotation(UrlPattern.class); 8 String urlPattern=urlPatternAnno.value(); 9 ApplicationConfig app= (ApplicationConfig)SpringContextUtil.getBean("applicationConfig"); 10 String urlRequest=request.getRequestURI(); 11 if(request.getRequestURI().indexOf(app.getContext())>0) { 12 urlRequest=request.getRequestURI().substring(app.getContext().length()); 13 } 14 Matcher mathcer = Pattern.compile(urlPattern).matcher(urlRequest); 15 List<String> paraValue=new ArrayList<String>(); 16 if (mathcer.find()) { 17 for (int i = 1; i <= mathcer.groupCount(); i++) { 18 paraValue.add(mathcer.group(i)); 19 } 20 } 21
    //获取参数名称 22 MethodParameter[] methodParameters= method.getMethodParameters(); 23 if(paraValue.size()!=methodParameters.length) { 24 throw new Exception("参数个数不匹配"); 25 }

    //整理参数名&参数值的键值对
    26 Dictionary<String, String> params=new Hashtable<>() ; 27 for (int i = 0; i < methodParameters.length; i++) { 28 params.put(methodParameters[i].getParameterName(), paraValue.get(i)); 29 } 30

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

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

     

    参考文档

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

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

  • 相关阅读:
    微信公众号开发的经验与坑
    微信公众号开发经验总结
    微信H5中禁止分享好友及分享到朋友圈的方法
    js 实现纯前端将数据导出excel两种方式,亲测有效
    JavaScript数组的一些方法、数学对象、定时器
    几种动态轨迹可视化效果实现方案-echarts、mapv、deck.gl
    前端大牛的博客收集
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/gudi/p/7889270.html
Copyright © 2011-2022 走看看