Spring Boot Get请求参数为下划线式

问题抛出

@GetMapping的方法直接以对象为参数,只识别URL中为驼峰式的参数,不识别下划线式参数。如

下划线式:http://127.0.0.1:8080/order/list?order_no=123456,不能识别参数orderNo
驼峰式:http://127.0.0.1:8080/order/list?orderNo=123456,可识别参数orderNo

注:POST方法无此问题

@GetMapping("list")
public Result<OrderListQueryResponse> queryOrderList(OrderListQueryRequest request) {

}
@Data
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class OrderListQueryRequest {

    @JsonProperty(value = "order_no")
    private String orderNo;

    @JsonProperty(value = "begin_time")
    private String beginTime;

    @JsonProperty(value = "end_time")
    private String endTime;

    @JsonProperty(value = "order_status")
    private String orderStatus;

    @JsonProperty(value = "page_size")
    private Integer pageSize;

    @JsonProperty(value = "page_index")
    private Long pageIndex;

    private Long offset;
}

解决方案

@RequestParam

public Result<PayOrderListQueryResponse> queryPaymentOrderList(
            @RequestParam("order_no") String orderNo
            @RequestParam("begin_time") String beginTime
            @RequestParam("end_time") String endTime
            @RequestParam("order_status") String orderStatus
            @RequestParam("page_size") String pageSize
            @RequestParam("pageIndex") String pageIndex) {

}
@Autowired
private ObjectMapper objectMapper;

@GetMapping("list")
public Result<OrderListQueryResponse> queryOrderList(@RequestParam Map<String, String> params) {
    OrderListQueryRequest request = objectMapper.convertValue(params, OrderListQueryRequest.class);

}

HandlerMethodArgumentResolver

参考:https://stackoverflow.com/questions/55203735/spring-boot-deserialization-snake-case-to-camel-case-fails-cant-deserialize-s

I created an Annotation to filter which type I wanna handle:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface QueryStringArgResolver {
}

Then created the resolver:

@Slf4j
@Component
public class QueryStringArgumentResolver implements HandlerMethodArgumentResolver {

    @Autowired
    private ObjectMapper mapper;

    @Override
    public boolean supportsParameter(final MethodParameter methodParameter) {
        return methodParameter.getParameterAnnotation(QueryStringArgResolver.class) != null;
    }

    @Override
    public Object resolveArgument(final MethodParameter methodParameter,
                                  final ModelAndViewContainer modelAndViewContainer,
                                  final NativeWebRequest nativeWebRequest,
                                  final WebDataBinderFactory webDataBinderFactory) throws Exception {

        final HttpServletRequest request = (HttpServletRequest) nativeWebRequest.getNativeRequest();
        final String json = qs2json(request.getQueryString());
        log.debug("json: {}", json);
        final Object a = mapper.readValue(json, methodParameter.getParameterType());

        return a;
    }

    private String qs2json(String qs) {
        log.debug("qs: {}", qs);
        if (StringUtils.isBlank(qs)) return "{}";
        try {
            Map<String, String> map = new HashMap<>();
            String[] queryStrings = URLDecoder.decode(qs, "UTF-8").split("&");
            String queryString;
            for (int i = 0; i < queryStrings.length; i++) {
                queryString = queryStrings[i];
                if (StringUtils.isNotBlank(queryString)) {
                    String[] kv = queryString.split("=");
                    if (kv.length == 2) {
                        map.put(kv[0], kv[1]);
                    }
                }
            }
            return JSON.toJSONString(map);
        } catch (Exception e) {
            log.warn("QueryStringArgumentResolver.qs2json exception: ", e);
            return "{}";
        }
    }

}

BTW, don't forget to register your resolver in this way to be able to inject beans:

@Configuration
public class ArgumentResolverConfig implements WebMvcConfigurer {
    @Autowired
    private QueryStringArgumentResolver argumentResolver;

    @Override
    public void addArgumentResolvers(
            final List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(argumentResolver);
    }
}

Usage:

@GetMapping("list")
public Result<OrderListQueryResponse> queryOrderList(@QueryStringArgResolver OrderListQueryRequest request) {

}

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/03/11/spring-boot-get-request-parameter-is-underlined/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Spring Boot Get请求参数为下划线式
问题抛出 @GetMapping的方法直接以对象为参数,只识别URL中为驼峰式的参数,不识别下划线式参数。如 下划线式:http://127.0.0.1:8080/order/list?order_no=12……
<<上一篇
下一篇>>
文章目录
关闭
目 录