AJAX/RestController Post Problem

Diskutiere AJAX/RestController Post Problem im Web Tier Bereich.
S

Sternenregen

Grüße euch,

Ich bin hart genervt. Sitze seit über 8 Stunden ab den Mist und ich komm nicht weiter. Ich hab schon so viele Dinge probiert, dass ich das hier gar nicht alles aufzählen kann. Es ist bestimmt irgend ein grundlegender Fehler.

Ich will über ein HTML Dokument ein AJAX Skript aufrufen, dass einen simplen String an einen Restcontroller @POST/PUT schicken soll. Der entsprechende Methode wird auch getriggert, allerdings ist der übergebene String IMMER null. Ich habe Postman genommen. Dort kommt der String an und wird verarbeitet. Das sagt mir, dass es am AJAX Script bzw dem HTML Teil liegt.

Die Forms performen ja in der Regel nur ein GET und kein POST. Daran wirds irgendwie liegen. Aber ich weiß nicht mehr weiter. Hab komplett Google umgegraben. Ich habe viele LÖsungen gefunden. Muss gestehen, ich arbeite jetzt das erste mal mit AJAX bzw Javascript im Allgemeinen so richtig.


Zur Erklärung: "operator" ist der Parameter der in dem RestController erwartet wird.



Hier die AJAX Function und der HTML Teil. Der RestController tut was er soll.

d1.PNG

Und hier der relevante HTML Teil:

Code:
    <div id="formDiv">
        <form id="form" method="post">
            <input type="text" id="display">
           
                <div class="batteryBlock">      
                    <table>
                        <tr>                          
                            <td><button type="submit" onClick="test()" id="bat" class="btnNum"  value = "+">+</button></td>          
                        </tr>





Erlöst mich bitte.
 
Thallius

Thallius

mach mal Type=„Button“. ehrlich gesagt habe ich keine Ahnung was passiert wenn du submit und onClick gleichzeitig benutzt aber der submit müßte eigentlich einen Page reload Auslösen was sicherlich nicht gewollt ist
 
mrBrown

mrBrown

Der content-type sieht zumindest schräg aus, was sendet der Browser da denn genau?
 
S

Sternenregen

Selbst von diesem AJAX-Script, hatte ich schon unzählige Versionen davon. Meine Content-Types u.a. so aus: text/plain, text, 'application/x-www-form-urlencoded'
usw... Und sogar laut Dokumentation komplett weggelassen, da letzteres eigentlich auch der default Wert ist.

Hab aber mal einen Script Validator drüberlaufen lassen, der monierte da @action("url...."). Hab jetzt nur url: "localhost:8080" dortstehen.

Der content-type sieht zumindest schräg aus, was sendet der Browser da denn genau?
Ich habe einen RestController. In meinem speziellen POST Methode gibt es keinen Pfad sondern nur ein Parameter der verlangt wird. Wenn ich es nicht verwechsel (Hab in dem Gebiet erst vor 4 Tagen begonnen) ist es ja glaub ich da der Vorteil dass die URL gleich bleibt.

Ich hoffe es gibt vom Ergebnis einen Unterschied zwischen
Code:
 var muell = { "operator": "umpalumpa" }
und
Code:
 data: {"operator": "umpalumpa"},
Was ich bisher gelesen habe, ist der erste Wert, der Parametername und der zweite (umpalumpa), der Wert, der darin gespeichert werden soll.
Falls dem nicht so ist, hab ich den Fehler gefunden. Weil ansonsten wird ja nur das object ausgegeben und ich müsste es ähnlich wie bei JSON stringifyen :) Aber da der DataType nur "text" ist...


Wie kann ich denn testen was bei einem ajax-Script versendet wird? Hab versucht in das Script sowie in der Success bzw Error ein Alert einzubauen. Aber das wird nicht aufgerufen. Das sagt mir eigentlich dass der Fehler vor dem Success: sein muss. Aber wie gesagt. ich hab schon alles erdenkliche ausprobiert.

Trotz allen hab ich das data: im Verdacht.
 
sascha-sphw

sascha-sphw

