微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

弹簧数据使用蛇形参数排序

如何解决弹簧数据使用蛇形参数排序

你能告诉我如何以snake_case格式将排序参数传递给rest控制器吗?

我的实体类

@Entity
public class MyEntity extends BaseEntity{

  @Id
  private Long id;

  @Column
  private Long parentId;
}

控制器方法

@GetMapping("list")
    List<MyEntity> getEntityList(
           @PageableDefault(sort = {"id"},direction = Sort.Direction.DESC) Pageable pageable);
}

在请求中我想使用 ?sort=parent_id

我已经创建了 Jackson2ObjectMapperBuilder 并且它构建了正确的 snake_case json

但是 spring 给我发送了 Caused by: org.springframework.data.mapping.PropertyReferenceException: No property parent found for type MyEntity! Did you mean 'parentId'? 我认为这是关于解析的问题,因为 spring 在 '_' 符号之后剪切了所有内容

我试过了:

  • @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
  • @Column(name = "parent_id") @JsonProperty("parent_id")
  • @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

解决方法

我解决了这个问题。为了正确使用snake_case 参数值,我们需要创建自定义的OncePerRequestFilter。此过滤器在传递给控制器​​之前准备参数。

用户 nullptr 使用相同的方式 here。顺便说一句,使用过滤器您可以准备任何其他参数/​​值,但此解决方案可能会产生错误。所有请求都将通过过滤器。

@Configuration
public class SnakeCaseFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request,HttpServletResponse response,FilterChain filterChain)
            throws ServletException,IOException {

        final Map<String,String[]> formattedParams = new ConcurrentHashMap<>();

        //Convert values for each parameter
        for (String param : request.getParameterMap().keySet()) {
            String[] values = request.getParameterValues(param);

            String formattedParam = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL,param);

        formattedParams.put(formattedParam,values);
        }

        filterChain.doFilter(new CustomResponseWrapper(request,formattedParams),response);

    }


    /**
     * Wrapper return new formatted parameters
     */
     class CustomResponseWrapper extends HttpServletRequestWrapper {

        /**
         * Constructs a request object wrapping the given request.
         *
         * @param request the {@link HttpServletRequest} to be wrapped.
         * @throws IllegalArgumentException if the request is null
         */

        private Map<String,String[]> params;

        public CustomResponseWrapper(HttpServletRequest request,Map<String,String[]> params) {
            super(request);
            this.params = params;
        }

        @Override
        public Map<String,String[]> getParameterMap() {
            return params;
        }

        @Override
        public String[] getParameterValues(String name) {
            return params.get(name);
        }

    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。