[英]Bind XMLGregorianCalendar field in Spring MVC with velocity
[英]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.