鍍金池/ 問答/Java  HTML/ 控制器參數(shù)接收不到頁面數(shù)據(jù)?

控制器參數(shù)接收不到頁面數(shù)據(jù)?

說明:前端使用layui,后端spring mvc.
頁面是這樣的:
圖片描述
代碼:

<script id="secRoleFunctionTpl" type="text/html">
    <div style="padding-top: 30px;padding-left:20px;  margin-right: 50px">
        <form class="layui-form layui-form-pane" id="secRoleFunctionForm">
            <div class="layui-form-item">
                {{# layui.each(d.list, function(index, item){ }}
                <div class="layui-form-item">
                    <label class="layui-form-label formLabel-100">一級菜單</label>
                    <div class="layui-input-block">
                        {{# if(item.isChecked){ }}
                        <input type="checkbox" name="fristFunc" title="{{item.fristFunc.funcName}}"
                               data-value="{{item.fristFunc.fid}}" lay-filter="fristFuncCheckbox"
                               checked>
                        {{# } }}
                        {{# if(!item.isChecked){ }}
                        <input type="checkbox" name="fristFunc" title="{{item.fristFunc.funcName}}"
                               data-value="{{item.fristFunc.fid}}" lay-filter="fristFuncCheckbox"
                        >
                        {{# } }}

                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label formLabel-100">二級菜單</label>
                    <div class="layui-input-block">
                        {{# layui.each(item.secondFuncList, function(indexChild, itemChild){ }}
                        {{# if(item.fristFunc.fid==itemChild.parentFid){ }}
                        {{# if(itemChild.isChecked){ }}
                        <input type="checkbox" name="secondFuncList" title="{{itemChild.funcName}}"
                               data-value="{{itemChild.fid}}" lay-filter="secondFuncCheckbox"
                               checked>
                        {{# } }}
                        {{# if(!itemChild.isChecked){ }}
                        <input type="checkbox" name="secondFuncList" title="{{itemChild.funcName}}"
                               data-value="{{itemChild.fid}}" lay-filter="secondFuncCheckbox"
                        >
                        {{# } }}
                        {{# } }}
                        {{# }); }}
                    </div>
                </div>
                {{# }); }}
                <div class="layui-input-block">
                    <button class="layui-btn" lay-submit lay-filter="secRoleFunctionButton">立即提交</button>
                    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
                </div>
            </div>
        </form>
    </div>
</script>

如上所示,每個checkbox都有一個fid。因為菜單數(shù)量是動態(tài)的,所以使用List<SecRoleFuncVO>的方式來做數(shù)據(jù)保存。結(jié)構(gòu)如下:

public class SecRoleFuncVO implements Serializable {
    private SecFunction fristFunc;
    private List<SecFunction> secondFuncList;
    private Integer roid;

    public Integer getRoid() {
        return roid;
    }

    public void setRoid(Integer roid) {
        this.roid = roid;
    }

    public SecFunction getFristFunc() {
        return fristFunc;
    }

    public void setFristFunc(SecFunction fristFunc) {
        this.fristFunc = fristFunc;
    }

    public List<SecFunction> getSecondFuncList() {
        return secondFuncList;
    }

    public void setSecondFuncList(List<SecFunction> secondFuncList) {
        this.secondFuncList = secondFuncList;
    }
}

roid是固定的,并不用管。至于SecFunction類的結(jié)構(gòu),它里面差不多只有一個int型的fid字段。換句話說,其實整個頁面就是要取這些checkbox的fid值就好了。

但是有個問題,控制器的參數(shù)不接受類集合,所以我又建了一個類來保存上面的List<SecRoleFuncVO>:

public class ParameterList implements Serializable {


    private List<SecRoleFuncVO> secRoleFuncVOList;


    public List<SecRoleFuncVO> getSecRoleFuncVOList() {
        return secRoleFuncVOList;
    }

    public void setSecRoleFuncVOList(List<SecRoleFuncVO> secRoleFuncVOList) {
        this.secRoleFuncVOList = secRoleFuncVOList;
    }
}

然后控制器的代碼:
/**

 * 保存或修改已分配的菜單
 *
 * @param paramList
 * @return
 */
@RequestMapping("/saveOrUpSecRoleFunction")
@ResponseBody
public Json saveOrUpSecRoleFunction(ParameterList paramList) {
    Json json = new Json();
    try {
        secService.saveOrUpSecRoleFunction(paramList.getSecRoleFuncVOList());
        json.setSuccess(true);
    } catch (Exception e) {
        e.printStackTrace();
        json.setMsg(e.getMessage());
    }
    return json;
}



    

接著是把頁面的值取過來。本來如果只有一條數(shù)據(jù),那么按說控制器參數(shù)的類會自動識別頁面上的控件名,但是這個頁面是動態(tài)的,并且有一級,二級兩層,數(shù)據(jù)會有N條。所以我只能選擇在js里寫:

//分配菜單事件
function secRoleFunction(roid) {
    var result = $.loadData('/sec/querySecRoleFunctionByRoid?roid=' + roid);
    if (!result.success) {
        layer.msg(result.msg);
    } else {
        openSecRoleFunction('分配菜單', result.obj, roid);
    }
}

// 提交菜單
function openSecRoleFunction(title, Data, roid) {
    var tplHtml;
    var data = {'list': Data};
    layui.laytpl(secRoleFunctionTpl.innerHTML).render(data, function (html) {
        tplHtml = html;
    });

    layerIndex = layer.open({
        type: 1,
        title: title,
        area: ['400', '400'],
        success: function () {
            form = layui.form;
            form.render();
            $('#secRoleFunctionForm')[0].reset();
            form.on('submit(secRoleFunctionButton)', function (data) {
                    var object = data.field;

                    var SecRoleFuncVOList = new Array();//實體集合
                    $('input:checkbox[name="fristFunc"]:checked').each(function (indexFirst, itemFirst) {//循環(huán)一級菜單
                        var SecRoleFuncVO = {};//實體
                        //角色編號
                        SecRoleFuncVO['roid'] = roid;
                        //一級菜單
                        var fristFunc = {fid: $(itemFirst).data('value')};
                        SecRoleFuncVO['fristFunc'] = fristFunc;

                        //二級菜單
                        var secondItem = $(itemFirst).parent().parent().next().children('div').children('input:checkbox[name="secondFuncList"]:checked');
                        var secondFuncList = new Array();//二級菜單集合
                        secondItem.each(function (indexSecond, itemSecond) {
                            var secondFunc = {fid: $(itemSecond).data('value')};
                            secondFuncList.push(secondFunc);
                        });

                        SecRoleFuncVO['secondFuncList'] = secondFuncList;
                        SecRoleFuncVOList.push(SecRoleFuncVO);
                    });
                    var paramList = {};//實體
                    paramList['secRoleFuncVOList'] = SecRoleFuncVOList;
                    object = paramList;
                    console.table(object);
                    layer.msg('提交中,請稍候', {icon: 16, time: false, shade: 0.8});
                    $.post('/sec/saveOrUpSecRoleFunction', object ,
                        function (data) {
                            if (data.success) {
                                layer.close(layerIndex);
                                layer.msg("操作成功!");
                            } else {
                                layer.msg(data.msg);
                            }
                        }
                    );
                    return false;
                }
            );
        }

        ,
        shadeClose: true,
        area:
            ['1000px', '600px'],
        content:
        tplHtml
    })
    ;
}

調(diào)試時結(jié)果很正常(請參照SecRoleFuncVO類):
圖片描述
但是,根本不進控制器,并且報了這個錯誤:

圖片描述

如果我將js中的

  var paramList = {};//實體
                    paramList['secRoleFuncVOList'] = SecRoleFuncVOList;
                    object = paramList;

改成

object =SecRoleFuncVOList;

那么能進控制器,但結(jié)果是這樣:
圖片描述

也就是說,不管我怎么寫,值就是進不了控制器,請問這個要怎么解決呢?
或者說,各位大神有更好的方法讓頁面的值傳進后臺嗎?(比如不通過js)

回答
編輯回答
怪痞

已解決
首先js不使用$.post,而是使用:

$.ajax({
                        type: "post",
                        url: '/sec/saveOrUpSecRoleFunction',
                        dataType: "json",
                        contentType: 'application/json;charset=utf-8',
                        data: JSON.stringify(SecRoleFuncVOList),//此塊注意
                        success: function (data) {
                            if (data.success) {
                                layer.close(layerIndex);
                                layer.msg("操作成功!");
                            } else {
                                layer.msg(data.msg);
                            }
                        }
                    });

控制器也不用再把類集合放到一個類中,直接傳參就可以:

@RequestMapping("/saveOrUpSecRoleFunction")
    @ResponseBody
    public Json saveOrUpSecRoleFunction(@RequestBody List<SecRoleFuncVO> secRoleFuncVOS) {
        Json json = new Json();
        try {
            //  secService.saveOrUpSecRoleFunction(paramList.getSecRoleFuncVOList());
            json.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            json.setMsg(e.getMessage());
        }
        return json;
    }
2017年11月18日 22:27
編輯回答
女流氓

這個問題我之前也碰到過,你試一下在參數(shù)對象上面加一個 @RequestBody 如下圖:
圖片描述

2017年5月30日 12:51