Hướng dẫn toàn diện xử lý lỗi Gson: Từ JsonSyntaxException đến bảo mật dữ liệu

Giải quyết triệt để lỗi phân tích JSON với Gson

Khi triển khai ứng dụng Java, lỗi JsonSyntaxException từ Gson thường gây sập hệ thống đột ngột. Dữ liệu không chuẩn từ API bên ngoài là nguyên nhân phổ biến. Bài viết này cung cấp phương pháp hệ thống để xử lý lỗi, xây dựng lớp xử lý JSON robust và đảm bảo an toàn dữ liệu.

Bản chất lỗi phân tích JSON

Gson sử dụng hai loại lỗi chính: JsonSyntaxExceptionJsonParseException. Dù biểu hiện tương tự, nguyên nhân và cách xử lý hoàn toàn khác nhau.

JsonSyntaxException: Lỗi cấu trúc cú pháp

Xảy ra khi chuỗi JSON không tuân thủ chuẩn. Ví dụ:

  • Thiếu dấu ngoặc đóng: {"name":"Alice
  • Giá trị số không hợp lệ: {"age": "hai mươi"}
  • Ký tự escape sai: {"path":"C:\\\\Documents"}

Trong mã nguồn, lớp này có 3 phương thức khởi tạo:

public JsonSyntaxException(String msg) { super(msg); }
public JsonSyntaxException(String msg, Throwable cause) { super(msg, cause); }
public JsonSyntaxException(Throwable cause) { super(cause); }

JsonParseException: Lỗi chuyển đổi dữ liệu

Là lớp cơ sở cho mọi lỗi phân tích. Xảy ra khi JSON hợp lệ nhưng không thể chuyển thành đối tượng Java. Ví dụ:

  • Chuyển mảng JSON thành đối tượng đơn
  • Chuyển đổi kiểu không thành công (ví dụ: chuỗi thành Date)
  • Bộ chuyển đổi tùy chỉnh ném ngoại lệ

Gson thiết kế JsonParseException như runtime exception để buộc xử lý lỗi, không bỏ qua.

Chẩn đoán lỗi hệ thống

Quy trình 3 bước khi gặp lỗi:

  1. Dùng instanceof xác định loại lỗi
  2. Phân tích stack trace để定位 lỗi
  3. Kiểm tra dữ liệu đầu vào bằng công cụ như JSONLint
try {
  // Logic phân tích
} catch (JsonSyntaxException e) {
  // Xử lý cú pháp
} catch (JsonParseException e) {
  // Xử lý cấu trúc
}

Giải pháp nâng cao

Xử lý cơ bản

public <T> T xử_lý_an_toàn(String dữ_liệu, Class<T> kiểu) {
  try {
    return new Gson().fromJson(dữ_liệu, kiểu);
  } catch (JsonSyntaxException e) {
    logger.error("Lỗi cú pháp: {} - Dữ liệu: {}", e.getMessage(), dữ_liệu, e);
    return null;
  } catch (JsonParseException e) {
    logger.error("Lỗi chuyển đổi: {} - Kiểu: {}", e.getMessage(), kiểu.getName(), e);
    return null;
  }
}

Bộ chuyển đổi linh hoạt

public class AdapterGiáDẻoDai extends TypeAdapter<BigDecimal> {
  @Override
  public void write(JsonWriter writer, BigDecimal giá) throws IOException {
    writer.value(giá);
  }

  @Override
  public BigDecimal read(JsonReader reader) throws IOException {
    if (reader.peek() == JsonToken.STRING) {
      try {
        return new BigDecimal(reader.nextString());
      } catch (NumberFormatException ex) {
        reader.skipValue();
        logger.warn("Dùng giá mặc định 0", ex);
        return BigDecimal.ZERO;
      }
    } else if (reader.peek() == JsonToken.NUMBER) {
      return reader.nextBigDecimal();
    }
    reader.skipValue();
    return BigDecimal.ZERO;
  }
}

Đăng ký adapter:

Gson gson = new GsonBuilder()
  .registerTypeAdapter(BigDecimal.class, new AdapterGiáDẻoDai())
  .create();

Phân tích trước dữ liệu

Dùng JSON Schema để validate trước khi parse:

JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7);
JsonSchema schema = factory.getSchema(new File("schema.json"));
Set<ValidationMessage> lỗi = schema.validate(jsonNode);

if (!lỗi.isEmpty()) {
  throw new InvalidDataException("Dữ liệu không hợp lệ: " + lỗi.iterator().next().getMessage());
}

Kinh nghiệm thực tế

Xử lý ngày tháng

Gson gson = new GsonBuilder()
  .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
  .registerTypeAdapter(Date.class, new AdapterNgàyUTC())
  .create();

Xử lý số

  • Dùng Long thay int để tránh tràn
  • Dùng BigDecimal thay double cho độ chính xác
  • Cho trường nullable dùng wrapper type

Đa dạng đối tượng

RuntimeTypeAdapterFactory<PhươngTiện> adapter = RuntimeTypeAdapterFactory
  .of(PhươngTiện.class, "loại")
  .registerSubtype(XeMay.class, "xe_may")
  .registerSubtype(XeOto.class, "xe_oto");

Gson gson = new GsonBuilder()
  .registerTypeAdapterFactory(adapter)
  .create();

Giám sát lỗi

Thu thập chỉ số:

  • Tỷ lệ thành công phân tích
  • Phân bố loại lỗi
  • Nguồn lỗi từ API
  • Mẫu lỗi phổ biến

Ví dụ: Nền tảng thương mại điện tử xử lý weight字段 khi đôi khi là số, đôi khi là chuỗi. Xây dựng Adapter tự động loại bỏ đơn vị, giảm lỗi từ 3.2% xuống 0.05%.

Thẻ: gson JSON exception-handling typeadapter data-validation

Đăng vào ngày 3 tháng 6 lúc 20:04