spring boot mvc 实现 url 实现参数自动解码(decode)

最近做项目中,发现后端spring boot 不能将http get请求中的转义字符进行解码,具体的方法如下:

/**
 * 查询车辆管理列表
 */
@SaCheckPermission("biz:carInfo:list")
@GetMapping("/list")
public TableDataInfo<CarInfoVo> list(CarInfoBo bo, PageQuery pageQuery) {
    return carInfoService.queryPageList(bo, pageQuery);
}

经过查找方法,主要有以下方法可以实现

  1. 添加Converter配置
/**
 * 通用配置
 *
 * @author rstc
 */
@AutoConfiguration
public class ResourcesConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
        // 全局日期格式转换配置
        registry.addConverter(String.class, Date.class, source -> {
            if (StringUtils.isBlank(source)) {
                return null;
            }
            return DateUtil.parse(source);
        });
        // 自动解码所有String类型的请求参数
        registry.addConverter(String.class, String.class, source -> {
            try {
                return URLDecoder.decode(source, StandardCharsets.UTF_8);
            } catch (Exception e) {
                return source; // 解码失败返回原值
            }
        });
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
    }

    /**
     * 全局异常处理器
     */
    @Bean
    public GlobalExceptionHandler globalExceptionHandler() {
        return new GlobalExceptionHandler();
    }
}

 

以上方式主要会在将参数转换为bean的时候,会调用该方法。但是这么修改会对所有的http请求都会生效,感觉不太好

2.  自定义filter

/**
 * 通用配置
 *
 * @author rstc
 */
@AutoConfiguration
public class ResourcesConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
        // 全局日期格式转换配置
        registry.addConverter(String.class, Date.class, source -> {
            if (StringUtils.isBlank(source)) {
                return null;
            }
            return DateUtil.parse(source);
        });
        // 自动解码所有String类型的请求参数
//        registry.addConverter(String.class, String.class, source -> {
//            try {
//                return URLDecoder.decode(source, StandardCharsets.UTF_8);
//            } catch (Exception e) {
//                return source; // 解码失败返回原值
//            }
//        });
    }

    @Bean
    public FilterRegistrationBean<ForceDecodeFilter> forceDecodeFilter() {
        FilterRegistrationBean<ForceDecodeFilter> bean = new FilterRegistrationBean<>();
        bean.setFilter(new ForceDecodeFilter());
        bean.addUrlPatterns("/*");
        return bean;
    }

    static class ForceDecodeFilter extends OncePerRequestFilter {
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                        FilterChain chain) throws ServletException, IOException {
            // 对GET参数和Form表单数据统一解码
            if (request.getMethod().equalsIgnoreCase("GET")) {
                request = new DecodingHttpServletRequestWrapper(request);
            }
            chain.doFilter(request, response);
        }
    }

    // 包装Request对象实现解码
    static class DecodingHttpServletRequestWrapper extends HttpServletRequestWrapper {
        public DecodingHttpServletRequestWrapper(HttpServletRequest request) {
            super(request);
        }

        @Override
        public String getParameter(String name) {
            String value = super.getParameter(name);
            try {
                return value != null ? URLDecoder.decode(value, "UTF-8") : null;
            } catch (UnsupportedEncodingException e) {
                return value;
            }
        }
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
    }

    /**
     * 全局异常处理器
     */
    @Bean
    public GlobalExceptionHandler globalExceptionHandler() {
        return new GlobalExceptionHandler();
    }
}

 

这个方法可以实现,有针对行的对Http请求进行处理,这里我们只需要处理http get的请求就行,其他的请求都不做处理

通过以上配置,就能够实现http get在spring mvc中进行自动转义效果。

Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注