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等不全面的地方。希望朋友可以指出,一起进步。