Чтение файлов Json с помощью Gson - Java - PullRequest
0 голосов
/ 16 марта 2019

Я пытался прочитать несколько простых JSON файлов с Gson.Это мой JSON:

[
  {
    "OBJECTID": 14476381,
    "ROW_": null,
    "LOCATION": "1400 BLK S CAPITOL ST SE N/B",
    "ADDRESS_ID": 277954,
    "STREETSEGID": null,
    "XCOORD": 399257.7,
    "YCOORD": 133847.29,
    "TICKETTYPE": "Moving",
    "FINEAMT": 300,
    "TOTALPAID": 0,
    "PENALTY1": 300,
    "PENALTY2": null,
    "ACCIDENTINDICATOR": "No",
    "TICKETISSUEDATE": "2018-04-01T11:59:00.000Z",
    "VIOLATIONCODE": "T122",
    "VIOLATIONDESC": "SPEED 26-30 MPH OVER THE SPEED LIMIT",
    "ROW_ID": null
  },
  {
    "OBJECTID": 14476382,
    "ROW_": null,
    "LOCATION": "100 BLK MICHIGAN AVE NW E/B",
    "ADDRESS_ID": 815694,
    "STREETSEGID": 1405,
    "XCOORD": 398728.3,
    "YCOORD": 139835.9,
    "TICKETTYPE": "Moving",
    "FINEAMT": 100,
    "TOTALPAID": 0,
    "PENALTY1": 100,
    "PENALTY2": null,
    "ACCIDENTINDICATOR": "No",
    "TICKETISSUEDATE": "2018-04-01T00:35:00.000Z",
    "VIOLATIONCODE": "T119",
    "VIOLATIONDESC": "SPEED 11-15 MPH OVER THE SPEED LIMIT",
    "ROW_ID": null
  },
  ...
]

И это то, что у меня есть в моем коде:

private void readJson(String[] months) throws NumberFormatException, IOException {
 for (int i = 0; i < months.length; i++) {
  String month = months[i];

  try {

   InputStreamReader isr = new InputStreamReader(new FileInputStream(month));
   JsonReader reader = new JsonReader(isr);

   reader.beginArray();

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

   while (reader.hasNext()) {
    VOMovingViolations violation = gson.fromJson(reader, VOMovingViolations.class);
    data.push(violation);

   }

  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

Это мой класс VOMovingViolation

class VOMovingViolation {
 private int objectId;
 private byte row;
 private String location;
 private int addressId;
 private byte streetSegId;
 private double xCord;
 private double yCord;
 private String ticketType;
 private short fineamt;
 private short totalPaid;
 private short penalty1;
 private short penalty2;
 private String accidentIndicator;
 private String ticketIssueDate;
 private String violationCode;
 private String violationDescription;
 private byte rowId;

 public VOMovingViolations(int objectId, byte row, String location, int addressId, byte streetSegId, double xCord,
  double yCord, String ticketType, short fineamt, short totalPaid, short penalty1, short penalty2,
  String accidentIndicator, String ticketIssueDate, String violationCode, String violationDescription,
  byte rowId) {

  this.objectId = objectId;
  this.row = row;
  this.location = location;
  this.addressId = addressId;
  this.streetSegId = streetSegId;
  this.xCord = xCord;
  this.yCord = yCord;
  this.ticketType = ticketType;
  this.fineamt = fineamt;
  this.totalPaid = totalPaid;
  this.penalty1 = penalty1;
  this.penalty2 = penalty2;
  this.accidentIndicator = accidentIndicator;
  this.ticketIssueDate = ticketIssueDate;
  this.violationCode = violationCode;
  this.violationDescription = violationDescription;
 }

 @Override
 public int compareTo(VOMovingViolations o) {
  return Integer.compare(objectId, o.objectId);
 }
}

Мне нужно создать объект для каждого JSON object, который читается из моего JSON, а затем добавить его в созданный мной стек.Если я реализую то, что имею, и печатаю в консоли мое первое нарушение, я получаю это

ObjectID: 0 ||Адрес ID: 0 ||Street Seg ID: 0 ||Всего оплачено: 0 ||Расположение: ноль ||Дата выпуска билета: ноль ||Индикатор аварии: ноль ||Нарушение Описание: null

Как правильно разобрать?

1 Ответ

0 голосов
/ 16 марта 2019

Имена в JSON не соответствуют именам свойств в POJO. Вам необходимо предоставить дополнительное соглашение об именах или использовать аннотацию SerializedName. С соглашением об именах это может выглядеть так:

import com.google.gson.FieldNamingStrategy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.List;

public class GsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        Gson gson = new GsonBuilder()
                .setFieldNamingStrategy(new FieldNamingStrategy() {
                    @Override
                    public String translateName(Field f) {
                        final String name = f.getName();
                        switch (name) {
                            case "row":
                                return "ROW_";
                            case "rowId":
                                return "ROW_ID";
                            case "violationDescription":
                                return "VIOLATIONDESC";
                            default:
                                return f.getName().toUpperCase();
                        }
                    }
                })
                .create();

        Type type = new TypeToken<List<VOMovingViolations>>() {
        }.getType();
        List<VOMovingViolations> violations = gson.fromJson(new FileReader(jsonFile), type);
        violations.forEach(System.out::println);
    }
}

Если вы хотите использовать аннотацию SerializedName, вам нужно аннотировать каждое поле в POJO, как показано ниже:

@SerializedName("OBJECTID")
private int objectId;

@SerializedName("ROW_")
private byte row;

...

В этом случае вам не нужно регистрировать FieldNamingStrategy объект, и ваш Gson объект может выглядеть следующим образом:

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

Кроме того, не создавайте Gson в цикле foreach. Этого будет достаточно, чтобы создать его один раз перед циклом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...