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注解的值都是为空的。下面运行代码。
测试效果如下图
效果图
可以发现我们的映射已经建立,测试成功!
网友评论