SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data?

flumex  22.06.2020, 13:38

Kannst du das JSON in die Frage hinzufügen?

irgendeinkerl 
Fragesteller
 22.06.2020, 13:42

Ich habe ja kein JSON. Die geholten Daten aus der Datenbank sollten dann als JSON konvertiert werden. Aber so sollte es aussehen.

{"id":1,"kategorie":"gürtel","oberkategorie":"A"}

2 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Lass dir den Response zunächst unbearbeitet in der Konsole ausgeben.

console.log(xmlhttp.responseText);

Es ist von Interesse, was du wirklich vom Server zurückbekommst.

irgendeinkerl 
Fragesteller
 23.06.2020, 00:30

In der Konsole bekomme ich nichts. Ich denke weil es ein Fehler im Code gibt.

Also jetzt gerade bekomme ich (je nachdem in Welchem browser ich meine Funktion aufrufe) diese Fehlermeldung:

Chrome: Uncaught SyntaxError: Unexpected end of JSON input

   at JSON.parse (<anonymous>)

   at XMLHttpRequest.xmlhttp.onreadystatechang

Firefox: SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data

So wie ich das verstehe bekomme ich also von Meinem Servlet etwas Falsch zurück.

Wenn ich diese Zeile noch mit Einfüge in mein code:

xmlhttp.responseType = "json";

Dann bekomme ich diese Meldung:

Firefox: InvalidStateError: responseText is only available if responseType is '' or 'text'.

Chrome: Kategorie.js:26 Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'text' (was 'json').

0
regex9  23.06.2020, 02:05
@irgendeinkerl

Die Fehler im Browser sind ziemlich irrelevant, denn die beziehen sich lediglich darauf, dass der Response nicht als JSON geparst werden kann. Das hat dir schon der erste Fehler deutlich genug gemacht. Wie gesagt, ist eher von Interesse, was der Server zurückgibt bzw. jetzt, was die Serveranwendung macht.

Wenn ich mir deine Servlet-Implementation anschaue, fällt mir auf, dass du weder Daten in den Response Body schreibst noch auf eine JSP weiterleitest. Es ist also nicht verwunderlich, dass die Ausgabe von responseText in der Browserkonsole eine leere Ausgabe zurückgibt.

Bau dir also erst einmal einen JSON-String im Servlet zusammen (es gibt genügend Bibliotheken, die dir dabei helfen können) und schreibe diesen dann in den Response Body.

// doGet:

// build json string from result ...

response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");

PrintWriter writer = response.getWriter();
writer.print(resultJson);
writer.flush();

Ein einfaches, konkretes Beispiel wird auch auf Baeldung gezeigt: https://www.baeldung.com/servlet-json-response

Prüfe danach nochmals den Inhalt von responseText.

0
irgendeinkerl 
Fragesteller
 23.06.2020, 09:18
@regex9

Ah ja klar macht Sinn. Ich habe dann etwas falsch verstanden aus dem Skript. Gut also für die Logs bekomme ich jetzt mit dem Code folgende ausgabe.

Jetzt muss ich nur noch herausfinden wie ich statt "test1" die daten aus dem ArrayList holen kann ohne Bibliotheken zu benutzen.

Vielen Dank! :)

        String resultJson = Json.createObjectBuilder()
                .add("id", "test1")
                .add("kategorie", "asdf")
                .add("oberkategorie","asdf")
                .build()
                .toString();

{"id":"test1","kategorie":"asdf","oberkategorie":"asdf"}

asdf

test1

asdf

0
irgendeinkerl 
Fragesteller
 23.06.2020, 12:09
@irgendeinkerl

Also mein doGet sieht jetzt folgendermaßen aus.

    response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");

        String resultJson = Json.createObjectBuilder()
                .add("id", kategorien.get(0).toString())
                .add("kategorie", kategorien.get(1).toString())
                .add("oberkategorie", kategorien.get(2).toString())
                .build()
                .toString();  
        

       // String gson = new Gson().toJson(kategorien);
        PrintWriter writer = response.getWriter();
        writer.print(resultJson);
        writer.flush();

Ich habe versucht die Kategoie.get(0) zu eine JsonValue zu casten aber mein Bean hat dann gemeckert, dass es keine Json values annehmen kann. Ich nutze also toString. Allerdings gibt es da ein kleines Problem. In meinem Browser kommen jetzt diese Adressen an statt daten.

{"id":"Beans.KategorieBean@278a2b2e","kategorie":"Beans.KategorieBean@546e78e6","oberkategorie":"Beans.KategorieBean@76f96338"}

