【问题标题】:Spring MVC + DataTables 1.10 Parameters bindingSpring MVC + DataTables 1.10 参数绑定
【发布时间】:2015-03-27 16:21:15
【问题描述】:

我正在尝试做一个为 DataTables 执行服务器端的控制器。

@RequestMapping(value="/grid", method={RequestMethod.GET}, produces= MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public DataTablesResponse<MyObject> grid(DataTablesRequest dt) {
        return service.getListOfMyObjects();
    }

DataTablesRequest.class:

public class DataTablesRequest {

    private int draw;
    private int start;
    private int length;

    private Search search;

    private List<Order> order;

    private List<Column> columns;

   //... Getters and setters
}

订单类:

public class Order {
    private String column;
    private String dir;
//...getters and setters
}

列.class

public class Column {

    private String data;
    private String name;
    private boolean searchable;
    private boolean orderable;
    private Search search;
//...Getters and setters
}

搜索类:

public class Search {
    private String value;
    private boolean regex;
//...getters and setters
}

问题在于 DataTables 发送的参数如下:column[0][name] 而 SpringMVC 期望的是 column[0].name 之类的参数。

有没有办法解决这个问题?如何将 DataTables 的参数绑定到对象?

【问题讨论】:

标签: spring spring-mvc datatables jquery-datatables datatables-1.10


【解决方案1】:

有点晚的答案,但也许这会对将来的某人有所帮助:

在数据表设置中,我们需要告诉 jQuery处理数据并发送 JSON:

ajax: {
     url: "/some/url.json"),
     type: "POST",
     data: function (data) {
         return JSON.stringify(data);
     },
     dataType: "json",
     processData: false,
     contentType: 'application/json;charset=UTF-8'
},

在 Spring 方面:

@RequestMapping(value = "/some/url")
@ResponseBody
public DataTablesResponse<Element> list(@RequestBody final DataTablesRequest dataTablesRequest) {
    // query the DB to get the number of elements (without filtering)
    // and the list of elements (filtered and/or paginated)
    return new DataTablesResponse(numberOfElements, notifications.getTotalElements(), dataTablesRequest.getDraw(), "", listOfElements);
}

DataTablesRequest 等的以下内容(@Data 来自 lombok,javadoc cmets 来自官方数据表文档。):

@Data
public class DataTablesRequest {
    /**
     * Draw counter. This is used by DataTables to ensure that the Ajax returns from server-side processing requests are drawn in sequence by DataTables
     * (Ajax requests are asynchronous and thus can return out of sequence). This is used as part of the draw return parameter (see below).
     */
    private int draw;

    /**
     * Paging first record indicator. This is the start point in the current data set (0 index based - i.e. 0 is the first record).
     */
    private int start;

    /**
     * Number of records that the table can display in the current draw. It is expected that the number of records returned will be equal to this number, unless
     * the server has fewer records to return. Note that this can be -1 to indicate that all records should be returned (although that negates any benefits of
     * server-side processing!)
     */
    private int length;

    /**
     * @see Search
     */
    private Search search;

    /**
     * @see Order
     */
    @JsonProperty("order")
    private List<Order> orders;

    /**
     * @see Column
     */
    private List<Column> columns;
}

@Data
private static class Search {
    /**
     * Global search value. To be applied to all columns which have searchable as true.
     */
    private String value;

    /**
     * <code>true</code> if the global filter should be treated as a regular expression for advanced searching, false otherwise. Note that normally server-side
     * processing scripts will not perform regular expression searching for performance reasons on large data sets, but it is technically possible and at the
     * discretion of your script.
     */
    private boolean regex;
}

@Data
private static class Order {
    /**
     * Column to which ordering should be applied. This is an index reference to the columns array of information that is also submitted to the server.
     */
    private int column;

    /**
     * Ordering direction for this column. It will be <code>asc</code> or <code>desc</code> to indicate ascending ordering or descending ordering,
     * respectively.
     */
    private String dir;
}

@Data
private static class Column {
    /**
     * Column's data source, as defined by columns.data.
     */
    private String data;

