Spring MVC Ajax 複雜參數的批量傳遞

Markdown

要解決的問題:javascript

  • 如何組織客戶端參數?
  • 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

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 相對應。 ajax

控制器

@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 實體類,很是的方便。json

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() 條件。 cookie

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

  • item 表示集合中每個元素進行迭代時的別名
  • index 指定一個名字,用於表示在迭代過程當中,每次迭代到的位置
  • open 表示該語句以什麼開始
  • separator 表示在每次進行迭代之間以什麼符號做爲分隔符
  • close 表示以什麼結束

其中在指定「collection」屬性時比較容易出錯:app

  • 若是傳入的是單參數且參數類型是一個 List 的時候,collection 屬性值爲 list
  • 若是傳入的是單參數且參數類型是一個 array 數組的時候,collection的 屬性值爲 array
相關文章
相關標籤/搜索