无法将查询字符串参数映射到我的JavaBean(使用Spring 4和Datatables)

Ber*_*ger 9 spring spring-mvc datatables javabeans

我真的很想在这里尝试将我的QueryString参数映射到我的Spring JavaBean Command对象中,到目前为止我找不到我的问题的答案.

我正在使用带有服务器端处理的 jQuery Datatables插件,以便我的数据表中的每个操作都会触发对Spring应用程序的AJAX请求.

这是Datatable插件发送到Rest服务的参数:

http://localhost:8080/relatorios/produtos-source?draw=2&columns[0][data]=nome&columns[0][name]=&columns[0][searchable]=true&columns[0][orderable]=true&columns[0][search][value]=&columns[0][search][regex]=false&columns[1][data]=nomesAlternativos&columns[1][name]=&columns[1][searchable]=true&columns[1][orderable]=true&columns[1][search][value]=&columns[1][search][regex]=false&order[0][column]=2&order[0][dir]=asc&start=0&length=10&search[value]=ss&search[regex]=false&_=1400248561282
Run Code Online (Sandbox Code Playgroud)

这就是我在Spring Controller中接收它的方式:

@RequestMapping(value = "/produtos-source", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public ProdutoTable dataTableRequest(@ModelAttribute DataTableCriterias criterias) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

最后,这是我的DataTableCriterias JavaBean(由@ModelAttribute指示):

public class DataTableCriterias {
    private int draw;
    private int start;
    private int length;

    private Map<SearchCriterias, String> search;

    private List<Map<OrderCriterias, String>> order;

    private List<Column> columns;

    public enum SearchCriterias {
        value,
        regex
    }

    public enum OrderCriterias {
        column,
        dir
    }

    public class Column {
        private String data;
        private String name;
        private boolean searchable;
        private boolean orderable;
        private Map<SearchCriterias, String> search;
    }
}
Run Code Online (Sandbox Code Playgroud)

(get/setters ommited)

这几乎完美无缺!如果我删除此行:

private List<Column> columns;
Run Code Online (Sandbox Code Playgroud)

然后Spring自动从查询字符串中填充我的DataTableCriterias bean(当然,我没有得到列属性映射)

但添加此行后,我收到此错误:

2014-05-16 17:20:16.605 ERROR 2368 --- [tomcat-http--99] o.a.c.c.C.[.[.[.[dispatcherServlet]      : Servlet.service() for servlet [dispatcherServlet] in context with path [/relatorios] threw exception [Request processing failed; nested exception is org.springframework.beans.InvalidPropertyException: Invalid property 'columns[0][data]' of bean class [com.bergermobile.rest.domain.DataTableCriterias]: Illegal attempt to get property 'columns' threw exception; nested exception is org.springframework.beans.NullValueInNestedPathException: Invalid property 'columns' of bean class [com.bergermobile.rest.domain.DataTableCriterias]: Could not instantiate property type [com.bergermobile.rest.domain.DataTableCriterias$Column] to auto-grow nested property path: java.lang.InstantiationException: com.bergermobile.rest.domain.DataTableCriterias$Column] with root cause

org.springframework.beans.NullValueInNestedPathException: Invalid property 'columns' of bean class [com.bergermobile.rest.domain.DataTableCriterias]: Could not instantiate property type [com.bergermobile.rest.domain.DataTableCriterias$Column] to auto-grow nested property path: java.lang.InstantiationException: com.bergermobile.rest.domain.DataTableCriterias$Column
    at org.springframework.beans.BeanWrapperImpl.newValue(BeanWrapperImpl.java:651)
Run Code Online (Sandbox Code Playgroud)

正如我所看到的,主要问题是Datatable插件发送的'column'参数是二维的,有时也是一个三维数组:

columns[0][data]=nome
columns[0][search][regex]=false
Run Code Online (Sandbox Code Playgroud)

所以,看起来我的Bean是正确的,但我得到了这个错误,现在我被卡住了.

有任何想法吗?

非常感谢!

Ber*_*ger 16

好的,所以我最终解决了这个问题,稍微修改了发送到服务器的参数,将两个3D列数组转换为2D数组.所以:

columns[0][search][value]=myvalue
columns[0][search][regex]=false
Run Code Online (Sandbox Code Playgroud)

结果是:

columns[0][searchValue]=myvalue
columns[0][searchRegex]=false
Run Code Online (Sandbox Code Playgroud)

这是在Databables中如何做到这一点:

$('#produtosTable').DataTable({
    serverSide: true,
    ajax: {
        "url": "produtos-source",
        "data": function(data) {
            planify(data);  
        } 
    }
});

function planify(data) {
    for (var i = 0; i < data.columns.length; i++) {
        column = data.columns[i];
        column.searchRegex = column.search.regex;
        column.searchValue = column.search.value;
        delete(column.search);
    }
}
Run Code Online (Sandbox Code Playgroud)

这样我就可以使用这个字段在我的Model对象中接收这些属性:

private List<Map<ColumnCriterias, String>> columns;
Run Code Online (Sandbox Code Playgroud)

仅供参考,这是我的控制器:

@RequestMapping(value = "/produtos-source", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public ProdutoTable dataTableRequest(@ModelAttribute DataTableCriterias criterias) {
    ProdutoTable produtoTable = produtosService.findProdutos();
    produtoTable.setDraw(criterias.getDraw());
    return produtoTable;
}
Run Code Online (Sandbox Code Playgroud)

这是最终我的DataTableCriterias @ModelAttriute:

public class DataTableCriterias {
    private int draw;
    private int start;
    private int length;

    private Map<SearchCriterias, String> search;

    private List<Map<ColumnCriterias, String>> columns;

    private List<Map<OrderCriterias, String>> order;

    public enum SearchCriterias {
        value,
        regex
    }
    public enum OrderCriterias {
        column,
        dir
    }
    public enum ColumnCriterias {
        data,
        name,
        searchable,
        orderable,
        searchValue,
        searchRegex
    }
Run Code Online (Sandbox Code Playgroud)

(get/setters省略)