Beans.KategorieBean@546e78e6

Beans.KategorieBean@278a2b2e

Beans.KategorieBean@76f96338

Eine idee wie ich das beheben könnte? :D

0
regex9  23.06.2020, 13:19
@irgendeinkerl

Du versuchst KategorieBean-Objekte zu Strings zu konvertieren. Das Standardverhalten von Java ist in dem Fall, den internen Typnamen (wie er in der VM gehandhabt wird) zurückzugeben.

Du brauchst eine eigene toString-Methode für deine Klasse.

Beispiel:

class Person {
  string firstname;
  string lastname;

  @Override
  public String toString() {
    return String.format("%s %s", firstname, lastname);
  }
}
0
irgendeinkerl 
Fragesteller
 23.06.2020, 16:25
@regex9

Aaaah. Jetzt verstehe ich auch wieso das genau so ausgegeben wurde.

The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:

Jetzt funktioniert es. Vielen Dank :)

0

Dein Servlet gibt also den folgenen JSON-String zurück:

{"id":1,"kategorie":"gürtel","oberkategorie":"A"}

Ich meinem Beispiel habe ich dafür jetzt eine JSON-Datei verwendet:

function pupulateDropDown() {
    const servletURL = "test.json";
    let xmlHttpRequest = new XMLHttpRequest();

    xmlHttpRequest.onreadystatechange = function () {
        if (xmlHttpRequest.readyState === 4 && xmlHttpRequest.status === 200) {

            let katGetter = JSON.parse(xmlHttpRequest.responseText);
            JSON.stringify(katGetter);

            document.getElementsByClassName("innerDiv").innerHTML = "<a href=" + "DisplayKlamotten" + "?=" + katGetter.kategorie + ">" + katGetter.kategorie + "</a>";

            console.log(xmlHttpRequest.responseText);
            console.log(katGetter.kategorie);
            console.log(katGetter.id);
            console.log(katGetter.oberkategorie);

        }
    };
    xmlHttpRequest.open("GET", servletURL, true);
    xmlHttpRequest.send();
}

pupulateDropDown();

Funktioniert einwandfrei. Dann scheint dein Servlet nicht richtig zu funktionieren. Ich habe deinen Code ein wenig angepasst und ein paar Typos gefixt.

Bild zum Beitrag

Alles richtig gemacht, jetzt bitte dein Servlet checken.

 - (JavaScript, JSON)
irgendeinkerl 
Fragesteller
 23.06.2020, 00:38

Ich habe gelesen, dass meine function "json" erwartet aber es bekommt ein "text" und deswegen geht es nicht. Das hat mich etwas durcheinander gebracht denn wenn ich im Browser die Funktion aufrufe diese Fehlermeldung kommt:

Chrome: Kategorie.js:26 Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'text' (was 'json').

Also genau der gegenteil. Ich habe nach Lösungen gesucht aber alle benutzen irgendwelche Externe Libraries und die darf ich wie gesagt nicht nutzen.

Die Letzte Lösung welche ich gefunden habe meinte ich soll meine Liste in ein JSONArray umwandeln. Das habe ich versucht aber bei der Hälfte habe ich gemerkt, dass dies auch nicht gehen wird ohne Externe libraries.

Hier ist mein Servlet vielleicht hast du ja eine Idee die ich versuchen könnte :D

    @Resource(lookup = "java:jboss/datasources/MySqlHHHdbDS")
    private DataSource ds;

    public KategorienHolen() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    //    pickedKategorie = request.getParameter("pickedKategorie");

        List<KategorieBean> kategorien = displayKat();

        HttpSession session = request.getSession();
        session.setAttribute("kategorie", kategorien);

        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");

    }

    public List<KategorieBean> displayKat() throws ServletException {

            List<KategorieBean> k = new ArrayList<KategorieBean>();

            try (Connection con = ds.getConnection();
                    PreparedStatement pstmt = con.prepareStatement("SELECT * FROM accessoireskategorie")) {

                try (ResultSet rs = pstmt.executeQuery()) {

                    while (rs.next()) {

                        KategorieBean katBean = new KategorieBean(); // bean wird bei jedem treffer erzeugt

                        // get --> belegt die bohnen

                        katBean.setId(rs.getInt("id"));
                        katBean.setKategorie(rs.getString("kategorie"));
                        katBean.setOberK(rs.getString("oberK"));

                        k.add(katBean); // bohnen in ArrayList hinzufügen.
                        
                    }
                }
            } catch (Exception ex) {
                throw new ServletException(ex.getMessage());
            }

            return k;

    }
0