dataTable 發送數據使用springMVC接收自動封裝失敗的解決辦法

dataTable 發送數據使用springMVC接收自動封裝失敗的解決辦法

  • 1、封裝dataTable傳到後臺的數據的封裝Bean
  • 2、自定義SpringMVC參數解析器

封裝Bean

  • 封裝主Bean:SearchCondition
package com.boleprint.util.entiy.datatable;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class SearchCondition implements Serializable{
    private static final long serialVersionUID = 1L;
    private int draw;
    private List<Column> columns = new ArrayList<Column>();
    private List<Order> orders = new ArrayList<Order>();
    private int start = 0;
    private Search search = new Search();

    /**
     * setter 及getter
     */
}
  • 封裝屬性Bean:Column
package com.boleprint.util.entiy.datatable;

import java.io.Serializable;

public class Column implements Serializable{
    private static final long serialVersionUID = 1L;
    private String data;
    private String name;
    private boolean searchable;
    private boolean orderable;
    private Search search = new Search();

    /**
     * setter 及getter
     */
}
  • 封裝屬性Bean:Order
package com.boleprint.util.entiy.datatable;

import java.io.Serializable;

public class Order implements Serializable{
    private static final long serialVersionUID = 1L;
    private int column;
    private String dir;
    /**
     * setter 及getter
     */
  • 封裝屬性Bean:Search
package com.boleprint.util.entiy.datatable;

import java.io.Serializable;

public class Search implements Serializable{
    private static final long serialVersionUID = 1L;
    private String value;
    private boolean regex;
    /**
     * setter 及getter
     */
}

自定義SpringMVC參數解析器(詳細方法自己瞭解)

  • 首先創建一個類實現HandlerMethodArgumentResolver接口
package com.boleprint.web.controller.resolver;

import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import com.boleprint.annotation.IsSearchCondition;
import com.boleprint.util.StringUtil;
import com.boleprint.util.entiy.datatable.Column;
import com.boleprint.util.entiy.datatable.Order;
import com.boleprint.util.entiy.datatable.SearchCondition;

public class SeacherConditionArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public SearchCondition resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        Set<String> parameterNames = webRequest.getParameterMap().keySet();
        SearchCondition condition = new SearchCondition();
        for (String name : parameterNames) {

            /*
             * 設置SearchCondition 的columns屬性;
             */
            if(name.startsWith("columns")){
                int index = Integer.parseInt(name.substring(8, 9));
                String secendName = name.substring(getCharPosition(name, "\\[", 2)+1, getCharPosition(name, "\\]", 2));
                try {
                    if(condition.getColumns().get(index)==null) condition.getColumns().add(new Column());
                }catch(IndexOutOfBoundsException e){
                    condition.getColumns().add(new Column());
                }
                switch (secendName) {
                case "data":
                    condition.getColumns().get(index).setData(webRequest.getParameter(name));
                    break;
                case "name":
                    condition.getColumns().get(index).setName(webRequest.getParameter(name));
                    break;
                case "searchable":
                    condition.getColumns().get(index).setSearchable(Boolean.valueOf(webRequest.getParameter(name)));
                    break;
                case "orderable":
                    condition.getColumns().get(index).setOrderable(Boolean.valueOf(webRequest.getParameter(name)));
                    break;
                case "search":
                    String thirdName = name.substring(getCharPosition(name, "\\[", 3)+1, getCharPosition(name, "\\]", 3));
                    switch (thirdName) {
                    case "regex":
                        condition.getColumns().get(index).getSearch().setRegex(Boolean.valueOf(webRequest.getParameter(name)));
                        break;
                    case "value":
                        String c = webRequest.getParameter(name);
                        condition.getColumns().get(index).getSearch().setValue(c);
                        break;
                    }
                    break;
                }
            }

            /*
             * 設置SearchCondition 的columns屬性;
             */
            else if(name.startsWith("order")){
                int index = Integer.parseInt(name.substring(6, 7));
                String secendName = name.substring(getCharPosition(name, "\\[", 2)+1, getCharPosition(name, "\\]", 2));
                try {
                    if(condition.getOrders().get(index)==null) condition.getOrders().add(new Order());
                }catch(IndexOutOfBoundsException e){
                    condition.getOrders().add(new Order());
                }
                switch (secendName) {
                case "column":
                    condition.getOrders().get(index).setColumn(Integer.parseInt(webRequest.getParameter(name)));
                    break;
                case "dir":
                    condition.getOrders().get(index).setDir(webRequest.getParameter(name));
                    break;
                }
            }

            /*
             * 設置SearchCondition 的draw屬性;
             */
            else if(name.equalsIgnoreCase("draw")){
                if(StringUtil.checkNull(webRequest.getParameter("draw"))) condition.setDraw(Integer.parseInt(webRequest.getParameter("draw")));
                else return null;
            }

            /*
             * 設置SearchCondition 的length屬性;
             */
            else if(name.equalsIgnoreCase("length")){
                if(StringUtil.checkNull(webRequest.getParameter("length"))) condition.setLength(Integer.parseInt(webRequest.getParameter("length")));
            }

            /*
             * 設置SearchCondition 的start屬性;
             */
            else if(name.equalsIgnoreCase("start")){
                if(StringUtil.checkNull(webRequest.getParameter("start"))) condition.setStart(Integer.parseInt(webRequest.getParameter("start")));
            }

            /*
             * 設置SearchCondition 的start屬性;
             */
            else if(name.equalsIgnoreCase("search")){
                String secendName = name.substring(getCharPosition(name, "\\[", 2)+1, getCharPosition(name, "\\]", 2));
                switch (secendName) {
                case "regex":
                    condition.getSearch().setRegex(Boolean.valueOf(webRequest.getParameter(name)));
                    break;
                case "value":
                    condition.getSearch().setValue(webRequest.getParameter(name));
                    break;
                }
            }
        }
        return condition;
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(IsSearchCondition.class);
    }

    /**
     * 獲取某段字符串在某個字符串中某次出現的位置
     * @param string 被查找的字符串
     * @param regex 需要查找的正則表達式
     * @param index 出現的次數
     * @return 需要查找的字符串/字符出現的位置
     */
    private int getCharPosition(String string, String regex, int index) {
        Matcher slashMatcher = Pattern.compile(regex).matcher(string);
        int mIdx = 0;
        while (slashMatcher.find()) {
            mIdx++;
            if (mIdx == index) break;
        }
        return slashMatcher.start();
    }
}
  • 自定義註解類。讓supportsParameter解析,目的是讓是有添加了這個註解的類才能進入到這個參數解析器,並沒有別的用處,所以類裏面可以什麼都不寫。
package com.boleprint.annotation;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PACKAGE;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.TYPE_PARAMETER;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Documented
@Retention(RUNTIME)
@Target({ TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE, PACKAGE, TYPE_PARAMETER, TYPE_USE })
public @interface IsSearchCondition {

}
  • 配置SpringMVC的配置文件
    <mvc:annotation-driven>
        <mvc:argument-resolvers>
            <bean class="com.boleprint.web.controller.resolver.SeacherConditionArgumentResolver"/>
        </mvc:argument-resolvers>
    </mvc:annotation-driven>

Controller的實現方式

@RequestMapping(value="quote/data/ChoosePaper")
    public @ResponseBody ResponsePage<CustomerSeachDTO> getSearchCustomer(@IsSearchCondition SearchCondition condition){
        return null;
    }

至此所有後臺配置全部結束,前臺部分沒有任何改變,也不需要有任何改變。

代碼本人親測可以成功,但是也許會有Bug等不全面的地方。希望朋友可以指出,一起進步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章