    /**
     * Column's name, as defined by columns.name.
     */
    private String name;

    /**
     * Flag to indicate if this column is searchable (true) or not (false). This is controlled by columns.searchable.
     */
    private boolean searchable;


    /**
     * Flag to indicate if this column is orderable (true) or not (false). This is controlled by columns.orderable.
     */
    private boolean orderable;

    /**
     * Search value to apply to this specific column.
     */
    private Search search;

    /**
     * Flag to indicate if the search term for this column should be treated as regular expression (true) or not (false). As with global search, normally
     * server-side processing scripts will not perform regular expression searching for performance reasons on large data sets, but it is technically possible
     * and at the discretion of your script.
     */
    private boolean regex;
}

@Data
public class DataTablesResponse<T> {
    /**
     * The draw counter that this object is a response to - from the draw parameter sent as part of the data request. Note that it is strongly recommended for
     * security reasons that you cast this parameter to an integer, rather than simply echoing back to the client what it sent in the draw parameter, in order
     * to prevent Cross Site Scripting (XSS) attacks.
     */
    private int draw;

    /**
     * Total records, before filtering (i.e. the total number of records in the database)
     * <p/>
     * (NB: I changed this to long)
     */
    private long recordsTotal;

    /**
     * Total records, after filtering (i.e. the total number of records after filtering has been applied - not just the number of records being returned for this
     * page of data).
     * <p/>
     * (NB: I changed this to long)
     */
    private long recordsFiltered;

    /**
     * Optional: If an error occurs during the running of the server-side processing script, you can inform the user of this error by passing back the error message
     * to be displayed using this parameter. Do not include if there is no error.
     */
    private String error;

    /**
     * The data to be displayed in the table. This is an array of data source objects, one for each row, which will be used by DataTables. Note that this parameter's
     * name can be changed using the ajax option's dataSrc property.
     */
    private List<T> data = Lists.newArrayList();
}

【讨论】:

  • 这是否可以使用 GET 或 POST 更容易实现?
  • GET 或 POST 这是你的选择,不是吗?
  • 是的,但是使用 GET 时的数据表传递的 url 使用 @RequestParams 等解析并非易事,这部分:&order[0][column]=1&order[0][dir ]=desc
【解决方案2】:

HandlerMethodArgumentResolver如何实现,请参考https://github.com/rakurakupg/springmvc-jquerydatatables-example

【讨论】:

    【解决方案3】:

    我有类似的问题,下面为我工作。 尝试将@JsonProperty 添加到每个参数绑定类中的每个属性,例如@JsonProperty(value = "draw")。这样,Jackson 将其与从 DataTable 发送的 JSON 很好地映射。就我而言,我低于 JSON

    {   
    "draw":1,
    "columns":[
        {"data":0,"name":"","searchable":true,"orderable":false,"search":{"value":"","regex":false}},
        {"data":1,"name":"","searchable":true,"orderable":false,"search":{"value":"","regex":false}}],
    "order":[],
    "start":0,
    "length":-1,
    "search":{"value":"","regex":false}
    

    }

    还需要为DataTablesRequestColumnOrderSearch 定义空构造函数。 如果你不想拥有默认构造函数,你可以像下面这样添加它,

    public Search(@JsonProperty("value") String value,@JsonProperty("regex") String regex) {
            // TODO Auto-generated constructor stub
        }
    

    希望这会有所帮助!

    【讨论】:

    • 忘了说,我使用的是 Jackson 1.9.9 和 DataTable 1.10。
    • 那没有成功。我试图将注释放在所有属性上,但没有奏效。问题在于 Spring 绑定。
    【解决方案4】:

    我的解决方案是按照此处的说明以 JSON 格式发送请求:ASP.net jQuery DataTables

    基本上只是将页面上的 JS 更改为如下内容:

    'ajax': {
        'url': 'serverSideTableProviderPage',
        'type': 'POST',
        'data':function(data)
         {
           return data = JSON.stringify(data);
         }
    },
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-23
      • 1970-01-01
      • 1970-01-01
      • 2016-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多