【问题标题】:Can Spring MVC inject Example<T> from spring-data into controller method invocation >Spring MVC 可以将来自 spring-data 的 Example<T> 注入到控制器方法调用中 >
【发布时间】:2018-02-06 09:43:23
【问题描述】:

假设我们有一个带有name 属性的User 实体和一个REST API,它提供对用户数据的查询,包括对实体字段的分页、排序和过滤。

Spring MVC 能否像使用 Pageable 一样将 spring-data 中的 Example&lt;User&gt; 注入到控制器方法调用中?

如果是这样。如何让它发挥作用?

在代码中:

为了实现GET /bike?offset=20&amp;name=Jo 请求,它返回所有名称以“Jo”开头的用户的可分页结果,我使用:

  @GetMapping
    public Page<User> all(Pageable p, User u) {
        Example<User> ex = Example.of(u, startMatcher);
        return repo.findAll(ex, p);
    }

这包含不必要的样板。

我能以某种方式实现吗:

  @GetMapping
    public Page<Bike> all(Pageable p, Example<Bike> b) {
        return repo.findAll(ex, p);
    }

自定义设置默认ExampleMatcher ?

【问题讨论】:

    标签: java spring spring-mvc spring-data


    【解决方案1】:

    我最终得到了自定义网络绑定。

    解析器

    public class FilterArgResolver implements HandlerMethodArgumentResolver {
    
        ExampleMatcher startMatcher = ExampleMatcher.matching()
                .withStringMatcher(ExampleMatcher.StringMatcher.STARTING);
    
        @Override
        public boolean supportsParameter(MethodParameter param) {
            return param.getParameterAnnotation(Filter.class) != null;
        }
    
        @Nullable
        @Override
        public Object resolveArgument(MethodParameter param,
                                      @Nullable ModelAndViewContainer mavContainer,
                                      NativeWebRequest webRequest,
                                      @Nullable WebDataBinderFactory binderFactory) throws Exception {
    
            Class clazz = param.getParameterAnnotation(Filter.class).value();
    
            Object o = clazz.getConstructor().newInstance();
    
            ServletRequestDataBinder b = (ServletRequestDataBinder) binderFactory.
                    createBinder(webRequest, o, "filter");
            b.bind((ServletRequest) webRequest.getNativeRequest());
            BindingResult r = b.getBindingResult();
            Object t = r.getTarget();
            return Example.of(t, startMatcher);
        }
    }
    

    注册

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Override
        public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
            resolvers.add(new FilterArgResolver());
        }
    
    }
    

    自定义注释

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.PARAMETER)
    public @interface Filter {
    
        Class<?> value();
    }
    

    用法

      @GetMapping
        public Page<Bike> all(Pageable p, @Filter(Bike.class) Example<Bike> ex) {
            return repo.findAll(ex, p);
        }
    

    【讨论】:

      猜你喜欢
      • 2016-12-09
      • 1970-01-01
      • 2015-09-12
      • 1970-01-01
      • 1970-01-01
      • 2014-11-06
      • 2012-12-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多