我在代码Identifiable<T>
中有一个处理标识符的特殊类。当在控制器方法中使用时,我会这样做:
@GetMapping("/user/{userId}")
public void getUser(
@PathVariable("userId") Identifiable<User> userId
) { .. }
将类定义为:
interface Identifiable<T> {
String identifier();
Class<? extends T> type();
}
此接口有多种实现方式。目前,我正在使用的是转换器:
@Component
public class StringToIdentifiableConverter implements Converter<String, Identifiable> {
@Override
public Identifiable convert(String source) {
return IdUtils.of(source, null);
}
}
第二个参数,在本例中为null
,需要User.getClass()
。当然,当使用转换器时,我无法访问此类型,因此我必须将其设置为null。
如果我,另一方面使用HandlerMethodArgumentResolver
,我实际上可以使用Reflection访问该类型; resolve
方法为我提供了MethodParameter
的实例,我可以这样做:
((ParameterizedType)(methodParameter.getGenericParameterType()))
.getActualTypeArguments()[0]
当然有必要的安全卫士。但是,如果我这样做,我将不得不使用不同的注释而不是@PathVariable
,因为弹簧内置解析器会在我的自定义解析器之前添加(https://github.com/spring-projects/spring-framework/blob/v5.0.0.RELEASE/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java#L195-L197)。这也意味着我失去了使用PathVariable
本身提供的所有解析功能。由于内置的解析器是在我的自定义解析器之前添加的,因此我甚至无法从PathVariableMethodArgumentResolver
扩展并编写自己的逻辑。
我相信有一种方法可以覆盖所有RequestMappingHandlers
或类似的东西,但是这最终只是在尝试匹配所有其他默认弹簧解析器时的一个mantainance问题。
在这种情况下,最佳解决方案是什么?