繁体   English   中英

Spring MVC在类型字段上绑定

[英]Spring MVC bind on a typed field

我有一个像这样的Spring MVC控制器:

    @RequestMapping(value = "/search", method = RequestMethod.GET)
    @ResponseBody
    public Object grid(Search<MyFilter> search){
      ...
    }

我的搜索对象类似于:

public class Search<F extends Filter> {
    private int offset;
    private int size;
    private F filter;

    //... getters/ setters
}

筛选器只是一个接口。 MyFilter是具有一些字段(如name, title等)的Filter的实现。

我正在使用以下命令对此控制器进行HTTP GET:/ /search?offset=0&size=10&filter.name=john

但是spring不能实例化MyFilter。 我试图使Filter成为一个普通的空类,并让MyFilter进行扩展,但是也不可能。

是否可以弹跳以实例化正确的过滤器然后绑定值?

[TL; DR]不,Spring不会从参数化类型实例化MyFilter

请求到达时,将实例化Search对象。 问题在于,在运行时,有关类型参数化的信息将被删除并转换为最通用的类​​型。 我的意思是,在运行时,您的Search对象实际上将如下所示:

class Search {

    /*
     * F is replaced by Filter since it is the most general type 
     * for <F extends Filter> parametrization. 
     * This will be the only Search class representation that compiler generates.
     */
    private Filter filter;

    //Rest of class body omitted
}

这就是泛型的工作方式。 Sicne Filter是对象映射器不知道应如何解决的接口。 您可以指导对象映射器如何基于额外的类型参数将Filter解析为特定的类(我相信这种情况在这里得到了回答)。 但是我不认为将其与泛型混合使用是个好主意。 它将导致复杂而混乱的代码。

您显然依赖于MyFilter实现,因此可以使用@DeezCashews建议中的方法。 或者您可以想到更灵活的解决方案。 如果所有的过滤器只是字段名称和所需值的容器,则可以执行以下操作:

public class Search {
    private int offset;
    private int size;
    private List<FieldPredicateTuple> filters;

    //getters and setters omitted
}

public class FieldPredicateTuple {
    String field;
    String value;

    //getters and setters omitted
}

然后调用端点:/ /search?offset=0&size=10&filters[0].field=name&filters[0].value=john

我不知道您要如何使用这些过滤器,所以我不知道要提出什么。 但我建议以某种方式重新设计。

我知道这可能并不是您想要的,但是如果您遇到困难,可以考虑将共享变量提取到其自己的类中,然后将两个参数而不是一个传递给您的grid方法。 Spring Data有一个类似于Pageable的类,因此也许您可以从中获得启发。 然后,您可以只传递一个带有条件的bean,另一个传递偏移量和大小的bean。 例如:

public Object grid(MyFilter f, Paged p);

public class MyFilter {
  String name;
  ...
}

public class Paged {
  int offset;
  int size;
  ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM