zoukankan      html  css  js  c++  java
  • Spring MVC Ajax 复杂参数的批量传递

    Markdown

    要解决的问题:

    • 如何组织客户端参数?
    • Ajax 方法的配置属性如何定义才能传递复杂参数?
    • 基于 SpringMVC 的服务端该如何接收?
    • MyBatis 怎么处理批量更新?

    客户端脚本

    viewMessage: function (messageId) {
        console.info('viewMessage');
        // 通过 id 获取完整数据对象
        var message = $.grep($messageDatagrid.datagrid('getRows'), function (n, i) {
            return n.messageId == messageId
        })[0];
        console.info(message);
     
     
        // 如果该条记录是“未读”则更新为“已读”
        if (message.isReaded == YesOrNoEnum.No) {
            var updateReadState = {
                isReaded: YesOrNoEnum.Yes,
                messageIds: [messageId]
            };
     
            $.ajax({
                data: JSON.stringify(updateReadState),
                url: UrlEnum.UpdateReadState,
                type: "POST",
                dataType: "json",
                contentType: 'application/json;charset=utf-8', //“参数为泛型集合 @RequestBody List<> 时”需设置请求头信息
                success: function (result) {
                    console.info('updateReadState success,返回数据如下:↓');
                    console.info(result);
     
                    if (result.success) {
                        $.messager.show({
                            title: '提示', // 头部面板上显示的标题文本。
                            msg: result.message
                        });
     
                        $messageDatagrid.datagrid('load');
                        // 确保没有任何缓存痕迹(必不可少)
                        $messageDatagrid.datagrid('clearChecked');
                        $messageDatagrid.datagrid('clearSelections');
                    }
                    else {
                        if (result.operationType == operationTypeEnum.CookieTimeout) {
                            result.message = decodeURIComponent(result.message);
                        }
                        $.messager.alert('提示', result.message, 'warning');
                    }
                },
                error: function (result) {
                }
            }); // end ajax
        } // isReaded = no
    }
    

    在传递复杂类型的数据时,注意 Ajax 方法的 data 和 contentType 两个参数的设置。在 data 属性中用到了 JSON.stringify(),目的是将 data 属性转化为“JSON字符文本”形式,也是防止 jQuery 内部把 data 属性转化成了“查询字符串”格式(key1=valu1&key2=value2),倘若如此 SpringMVC 就不好识别解析了。

    Java 实体类

    public class BaseMessageUpdateReadState extends BaseEntity {
        private List<Integer> messageIds;
        private Integer    isReaded;
     
        public List<Integer> getMessageIds() {
            return messageIds;
        }
     
        public void setMessageIds(List<Integer> messageIds) {
            this.messageIds = messageIds;
        }
     
        public Integer getIsReaded() {
            return isReaded;
        }
     
        public void setIsReaded(Integer isReaded) {
            this.isReaded = isReaded;
        }
    }
    

    该实体类就是一个复杂形式的实体类,把实体类 BaseMessageUpdateReadState 的字段与客户端的 JSON 对象 updateReadState 作比较,可见二者是如此一致,需注意一下的是 js 中的数组与 Java 中的泛型集合 List 相对应。

    控制器

    @RequestMapping(value = "/UpdateReadState", method = RequestMethod.POST)
    @ResponseBody
    public TransactionResult UpdateReadState(@RequestBody BaseMessageUpdateReadState baseMessageUpdateReadState, @CookieValue(value = "base_cookieKey", required = false) CookieObject cookieObject) {
        baseMessageUpdateReadState.setCookieObject(cookieObject);
        TransactionResult result = null;
        try {
            result = iBaseMessageService.UpdateReadState(baseMessageUpdateReadState);
            return result;
        } catch (RuntimeException e) {
            result = new TransactionResult(false);
            if (e.getMessage() == null) {
                ByteArrayOutputStream buf = new java.io.ByteArrayOutputStream();
                e.printStackTrace(new java.io.PrintWriter(buf, true));
                String expMessage = buf.toString();
                try {
                    buf.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                result.setMessage(expMessage);
            } else {
                result.setMessage(e.getMessage());
            }
            return result;
        }
    }
    

    在控制器方法中,参数 BaseMessageUpdateReadState 前面必须带上 @RequestBody,它负责将 JSON 格式的复杂参数转化为 Java 实体类,非常的方便。

    MyBatis 应用

    接口:

    int affectedRows = iBaseMessageDao.UpdateReadState(baseMessageUpdateReadState);
    

    XML映射器:

    <!-- 批量更新阅读状态 -->
    <update id="UpdateReadState" parameterType="baseMessageUpdateReadState" timeout="20" flushCache="true">
        Update BaseMessage
        Set
            IsReaded = #{isReaded}
        Where 1=1
            and MessageId in
            <foreach collection="messageIds" index="index" item="item" open="(" close=")" separator=",">
            #{item}
            </foreach>
    </update>
    

    着重看看 #{isReaded} 和 collection="messageIds",这里也是跟 Java 实体类逐个对应,十分称心。
    值得一说的是 ,它主要就是用来构建 in() 条件。

    foreach 元素的属性主要有 item、index、collection、open、separator、close。

    • item 表示集合中每一个元素进行迭代时的别名
    • index 指定一个名字,用于表示在迭代过程中,每次迭代到的位置
    • open 表示该语句以什么开始
    • separator 表示在每次进行迭代之间以什么符号作为分隔符
    • close 表示以什么结束

    其中在指定“collection”属性时比较容易出错:

    • 如果传入的是单参数且参数类型是一个 List 的时候,collection 属性值为 list
    • 如果传入的是单参数且参数类型是一个 array 数组的时候,collection的 属性值为 array
  • 相关阅读:
    分页SQL 和Oracle 存储过程
    什么是SilverLight
    opendpi 源码分析(一)
    Multiway arrays
    循环链表
    轮询算法 这是一个印度人写的,学习下。 来自 codeproject
    Friday the Thirteenth
    通过命令行指定监听的IP和端口
    pthread_key_t
    贝叶斯网络 未学习前数据结构
  • 原文地址:https://www.cnblogs.com/ramantic/p/7530578.html
Copyright © 2011-2022 走看看