jQuery DataTable使用时不能把请求参数绑定到javabean对象中

本文讲述了在使用最新版jQuery DataTables时遇到的服务器端分页字段排序参数绑定到Java Bean对象的问题。作者详细描述了问题的出现及解决过程,包括DataTable的配置、请求参数问题,以及最终通过修改配置和Bean结构解决问题的方法。旨在帮助遇到相同问题的开发者找到解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

故事前提:

最近项目中有使用到bootstrap框架,为了风格统一,于是后台表格分页显示插件选用了DataTable。DataTable是一款基于jquery开发的table控件,且风格统一于bootstrap,所以感觉选择这个控件是不错的选择。

国内介绍 DataTable 插件的文档还是不多,且很多都是基于version 1.9之前的老版本使用。我选择的是最新的1.10版,和之前的历史版本有较大区别,这里也是我项目中使用遇到的比较麻烦的问题,耗时1天半才搞定,所以在此撰写此文,希望有童谣问题的童鞋能有所收获。

注:DataTable官方文档

问题描述:

DataTable常用参数配置:

table = $('#dataTables-news').dataTable( {
    	
	lengthMenu : [10, 25, 50],
        processing: true,
        serverSide: true,
        ajax: {
            url: "./news/queryPageNews.htm",
            data : function(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);
                }
            }
        },
        columnDefs: [
             {
            	 "targets": [ 0 ],
                 "visible": false
             }
        ],
        columns: [
            { "data": "newsId","name":"news_id","searchable" : false},
            { "data": "newsTitle" ,"name":"news_title"},
            { "data": "newsType.newsTypeName" ,"name":"news_type" },
            { "data": "newsAuthor" ,"name":"news_author","orderable" : false},
            { "data": "newsReleaseTime" ,"name":"news_release_time","searchable" : false,"orderable" : false},
            { "data": "newsKeywords" ,"name":"news_keywords","searchable" : false,"orderable" : false},
            {
                "data": null,
                "orderable" : false,
                "className": "center",
            }
        ]
    } );

columns:是用来定义表格列相关详细配置,关系数据回调后的解析、是否可查询、查询时字段名称等问题,是一般开发者最为关注的配置项之一。

DataTable支持浏览器端和服务器端的分页。客户端分页较为简单,当使用服务器端分页时,问题就复杂了点,要设计字段排序。插件通过Ajax发送一个请求给服务器端,传递相关参数,具体如下:

draw(integer):Draw counter。用来保证从服务器端异步返回的结果按照序列绘制,可以有效防止跨域攻击。

start(integer):开始页码

length(integer):单页显示数量

search.value(string): Global search value

search.regex(boolean): 全局过滤器(不怎么在服务器端分页使用)

order[i].column(integer):需要排序的列号,从0开始计数

order[i].dir(string):排序的方向(desc 或 asc)

columns[i].data(string): defined by  columns.data 解析回调数据时使用

column[i].name(string):defined by columns.name 排序的字段名称使用这个

columns[i].searchable(boolean): 指定该列是否支持搜索

columns[i].orderable(Boolean):指定该列是否支持排序

columns[i].search.value(string):针对指定列的搜索值

columns[i].search.regex(false):标识该列是否被当做常规表达式(个人暂时未用到这个)


打开 开发者工具 时,看到传递的参数格式为:

draw=1

start=1

length=20

order[0][column]=1

order[0][dir]=asc

search[value]=xxx

search[regex]=false

column[0][data]=newsName

column[0][name]=news_name

columns[0][searchable]=false

columns[0][orderable]=true

columns[0][data]=nome
columns[0][search][regex]=false

使用时,发现不配置支持字段排序时是没问题的,但是如果 配置多个column排序时,参数获取就遇到困难了,想到java bean封装类定义成如下格式:

private Integer draw ;
	
	private Integer start;
	
	private Integer length;
	
	private Map<Search, String> search = new HashMap<Search, String>();

    private List<Map<Order, String>> order = new ArrayList<Map<Order, String>>();

    private List<Map<Column, String>> columns = new ArrayList<Map<Column, String>>();

    public DTRequestParams() {
    	
    }
    public enum Search {
        value,
        regex
    }

    public enum Order {
        column,
        dir
    }

    public enum Column {
        private String data;
        private String name;
        private boolean searchable;
        private boolean orderable;
        private Map<SearchCriterias, String> search;
    }

//省略了getter and setter方法

spring mvc 控制层的配置如下:

@RequestMapping(value="/back/news/queryPageNews",method=RequestMethod.GET)
	@ResponseBody
	public DTListVO queryPageNewsForAdmin(@ModelAttribute DTRequestParams dtParams,HttpServletRequest request){
.......
}

这样数据绑定,会报错,错误信息如下:

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)

百思不得其解,最终发现错误提示是说,数据绑定出错,因为请求参数columns是一个高维数组表示形式。

花了一天的时间来解决spring mvc数据绑定问题上,但最终还是没得到解决办法。最后,选择了在DataTable配置上来解决问题,最终的解决方案是处理请求参数,使之columns高维数组降维成了一位数组,问题就得到解决了。


更改配置项ajax:

ajax: {
            url: "./news/queryPageNews.htm",
            data : function(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);
                }
            }
        }

也就是从新构造了请求的参数。


最后java bean封装类定义改成了:

private Integer draw ;
	
	private Integer start;
	
	private Integer length;
	
	private Map<Search, String> search = new HashMap<Search, String>();

    private List<Map<Order, String>> order = new ArrayList<Map<Order, String>>();

    private List<Map<Column, String>> columns = new ArrayList<Map<Column, String>>();

    public DTRequestParams() {
    	
    }
    public enum Search {
        value,
        regex
    }

    public enum Order {
        column,
        dir
    }

    public enum Column {
        data,
        name,
        searchable,
        orderable,
        searchValue,
        searchRegex
    }


注意,只是修改了Column 类。

同理,省略了相应的getter setter方法。


就这样,问题解决了,希望对大家有帮助,如果更完美的解决方案,欢迎交流,共同学习!!!




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值