美文网首页
重写RequestMappingHandlerMapping,注

重写RequestMappingHandlerMapping,注

作者: chanyi | 来源:发表于2020-06-08 22:31 被阅读0次

1、说明

当使用@RequestMapping注解是时,如果@RequestMapping的值为空,spring容器则不会进行路径映射。
下面我们将通过重写RequestMappingHandlerMapping,实现@RequestMapping无值时也能进行路径映射

2、实现思路:

首先获取建立自定义的RequestMappingHandlerMapping自定义类,继承RequestMappingHandlerMapping。
重写其中的getMappingForMethod方法。利用方法的参数我们需要实现自己的业务逻辑。
主要逻辑就是:首先将注解分为类上的注解和方法上的注解,然后分别处理。处理过程中先判读注解是否为空,如果注解不为空,判断注解的value是否为空,如果为空则自定义。

3、代码

代码如下:

/**
 * @program: test
 * @description: 自定义handlerRequestMapping 
 * 主要功能实现: 当@RequestMapping的value为空时,默认使用类名或者方法名
 * @author: lilei
 * @create: 2020/06/08
 **/
public class CustomRequestMappingHandlerMapping extends RequestMappingHandlerMapping {

  /**
   * 重写对方法的映射
   */
  @Override
  protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
    RequestMappingInfo requestMappingClassInfo =null;
    RequestMappingInfo requestMappingMethodInfo =
        createRequestMappingInfo(
            //方法上的@RequestMapping
            AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class),
            getCustomMethodCondition(method),
            null,
            method);
    if (requestMappingMethodInfo != null) {
       requestMappingClassInfo =  createRequestMappingInfo(
              //类上的@RequestMapping
              AnnotatedElementUtils.findMergedAnnotation(handlerType, RequestMapping.class),
              getCustomTypeCondition(handlerType),
              handlerType,
              null);
      if (requestMappingClassInfo != null) {
        requestMappingClassInfo = requestMappingClassInfo.combine(requestMappingMethodInfo);
      }
    }
    return requestMappingClassInfo;
  }


  private RequestMappingInfo createRequestMappingInfo(RequestMapping requestMapping,
      RequestCondition<?> customCondition,Class<?> handlerType, Method method) {
    //注解的情况
    if(requestMapping==null){
      return null;
    }
    String[] patterns = resolveEmbeddedValuesInPatterns(requestMapping.value());
    StringBuilder builder = new StringBuilder();
    System.out.println("start patterns:" + Arrays.toString(patterns));
    //类上注解 value为空
    if ((handlerType!=null && method == null) && (patterns == null || patterns.length < 1)) {
      //RequestMapping的value属性为空,自定义url。
      String className = handlerType.getSimpleName();
      if (className.endsWith("Controller")) {
        className = className.substring(0, className.lastIndexOf("Controller"));
      }
      builder = builder.append("/").append(firstCaseLower(className));
    }
    //方法上注解 value为空
    if((handlerType==null && method!=null) && (patterns == null || patterns.length < 1) ){
      builder = builder.append("/").append(method.getName());
    }
    if(!"".equals(builder.toString())){
      patterns = new String[]{builder.toString()};
    }
    System.out.println("end patterns:" + Arrays.toString(patterns));
    return RequestMappingInfo
        .paths(resolveEmbeddedValuesInPatterns(patterns))
        .methods(requestMapping.method())
        .params(requestMapping.params())
        .headers(requestMapping.headers())
        .consumes(requestMapping.consumes())
        .produces(requestMapping.produces())
        .mappingName(requestMapping.name())
        .customCondition(customCondition)
        .build();

  }


  //首字母小写
  private String firstCaseLower(String s) {
    StringBuilder stringBuilder = new StringBuilder(s.substring(0, 1).toLowerCase());
    return stringBuilder.append(s.substring(1)).toString();
  }
}

4、测试:

建一个测试类:

/**
 * @program: test
 * @description: test
 * @author: lilei
 * @create: 2020/06/08
 **/
@RequestMapping
@RestController
public class Test88888 {
  @RequestMapping
  public void test77777(){
  }
}

可以看到我们的类和方法上的@RequestMapping注解的值都是为空的。下面运行代码。
测试效果如下图


效果图

可以发现我们的映射已经建立,测试成功!

相关文章

网友评论

      本文标题:重写RequestMappingHandlerMapping,注

      本文链接:https://www.haomeiwen.com/subject/ksndtktx.html