Spring数据休息排序带有下划线的字段

时间:2016-11-22 15:55:35

标签: java json spring-data spring-data-jpa spring-data-rest

我们在连接到postgres数据库的@RepositoryRestResource之上使用了一个非常简单的PagingAndSortingRepository设置。我们还配置了spring.jackson.property-naming-strategy=SNAKE_CASE来返回漂亮的json。在我们开始排序之前,一切都很好。正如我们所发现的 - 排序要求我们提供实际的类字段名称(我们当然在驼峰的情况下):

get("/thing?sort=dateCreated,desc")

当我们尝试做友好的javascript时

get("/thing?sort=date_created,desc")

它失败了,因为jpa试图用下划线拆分参数。

是否有一种简单的方法可以使路径与我们返回的json中的params格式相同?

2 个答案:

答案 0 :(得分:5)

有一个错误 - DATAREST-883。它被修复并发布。但是,由于回归(DATAREST-909),这在下一个版本中被删除了。 I asked them on Github如果他们打算再次这样做,因为过去这也让我感到困惑。我们将看到他们对此有何看法。

现在你可以:

  • 留下它
  • 使用驼峰案例属性名称
  • 解决这个问题(例如和Alan Haye's answer一起去) - 这似乎是脆弱的恕我直言,但可能会在短期内完成。

我测试过的最近的spring-boot版本中的功能状态:

  • 1.4.0(spring-data-rest 2.5.2):尚未实施 - > code
  • 1.4.1(spring-data-rest 2.5.3):作品
  • 1.4.2(spring-data-rest 2.5.5):drop

答案 1 :(得分:2)

目前还不清楚是否可以通过一些Spring Data Rest特定方式执行此操作,但是您应该能够通过标准的Servlet过滤器来处理它,如下所示:

public class SortParameterConversionFilter extends GenericFilterBean {

    // as we are extending Spring's GenericFilterBean
    // you can then *possibly* inject the RepositoryRestConfiguration
    // and use  RepositoryRestConfiguration#getSortParamName
    // to avoid hard coding
    private static final String SORT_PARAM_KEY = "sort";

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;

        if (shouldApply(request)) {
            chain.doFilter(new CollectionResourceRequestWrapper(request), res);
        } else {
            chain.doFilter(req, res);
        }
    }

    /**
     * 
     * @param request
     * @return True if this filter should be applied for this request, otherwise
     *         false.
     */
    protected boolean shouldApply(HttpServletRequest request) {
        return request.getServletPath().matches("some-pattern");
    }

    /**
     * HttpServletRequestWrapper implementation which allows us to wrap and
     * modify the incoming request.
     *
     */
    public class CollectionResourceRequestWrapper extends HttpServletRequestWrapper {

        public ResourceRequestWrapper(HttpServletRequest request) {
            super(request);
        }

        @Override
        public String getParameter(final String name) {
            if (name.equals(SORT_PARAM_KEY)) {
                String [] parts = super.getParameter(SORT_PARAM_KEY).split(",");
                StringBuilder builder = new StringBuilder();

                int index = 0;

                for (String part : parts) {
                    // using some mechanism of you choosing
                    // convert from underscore to camelCase
                    // Using the Guava library for example
                    String convertedPart = CaseFormat.LOWER_UNDERSCORE.to(
                         CaseFormat.LOWER_CAMEL, part);
                    ++index;
                    builder.append(convertedPart).append(index < parts.length ? "," : "");
                }

                return builder.toString();
            }

            return super.getParameter(name);
        }
    }
}