Java 类型化字段上的Spring MVC绑定
我有一个Spring MVC控制器,如下所示:Java 类型化字段上的Spring MVC绑定,java,spring,spring-mvc,Java,Spring,Spring Mvc,我有一个Spring MVC控制器,如下所示: @RequestMapping(value = "/search", method = RequestMethod.GET) @ResponseBody public Object grid(Search<MyFilter> search){ ... } @RequestMapping(value=“/search”,method=RequestMethod.GET) @应答器 公共对象网格
@RequestMapping(value = "/search", method = RequestMethod.GET)
@ResponseBody
public Object grid(Search<MyFilter> search){
...
}
@RequestMapping(value=“/search”,method=RequestMethod.GET)
@应答器
公共对象网格(搜索){
...
}
我的搜索对象类似于:
public class Search<F extends Filter> {
private int offset;
private int size;
private F filter;
//... getters/ setters
}
公共类搜索{
私有整数偏移;
私有整数大小;
专用F滤波器;
//…能手/二传手
}
过滤器只是一个接口MyFilter
是Filter
的一个实现,其中包含一些字段,如name、
title
等
我正在使用以下命令对该控制器进行HTTP访问:/search?offset=0&size=10&filter.name=john
但是spring不能实例化MyFilter。我试图将Filter
设置为一个普通的空类,并将MyFilter
扩展为一个空类,但也不可能
是否可以弹出实例化正确的过滤器,然后绑定值?
我知道这可能不是你正在寻找的,但是如果你被困了,也许考虑把共享变量提取到它自己的类中,然后将两个参数传递给你的网格方法而不是一个。SpringData有一个类似的可分页类,所以您可以从中获得灵感。然后,您可以传递一个带有条件的bean和另一个带有偏移量和大小的bean。例:public Object grid(MyFilter f, Paged p);
public class MyFilter {
String name;
...
}
public class Paged {
int offset;
int size;
...
}
[TL;DR]不,Spring不会从参数化类型实例化
MyFilter
当请求到达时,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
}
然后调用端点:/search?offset=0&size=10&filters[0]。field=name&filters[0]。value=john
我不知道你想如何使用这些过滤器,所以我不知道该建议什么。但我建议您以某种方式重新设计它。编写一个自定义解析器或为每种类型创建一个方法。@zeroflagL您能解释一下吗?回答:FieldPredicateTuple解决方案太复杂了。。。不好。但是,我需要的答案是否定的。类型实际上并没有被完全删除,它仍然可以从方法参数的泛型信息或字段的泛型信息中找到类型实现。ActFramework刚刚实现了这个特性。请参阅@GelinLuo您说过“它仍然可以从方法参数的泛型信息或字段的泛型信息中找到类型实现”-您能告诉我相关的代码吗?我认为类型实现是从通过http传入的参数中发现的,而不是从方法参数的信息中发现的。让我们假设问题中的方法采用
搜索
。尽管如此,调用endpoint/search?filter=john
是完全合法的。该方法运行(使用String
“john”作为筛选器字段的值),并在尝试将其用作Integer
@JakubCh时最终抛出运行时错误。我说的不是请求参数值,而是泛型类型实现。例如,您的class Foo{}
是一个类声明,但是void addStrFoo(Foo strFoo)
将符号T
具体化为一个真正的实现String
。参数绑定代码可在中找到。获取字段类型实现的方法请访问:@GelinLuo谢谢您的回复!我一定会看看你是怎么做到的。我没有料到泛型可以实现为正确的实现。我很高兴你指出了这一点:)
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
}