该文章的内容是记录如同通过URL后缀名返回到指定API。
假设已定义API /test/get。想要通过/test/get.json 或者 /test/get.jsonp来访问到/test/get。可以使用以下方法来实现:
通用方法:过滤器
由于过滤器在JavaWeb中的执行时机比较早。所以用Filter过滤器来实现比较简单粗暴。
@Component
public class ExtensionFilter implements Filter {
public static final String[] extentsions = {
".json", ".jsonp"
};
private RequestMappingHandlerMapping requestMappingHandlerMapping;
private AntPathMatcher antPathMatcher = new AntPathMatcher();
public ExtensionFilter(@Qualifier("requestMappingHandlerMapping") RequestMappingHandlerMapping requestMappingHandlerMapping) {
this.requestMappingHandlerMapping = requestMappingHandlerMapping;
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
if (servletRequest instanceof HttpServletRequest) {
String requestURI = ((HttpServletRequest) servletRequest).getRequestURI();
// 对存在的API进行全匹配,未匹配再进行后缀处理
if (matcherUrl(requestURI)) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
for (String extentsion : extentsions) {
if (requestURI.endsWith(extentsion)) {
String path = requestURI.substring(0, requestURI.length() - extentsion.length());
servletRequest.getRequestDispatcher(path).forward(servletRequest, servletResponse);
return;
}
}
}
filterChain.doFilter(servletRequest, servletResponse);
}
private boolean matcherUrl(String url) {
for (RequestMappingInfo requestMappingInfo : requestMappingHandlerMapping.getHandlerMethods().keySet()) {
for (String s : Optional.ofNullable(requestMappingInfo.getPatternValues()).orElse(new HashSet<>())) {
if (antPathMatcher.match(s, url)) {
return true;
}
}
}
return false;
}
}
SpringMVC 5.2.4以下版本
使用MVC Config配置来实现
@Component
public class MvcConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(true);
configurer.setUseTrailingSlashMatch(true);
}
}
SpringMVC 5.2.4以上版本
自定义 RequestMappingHandlerMapping
TODO 暂时没法做到限制后缀类型
@Component
public class SuffixRequestMappingHandlerMapping extends RequestMappingHandlerMapping implements Ordered {
public SuffixRequestMappingHandlerMapping() {
// 该方法也是被弃用的,后续可能需要自定义匹配规则。
setUseSuffixPatternMatch(true);
}
@Override
public int getOrder() {
// 这里很重要。
return super.getOrder() - 1;
}
}