Open seaswalker opened 3 years ago
微信等回调有的使用post form data的请求形式,并且参数字段为snake格式,而不是Java常用的camel case。
首先定义一个filter:
public class SnakeToCamelCaseFilter extends OncePerRequestFilter { @Override protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain ) throws ServletException, IOException { final Map<String, String[]> formattedParams = new ConcurrentHashMap<>(); for (String param : request.getParameterMap().keySet()) { String formattedParam = snakeToCamel(param); formattedParams.put(formattedParam, request.getParameterValues(param)); } filterChain.doFilter( new HttpServletRequestWrapper(request) { @Override public String getParameter(String name) { return formattedParams.containsKey(name) ? formattedParams.get(name)[0] : null; } @Override public Enumeration<String> getParameterNames() { return Collections.enumeration(formattedParams.keySet()); } @Override public String[] getParameterValues(String name) { return formattedParams.get(name); } @Override public Map<String, String[]> getParameterMap() { return formattedParams; } }, response ); } private static String snakeToCamel(final String snake) { if (StringUtils.isEmpty(snake)) { return snake; } final StringBuilder sb = new StringBuilder(snake.length() + snake.length()); for (int i = 0; i < snake.length(); i++) { final char c = snake.charAt(i); if (c == '_') { sb.append( (i + 1) < snake.length() ? Character.toUpperCase(snake.charAt(++i)) : "" ); } else { sb.append(c); } } return sb.toString(); } }
之后在Spring中配置此filter:
@Bean public FilterRegistrationBean<SnakeToCamelCaseFilter> snakeToCamelCaseFilter() { FilterRegistrationBean<SnakeToCamelCaseFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new SnakeToCamelCaseFilter()); registrationBean.addUrlPatterns("/api/v1/firstName"); registrationBean.setOrder(1); return registrationBean; }
而后可以定义controller:
@PostMapping(value = "/firstName", consumes = MediaType.APPLICATION_FORM_URLENCODED) public String firstName(@Valid @ModelAttribute Domain domain) { return "success"; } @Data public class Domain { private String firstName; }
这样以下面这样的格式请求,firstName也会被赋上值,并且参数校验同样起作用:
POST http://localhost:8080/firstname Content-Type: application/x-www-form-urlencoded first_name=skywalker
snake转为camel参考自: CamelCase と snake_case を相互変換する 原代码当请求参数名并不是snake而是camel时,如firstName,会转换为firstname,Google guava也有同样的问题。
Spring相关issue: Add @FormAttribute attributes to customize x-www-form-urlencoded [SPR-13433]
@ModelAttribute注解非必须
微信等回调有的使用post form data的请求形式,并且参数字段为snake格式,而不是Java常用的camel case。
首先定义一个filter:
之后在Spring中配置此filter:
而后可以定义controller:
这样以下面这样的格式请求,firstName也会被赋上值,并且参数校验同样起作用:
snake转为camel参考自: CamelCase と snake_case を相互変換する 原代码当请求参数名并不是snake而是camel时,如firstName,会转换为firstname,Google guava也有同样的问题。
Spring相关issue: Add @FormAttribute attributes to customize x-www-form-urlencoded [SPR-13433]