Исключение: Генерация неполная JSON - PullRequest
0 голосов
/ 18 июня 2020

У меня есть следующий метод, который генерирует файл json с заданными аргументами, и если файл существует, он читает его, чтобы получить данные, а затем добавляет к нему новую информацию. По сути, я получаю эту ошибку либо с нашим, не имея уже созданного файла json.

public void cargarVentasDiaMesaJson(Mesas m, double total) {
    FileInputStream fI = null;
    JsonReader jRe = null;
    FileOutputStream f = null;
    JsonWriter jR = null;
    try {
        f = new FileOutputStream("C:\\archivos\\VentasDiaMesa.json");
        jR = Json.createWriter(f);
        JsonObjectBuilder obj = Json.createObjectBuilder();
        JsonArrayBuilder arrayB = Json.createArrayBuilder();
        File file = new File("C:\\archivos\\VentasDiaMesa.json");
        if(file.exists()) {
            fI = new FileInputStream("C:\\archivos\\VentasDiaMesa.json");
            jRe = Json.createReader(fI);
            JsonObject jsonR = jRe.readObject();
            JsonArray array = jsonR.getJsonArray("ventasDiaMesa");
            for(int i=0; i<array.size(); i++) {
                JsonObject vDiaMesa = array.getJsonObject(i);
                String fecha = vDiaMesa.getString("fecha");
                int numero = vDiaMesa.getInt("numero");
                double tot = Double.parseDouble(vDiaMesa.getString("total"));
                JsonObjectBuilder diaMesa = Json.createObjectBuilder();
                diaMesa.add("fecha", fecha);
                diaMesa.add("numero", numero);
                diaMesa.add("total", tot);
                JsonObject objLinea = diaMesa.build();
                arrayB.add(objLinea);
            }
        }
        JsonObjectBuilder diaMesa = Json.createObjectBuilder();
        Calendar fecha = Calendar.getInstance();
        String mes = (fecha.get(Calendar.MONTH)+1)<10?"0"+(fecha.get(Calendar.MONTH)+1):""+(fecha.get(Calendar.MONTH)+1);
        String dia = fecha.get(Calendar.DATE)<10?"0"+fecha.get(Calendar.DATE):""+fecha.get(Calendar.DATE);
        String date = "" + fecha.get(Calendar.YEAR) + mes + dia;
        diaMesa.add("fecha", date);
        String numero = (m.getNumero()<10)?"0"+m.getNumero():""+m.getNumero();
        diaMesa.add("numero", numero);
        String tot = Double.toString(total);
        while(tot.length() != 10) {
            tot = "0" + tot;
        }
        diaMesa.add("total", tot);
        JsonObject objLinea = diaMesa.build();
        arrayB.add(objLinea);
        JsonArray arr = arrayB.build();
        obj.add("ventasDiaMesa", arr);
        JsonObject obbbj = obj.build();
        jR.writeObject(obbbj);
    } catch (IOException e) {
        // TODO: handle exception
        e.printStackTrace();
    } finally {
        jR.close();
    }
}

И я получаю следующее сообщение об ошибке:

Exception in thread "AWT-EventQueue-0" javax.json.stream.JsonGenerationException: Generating incomplete JSON
at org.glassfish.json.JsonGeneratorImpl.close(JsonGeneratorImpl.java:509)
at org.glassfish.json.JsonWriterImpl.close(JsonWriterImpl.java:150)
at Modelo.DAO.VentasDiaMesaJSON.cargarVentasDiaMesaJson(VentasDiaMesaJSON.java:77)
at Controlador.ControladorPedidos.totalMesa(ControladorPedidos.java:94)
at Controlador.ControladorPedidos.cerrarDia(ControladorPedidos.java:119)
at Vista.PedidosGUI$1.actionPerformed(PedidosGUI.java:50)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Я создаю 3 конструктора объектов который я затем перехожу к сборке и, наконец, пишу основной объект перед закрытием файла. Я не вижу здесь ошибки. Есть идеи, где это может быть?

Спасибо

1 Ответ

2 голосов
/ 18 июня 2020

Я считаю, что вы читаете и записываете один и тот же файл одновременно . Кроме того, входной поток не закрывается, когда вы снова записываете в файл. Это могло поставить писателя в странное положение. Не могли бы вы попробовать со следующими настройками.