Den Request kannst Du Dir im Browser in den Dev-Tools Anschauen. F12 (Chrome, Firefox, IE, Edge) da findest Du dann einen Bereich in dem die ganzen Requests angezeigt werden. HINT: erst Dev-Tools öffnen, dann Request absetzen.

Wie erwartest Du denn die Daten am RestController? Passend dazu musst Du sie über JS abschicken.
 
sascha-sphw

sascha-sphw

Über Insomnia kann man sich das JavaScript eines Requests generieren lassen. Ich kann mir gut vorstellen, dass Postman das auch kann.
 
S

Sternenregen

Wie erwartest Du denn die Daten am RestController? Passend dazu musst Du sie über JS abschicken.
Der RestController erwartet an der Stelle einen String.

So sieht der Methodenkopf aus:
Code:
public String setTest(@RequestParam(required=false) String operator)
Ich hab jetzt mal in Chrome nachgeschaut. Die Request Methode ist auf jeden Fall POST. Aber die Content-Länge ist 0. Sowohl beim Request wie auch bei der Response. Aber das zeigt mir auch die JavaConsole an, dass der String null ist.

Die Frage ist warum.

Achja und Postman hab ich schon genutzt. Das Post funktioniert und die Werte werden auch übertragen. Das sagt mir persönlich, dass das Problem bei dem data: liegt bzw an der Stelle, wo in dem AJAX der Text übergeben wird.

Aktuell sieht das Skript so aus:


Code:
function test(){
        
        alert("springe in ajax funktion");   
        
         $.ajax({
                url: "localhost:8080",
                type: "POST",
                dataType: 'text',
                data: { 'operator': 'foooooo'},
                cache: false,
                              
                success: function (data) {                   //Springt nicht rein
                    alert("Es funktioniert endlich");
                },
              
                error: function(data){                       //Springt nicht rein
                    alert("Es geht nicht, aber es läuft");
                }
            });   
        
         alert("muh");                                      //Springt nicht rein
    }
 
Thallius

Thallius

Also für mich ist das kein String sondern ein JSON. Von daher würde ich es ganz blöd mal mit datatype: "json" probieren. Weiterhin finde ich es befremdlich, dass die URL der Root ist. Normalerweise nimmt man hier eine URL die den Namen der API Methode enthält. Also Localhost:8080/setUser oder sowas. Weiterhin adde doch mal

Code:
.done(function() { console.log("Done"); } );
zum request hinzu. Vielleicht wird das ja aufgerufen
 
mrBrown

mrBrown

Also für mich ist das kein String sondern ein JSON. Von daher würde ich es ganz blöd mal mit datatype: "json" probieren.
dataType ist der Typ, den man vom Server zurück bekommt. Ist in diesem Fall String, text ist also völlig richtig.


Weiterhin finde ich es befremdlich, dass die URL der Root ist. Normalerweise nimmt man hier eine URL die den Namen der API Methode enthält. Also Localhost:8080/setUser oder sowas
Eine Methode in der URL stehen zu haben ist eigentlich das genaue Gegenteil von üblich – das gilt bei Rest als ziemliches Antipattern.
Da der Controller auch aufgerufen wird, scheint die URL korrekt zu sein.
 
S

Sternenregen

OMG.

Jetzt gehts. Nach der url hat ein / gefehlt. Also localhost:8080/.

Ich dachte immer und machte immer localhost:8080?operator=fooo

10 Stunden wegen einem Schrägstrich.

!!

Aber das Ganze offenbart mir, dass ich den Part mit dem data: offenbar doch nicht so ganz verstanden habe.

Es hatte jetzt funktioniert weil ich in die URL:
Code:
   url: "localhost:8080/?operator=fooo",
Aber ist nicht gerade der Sinn von data: den Parameternamen und den Wert zu übermitteln? Hab es grad getestet.
Code:
localhost:8080/?
data: { 'operator':'foooooo'},
geht auch nicht. Ich hatte mir Dokumentation angeschaut und hatte das so rausgelesen.
 
Zuletzt bearbeitet:
mrBrown

mrBrown

Moment – ohne slash wird der Request zwar gesendet, aber der Body ist leer, und mit slash ist der Body dann gefüllt?
 
S

Sternenregen

Jap. So siehts aus.

Ich dachte die ganze Zeit

localhost:8080?operator=fooo == url:"localhost:8080", data: { 'operator':'foooooo'}

Aber beides ging nicht.

localhost:8080/?operator=foo


läuft
 
Zuletzt bearbeitet:
S

Sternenregen

Ich hab mir jetzt nochmal die offizielle Dokumentation angeschaut: https://api.jquery.com/jquery.ajax/
Ich erkenne keinen Fehler.

Laut Doku:
data: { 'operator':'foooooo'} = operator=foooooo

Gut, wenn man danach geht, fehlt ja noch das Fragezeichen. Und nimmt man noch das / dazu, müsste es ja theoretisch in der Kombination
ja hinhauen:

localhost:8080/?
data: { 'operator':'foooooo'}


Tut es aber nicht. Woran liegt das? Der Fehler muss daher im data: liegen. Ich will das verstehen. Weiß das jemand?
 
S

Sternenregen

Ja, aber warum wird das nicht berücksichtigt? Der RestController/POST/PUT wird ja getriggert und die Anfrage kommt an. Warum nicht der Inhalt?

Es ist wie du sagst, ein POST-Request. Und ich habe den Parameter und den Wert mit angegeben.
Das data: { 'operator':'foooooo'} müsste ja im Body stehen. Oder versteh ich das falsch.

Ich glaub das Ganze resultiert daraus, dass das GET Request eher abgefeuert wird als das AJAX. Und deswegen ist es immer null. Ich guck mal. Da gibt es ja etwas, um dieses zu unterbinden. Wenn es funzt, schreibe ich es hierher.
 
Zuletzt bearbeitet:
sascha-sphw

sascha-sphw

Ja, aber warum wird das nicht berücksichtigt? Der RestController/POST/PUT wird ja getriggert und die Anfrage kommt an. Warum nicht der Inhalt?
Der Inhalt kommt wahrscheinlich im Body auch an, nur wird er von Deinem Service nicht ausgewertet, die Annotation @RequestParam steht für einen Query oder einen Form Parameter. Wenn ich mich nicht irre.

Versuchs mal so:
Javascript:
$.ajax({
  "url": "http://localhost:8080/",
  "method": "POST",
  "headers": {
    "content-type": "application/x-www-form-urlencoded"
  },
  "data": {
    "operator": "fooo"
  }
}).done(function (response) {
  console.log(response);
});
Wenn Du den Body auswerten möchtest, sollte im Controller sowas stehen.
Java:
public class MyDto {
    private String operator;
   
    // getters setter omitted
}

@PostMapping
public String setTest(MyDto dto) { ... }
Und dann mit JS:
Javascript:
$.ajax({
  "url": "http://localhost:8080/",
  "method": "POST",
  "headers": {
    "content-type": "application/json"
  },
  "processData": false,
  "data": JSON.stringify({
      operator: "fooo"
  })
}).done(function (response) {
  console.log(response);
});
PS: Code nicht getestet, es könnten also Fehler enthalten sein.
 
mrBrown

mrBrown

Der Inhalt kommt wahrscheinlich im Body auch an, nur wird er von Deinem Service nicht ausgewertet, die Annotation @RequestParam steht für einen Query oder einen Form Parameter. Wenn ich mich nicht irre.
application/x-www-form-urlencoded ist der default, und zumindest in der letzten Variante hier im Thread ist nichts anderes angegeben, es sollte also ganz normal als Form-Daten gesendet werden.
 
mrBrown

mrBrown

Habs grad extra getestet, dieser Request funktioniert völlig Problemlos:

Javascript:
$.ajax({
    url: "http://localhost:8080",
    type: "POST",
    data: {'operator': 'foooooo'},
    success: function (data) {
        alert("Es funktioniert endlich: " + data);
    }
});
Und auf Spring-Seite einfach nur ein @PostMapping("/") @ResponseBody public String test(@RequestParam String operator)


OMG.

Jetzt gehts. Nach der url hat ein / gefehlt. Also localhost:8080/.
Mit Chrome und jQuery 3.1.1 produzieren "http://localhost:8080" und "http://localhost:8080/" genau den gleichem Request, der Slash am Ende ist da völlig egal.
 
Thema: 

AJAX/RestController Post Problem

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben