控制器参数接收不到页面数据?

说明:前端使用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。因为菜单数量是动态的,所以使用List<SecRoleFuncVO>的方式来做数据保存。结构如下:

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类的结构,它里面差不多只有一个int型的fid字段。换句话说,其实整个页面就是要取这些checkbox的fid值就好了。

但是有个问题,控制器的参数不接受类集合,所以我又建了一个类来保存上面的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;
}



    

接着是把页面的值取过来。本来如果只有一条数据,那么按说控制器参数的类会自动识别页面上的控件名,但是这个页面是动态的,并且有一级,二级两层,数据会有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) {//循环一级菜单
                        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
    })
    ;
}

调试时结果很正常(请参照SecRoleFuncVO类):
图片描述
但是,根本不进控制器,并且报了这个错误:

图片描述

如果我将js中的

  var paramList = {};//实体
                    paramList['secRoleFuncVOList'] = SecRoleFuncVOList;
                    object = paramList;

改成

object =SecRoleFuncVOList;

那么能进控制器,但结果是这样:
图片描述

也就是说,不管我怎么写,值就是进不了控制器,请问这个要怎么解决呢?
或者说,各位大神有更好的方法让页面的值传进后台吗?(比如不通过js)

阅读 2.6k
2 个回答

这个问题我之前也碰到过,你试一下在参数对象上面加一个 @RequestBody 如下图:
图片描述

新手上路,请多包涵

已解决
首先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;
    }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题