public void cargarVentasDiaMesaJson(Mesas m, double total) {
    String fileName = "C:\\archivos\\VentasDiaMesa.json";

    try {
        JsonObjectBuilder obj = Json.createObjectBuilder();
        JsonArrayBuilder arrayB = Json.createArrayBuilder();
        File file = new File(fileName);
        if (file.exists()) {
            // Try-with-resources: will auto-close JsonReader and inputStream
            //  >> close() of this stream was missing in original code
            try (JsonReader jRe = Json.createReader(new FileInputStream(file))) {
                JsonObject jsonR = jRe.readObject();
                JsonArray array = jsonR.getJsonArray("ventasDiaMesa");
                for (int i = 0; i < array.size(); i++) {
                    JsonObject vDiaMesa = array.getJsonObject(i);
                    String fecha = vDiaMesa.getString("fecha");
                    int numero = vDiaMesa.getInt("numero");
                    double tot = Double.parseDouble(vDiaMesa.getString("total"));
                    JsonObjectBuilder diaMesa = Json.createObjectBuilder();
                    diaMesa.add("fecha", fecha);
                    diaMesa.add("numero", numero);
                    diaMesa.add("total", tot);
                    JsonObject objLinea = diaMesa.build();
                    arrayB.add(objLinea);
                }
            }
        }
        JsonObjectBuilder diaMesa = Json.createObjectBuilder();
        Calendar fecha = Calendar.getInstance();
        String mes = (fecha.get(Calendar.MONTH) + 1) < 10 ? "0" + (fecha.get(Calendar.MONTH) + 1) : "" + (fecha.get(Calendar.MONTH) + 1);
        String dia = fecha.get(Calendar.DATE) < 10 ? "0" + fecha.get(Calendar.DATE) : "" + fecha.get(Calendar.DATE);
        String date = "" + fecha.get(Calendar.YEAR) + mes + dia;
        diaMesa.add("fecha", date);
        String numero = (m.getNumero() < 10) ? "0" + m.getNumero() : "" + m.getNumero();
        diaMesa.add("numero", numero);
        String tot = Double.toString(total);
        while (tot.length() != 10) {
            tot = "0" + tot;
        }
        diaMesa.add("total", tot);
        JsonObject objLinea = diaMesa.build();
        arrayB.add(objLinea);
        JsonArray arr = arrayB.build();
        obj.add("ventasDiaMesa", arr);
        JsonObject obbbj = obj.build();

        // (Re)Write object
        //   >> Opening of this stream was made too early in original code.
        JsonWriter jR;
        try {
            jR = Json.createWriter(new FileOutputStream(fileName));
            jR.writeObject(obbbj);
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            jR.close();
        }
    } catch (Exception e) {
        // TODO: handle exception
        e.printStackTrace();
    }
}

Мы будем очень признательны, если вы очистите свой код перед его публикацией. Едва читается. Я предлагаю по крайней мере:

  • использовать правильное именование переменных, давая удобочитаемое имя вашим переменным и в CamelCase. Старайтесь действительно избегать одно- и двухбуквенных имен.
  • создавать больше методов
  • помогать дыханию вашего кода
  • создавать меньше бесполезных (одноразовых) переменных или ссылок

Например:

public void cargarVentasDiaMesaJson(Mesas m, double total) {
    String fileName = "C:\\archivos\\VentasDiaMesa.json";

    try {
        JsonArrayBuilder updReadArrayB = Json.createArrayBuilder();

        File file = new File(fileName);
        if (file.exists()) {
            // Try-with-resources: will auto-close JsonReader and inputStream
            //  >> close() of this stream was missing in original code
            try (JsonReader jReader = Json.createReader(new FileInputStream(file))) {
                readPrepareObject(jReader, updReadArrayB);
            } catch (IOException ex) {
                // Cannot read file
                ex.printStackTrace();
            }

            JsonObject outJsonObj = rebuildObject(m, total, updReadArrayB, Json.createObjectBuilder());

            // (Re)Write object
            //   >> Opening of this stream was made too early in original code.
            JsonWriter jWriter;
            try {
                jWriter = Json.createWriter(new FileOutputStream(fileName));
                jWriter.writeObject(outJsonObj);
            } catch (IOException ex) {
                ex.printStackTrace();
            } finally {
                jWriter.close();
            }
        }
    } catch (Exception e) {
        // TODO: handle exception
        e.printStackTrace();
    }
}

private void readPrepareObject(final JsonReader jRe, JsonArrayBuilder arrayB) throws NumberFormatException {
    JsonObject jsonR = jRe.readObject();
    JsonArray array = jsonR.getJsonArray("ventasDiaMesa");

    for (int i = 0; i < array.size(); i++) {
        JsonObject vDiaMesa = array.getJsonObject(i);
        String fecha = vDiaMesa.getString("fecha");
        int numero = vDiaMesa.getInt("numero");
        double tot = Double.parseDouble(vDiaMesa.getString("total"));
        JsonObjectBuilder diaMesa = Json.createObjectBuilder();
        diaMesa.add("fecha", fecha);
        diaMesa.add("numero", numero);
        diaMesa.add("total", tot);

        arrayB.add(diaMesa.build());
    }
}

private JsonObject rebuildObject(Mesas m, double total, JsonArrayBuilder arrayB, JsonObjectBuilder obj) {
    JsonObjectBuilder diaMesa = Json.createObjectBuilder();

    Calendar fecha = Calendar.getInstance();
    String mes = (fecha.get(Calendar.MONTH) + 1) < 10 ? "0" + (fecha.get(Calendar.MONTH) + 1) : "" + (fecha.get(Calendar.MONTH) + 1);
    String dia = fecha.get(Calendar.DATE) < 10 ? "0" + fecha.get(Calendar.DATE) : "" + fecha.get(Calendar.DATE);
    String date = "" + fecha.get(Calendar.YEAR) + mes + dia;
    diaMesa.add("fecha", date);
    String numero = (m.getNumero() < 10) ? "0" + m.getNumero() : "" + m.getNumero();
    diaMesa.add("numero", numero);
    String tot = Double.toString(total);
    while (tot.length() != 10) {
        tot = "0" + tot;
    }
    diaMesa.add("total", tot);
    JsonObject objLinea = diaMesa.build();
    arrayB.add(objLinea);
    JsonArray arr = arrayB.build();
    obj.add("ventasDiaMesa", arr);

    return obj.build();
}

Обратите внимание Я не проверял (и почти не изменял) ваши Json манипуляции инструкции.

И последнее, но не менее важное: не выполняйте длинный блокирующий или связанный с вводом-выводом код в потоке событий AWT. Вы должны использовать ExecutorService для выполнения большей части вашего logi c вне очереди событий AWT.

...