使用Spring将默认顺序按ID添加到Pageable

时间:2016-04-11 15:03:16

标签: java spring spring-mvc spring-data

我正在使用Spring Pageable数据和对象。当按照在数据库中具有相同值的字段进行排序时,更改页面会检索错误的结果。

我正在尝试使用HandlerInterceptorAdapter按ID添加默认顺序,如下所示:

我的拦截器:

public class OrderByIdWebArgumentResolver extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

        HandlerMethod hm= (HandlerMethod) handler;
        Method method = hm.getMethod();
        OrderById orderById = method.getAnnotation(OrderById.class);
        if (orderById != null) {
            for (MethodParameter parametro : hm.getMethodParameters()) {
                if (parametro.getGenericParameterType().equals(Pageable.class)) {
                    Map<String, String[]> parameters = request.getParameterMap();
                    String[] sortById = new String[2];
                    sortById[0] = "id";
                    sortById[0] = "desc";
                    parameters.put("sort", sortById);
                }

            }

        }

        return true;
    }
}

我的控制器:

@OrderById
@RequestMapping(value = "/print", method = RequestMethod.GET)
public String printMensagges(@ModelAttribute MensaggesOption messageSelector, final ModelMap model,
       @SortDefault(sort = "date", direction = Sort.Direction.DESC) @PageableDefault(value = 5) final Pageable pageable, final Principal principal) {

    //I need the pageable has order by id here or in a service method
    List<Message> messages = messageService.findAll(pageable);

    return "/index";
}

我收到此错误:

  

java.lang.IllegalStateException:JBWEB000096:没有修改   允许锁定的ParameterMap

有没有办法添加默认订单?您可以添加具有Pageable参数的服务方法吗?

3 个答案:

答案 0 :(得分:2)

您可以在@PageableDefault定义中添加排序,而不是添加单独的@SortDefault。

@PageableDefault(sort = {"name", "id"}, direction = Sort.Direction.DESC, value = 5) final Pageable pageable

答案 1 :(得分:0)

使用@PageableDefault添加排序和方向:

 public String printMensagges(@PageableDefault(size = 40, sort = "id", direction = Direction.DESC) Pageable pageable, Model model)

答案 2 :(得分:0)

这是我的解决方案(使用自定义字段名称进行其他排序)。

可分页参数的注释(用于自定义字段名称):

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface AdditionalSort {
    String value() default "id";
}

配置(此处是主要问题答案):

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        PageableHandlerMethodArgumentResolver pageResolver =
                new PageableHandlerMethodArgumentResolver(new AdditionalSortHandlerMethodArgumentResolver());
        pageResolver.setFallbackPageable(PageRequest.of(0, Integer.MAX_VALUE));
        argumentResolvers.add(pageResolver);
    }


    private static class AdditionalSortHandlerMethodArgumentResolver extends SortHandlerMethodArgumentResolver {

        private static final String DEFAULT_ADDITIONAL_SORT_FIELD = "id";

        @Override
        public Sort resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                    NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
            Sort sort = super.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
            String additionalSortField = parameter.hasParameterAnnotation(AdditionalSort.class) ?
                    parameter.getParameterAnnotation(AdditionalSort.class).value() : DEFAULT_ADDITIONAL_SORT_FIELD;
            return sort.and(Sort.by(additionalSortField));
        }

    }

}

控制器:

@GetMapping(value = "/byOrganization/{organizationId}", produces = APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<JsonItem<PageDto<EmployeeDto>>> getByOrganization(@PathVariable
                                                                                String organizationId,
                                                                        EmployeeFilter filter,
                                                                        @SortDefault(sort = CREATION_DATE, direction = DESC)
                                                                        @AdditionalSort("personId")
                                                                                Pageable pageable) {
    return ResponseEntity.ok(JsonItem.withData(employeeService.findEmployees(organizationId, filter, pageable)));
}