首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

使用 jQuery 簡化 Ajax 開發:JSON 數據交換、客戶端解析與 Java 服務端編碼實戰

     編輯:Java 相關知識

XML 解析繁瑣、HTML 片段耦合度高,JSON 以輕量、原生 JavaScript 支持、跨語言通用成為 Ajax 數據交換首選。本文系統講解 JSON 格式規範、JavaScript 原生處理、jQuery/Prototype 封裝調用、Java 服務端編碼輸出全流程,附完整代碼示例。

JSON 數據格式速覽

類型JSON 表示示例
String雙引號包裹,特殊字符轉義"Hello\nWorld"
Number整數/浮點數/科學計數法123 -3.9e10
Booleantrue / false(無引號)true
Nullnull(無引號)null
Array方括號,逗號分隔["abc", 123, false, null]
Object大括號,鍵值對,鍵必須雙引號{"city":"Beijing","postcode":100025}

嵌套示例:

{
  "name": "Michael",
  "address": {
    "city": "Beijing",
    "street": "Chaoyang Road",
    "postcode": 100025
  }
}

客戶端處理:原生 + jQuery

1. 原生 JavaScript(現代瀏覽器首選)

// 發送請求
fetch('/api/user/1')
  .then(res => res.json())  // 自動解析 JSON
  .then(data => {
      console.log(data.name);           // "Michael"
      console.log(data.address.city);   // "Beijing"
      updateUI(data);
  })
  .catch(err => console.error(err));

// 或使用 async/await
async function loadUser() {
    const res = await fetch('/api/user/1');
    const data = await res.json();
    return data;
}

2. jQuery 封裝(兼容舊項目)

$.ajax({
    url: '/api/user/1',
    dataType: 'json',  // 關鍵:自動調用 JSON.parse
    success: function(data) {
        console.log(data.name);
        $('#user-name').text(data.name);
    },
    error: function(xhr, status, err) {
        console.error('載入失敗:', err);
    }
});

// 簡化 GET
$.getJSON('/api/user/1', function(data) {
    console.log(data.address.street);
});

3. Prototype 風格(歷史參考)

new Ajax.Request('/api/user/1', {
    method: 'get',
    onSuccess: function(transport) {
        var json = transport.responseText.evalJSON(); // Prototype 擴展
        // 處理 json...
    }
});

服務端輸出:Java 手工編碼實現

為理解本質,展示無第三方庫的手工編碼(生產建議用 Jackson/Gson)。

核心編碼類 JsonUtil

public class JsonUtil {

    public static String toJson(Object o) {
        if (o == null) return "null";
        if (o instanceof String) return string2Json((String) o);
        if (o instanceof Boolean) return boolean2Json((Boolean) o);
        if (o instanceof Number) return number2Json((Number) o);
        if (o instanceof Map) return map2Json((Map<String, Object>) o);
        if (o instanceof Object[]) return array2Json((Object[]) o);
        throw new RuntimeException("Unsupported type: " + o.getClass().getName());
    }

    private static String string2Json(String s) {
        StringBuilder sb = new StringBuilder(s.length() + 20);
        sb.append('"');
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            switch (c) {
                case '"': sb.append("\\\""); break;
                case '\\': sb.append("\\\\"); break;
                case '/': sb.append("\\/"); break;
                case '\b': sb.append("\\b"); break;
                case '\f': sb.append("\\f"); break;
                case '\n': sb.append("\\n"); break;
                case '\r': sb.append("\\r"); break;
                case '\t': sb.append("\\t"); break;
                default: sb.append(c);
            }
        }
        sb.append('"');
        return sb.toString();
    }

    private static String number2Json(Number n) { return n.toString(); }
    private static String boolean2Json(Boolean b) { return b.toString(); }

    private static String array2Json(Object[] arr) {
        if (arr.length == 0) return "[]";
        StringBuilder sb = new StringBuilder(arr.length << 4);
        sb.append('[');
        for (Object o : arr) {
            sb.append(toJson(o)).append(',');
        }
        sb.setCharAt(sb.length() - 1, ']');
        return sb.toString();
    }

    private static String map2Json(Map<String, Object> map) {
        if (map.isEmpty()) return "{}";
        StringBuilder sb = new StringBuilder(map.size() << 4);
        sb.append('{');
        for (Map.Entry<String, Object> e : map.entrySet()) {
            sb.append('"').append(e.getKey()).append('"').append(':')
              .append(toJson(e.getValue())).append(',');
        }
        sb.setCharAt(sb.length() - 1, '}');
        return sb.toString();
    }
}

Servlet 輸出示例

@WebServlet("/api/user/*")
public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String path = req.getPathInfo(); // /1
        Long id = Long.valueOf(path.substring(1));

        // 模擬數據
        Map<String, Object> address = new HashMap<>();
        address.put("city", "Beijing");
        address.put("street", "Chaoyang Road");
        address.put("postcode", 100025);

        Map<String, Object> user = new HashMap<>();
        user.put("name", "Michael");
        user.put("address", address);

        // 輸出 JSON
        resp.setContentType("application/json;charset=UTF-8");
        resp.setCharacterEncoding("UTF-8");
        try (PrintWriter pw = resp.getWriter()) {
            pw.write(JsonUtil.toJson(user));
            pw.flush();
        }
    }
}

生產級建議:拥抱成熟庫

庫特點Maven 坐標
Jackson高性能、功能全、Spring Boot 默認、支持流式/樹模型/數據綁定com.fasterxml.jackson.core:jackson-databind
GsonGoogle 出品、API 簡潔、對 Kotlin 友好、適合 Androidcom.google.code.gson:gson
JSON-B (Jakarta EE)標準化 API、多實現(Yasson、Johnzon)、CDI 集成jakarta.json.bind:jakarta.json.bind-api

Jackson 一鍵序列化

ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
String json = mapper.writeValueAsString(userObject);
// 或直接返回對象,Spring MVC 自動轉換
@GetMapping("/api/user/{id}")
public User getUser(@PathVariable Long id) { return userService.find(id); }

安全與最佳實踐

  1. 設置正確 MIME:application/json;charset=UTF-8,防止瀏覽器誤識為 HTML 執行腳本。
  2. 防 JSON 劫持:敏感數據接口僅接受 POST、驗證 CSRF Token、或在 JSON 前綴 )]}\',\n(GWT/Gmail 風格)。
  3. 輸入驗證:服務端嚴格校驗反序列化對象(JSR-303 @Valid + Bean Validation)。
  4. 日期格式統一:ISO-8601 (yyyy-MM-dd'T'HH:mm:ss.SSSZ),避免時區歧義。
  5. 避免循環引用:Jackson @JsonIgnore / @JsonManagedReference / @JsonBackReference 處理雙向關聯。

小結

JSON 以極簡語法、原生 JS 支持、廣泛語言生態成為 Web 數據交換事實標準。理解其格式本質、客戶端解析機制、服務端編碼邏輯,能幫你在選型、調試、性能優化、安全加固等環節做出專業決策。現代開發中,**客戶端優先 fetch + response.json(),服務端優先 Jackson/Gson 自動綁定**,手工編碼僅作教學或極端受限環境備選。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved