SpringBoot开启URL通用后缀访问功能


该文章的内容是记录如同通过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;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot中,可以通过配置类WebMvcConfigurer添一个拦截器来实现MIME类型和后缀检查。 首先,创建一个自定义的拦截器类,例如MyInterceptor: ```java public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String requestURI = request.getRequestURI(); String extension = StringUtils.getFilenameExtension(requestURI); String mimeType = new Tika().detect(requestURI); if (!isValid(extension, mimeType)) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid file type"); return false; } return true; } private boolean isValid(String extension, String mimeType) { // check if extension and MIME type are valid return true; } } ``` 然后,在配置类中注册拦截器并添拦截规则: ```java @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Autowired private MyInterceptor myInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myInterceptor).addPathPatterns("/**").excludePathPatterns("/static/**"); } } ``` 这里的拦截规则是拦截所有请求("/**"),但是排除静态资源请求("/static/**")。在拦截器中,我们使用StringUtils.getFilenameExtension方法获取请求URI的后缀,然后使用Apache Tika检测MIME类型。最后,我们根据自定义的isValid方法判断请求是否合法,如果不合法,则返回HTTP状态码400(Bad Request)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值