SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data?
Hallo,
ich versuche mit JavaScript Daten über ein Servlet aus der Datenbank zu holen. In folgende Zeile bekomme ich die Fehlermeldung aus dem Titel:
var katHoler = JSON.parse(xmlhttp.responseText);
Ich habe gelesen, dass meine Funktion eine JSON erwartet. Aber ich habe nur Lösungen mit Libraries wie jQuery gefunden. Die darf ich aber von meinem Professor aus nicht benutzen.
function pupulateDropDown() {
var servletURL = "./KategorienHolen"
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var katHoler = JSON.parse(xmlhttp.responseText);
JSON.stringify(katHoler);
var ausgabe = "<a href=" + "DisplayKlamotten" + "?=" + katHoler.kategorie + ">" + katHoler.kategorie + "</a>";
document.getElementsByClassName("innerDiv").innerHTML = ausgabe;
console.log(xmlhttp.responseText);
console.log(katHoler.kategorie);
console.log(katHoler.id);
}
}
xmlhttp.open("GET", servletURL, true);
xmlhttp.send();
}
Kannst du das JSON in die Frage hinzufügen?
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
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.
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.
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
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
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);
}
}
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 :)
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.
Alles richtig gemacht, jetzt bitte dein Servlet checken.
![- (JavaScript, JSON)](https://images.gutefrage.net/media/fragen-antworten/bilder/355610859/0_big.png?v=1592826817000)
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;
}
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:
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').