Ich nehme derzeit an einer Akademie zum Java Fullstack Software Engineer teil. In den kommenden Wochen möchte ich hier meine Mitschrift, so gut es geht, aufzeichnen und mitteilen. Hier ist das, was ich vom zweiten Tag in Block 7 gelernt und behalten habe:
Web App Security
Top Ten Web App Security Risiken:

Cross Site Scripting bedeutet Code vom Drittanbieter auf meiner Seite, z.B. durch Werbung. @CrossOrigin erlaubt den Zugriff von anderen Domänen.


Design Pattern Model View Control (MVC)
DTO - Data Transfer Objekt - Schnittstelle zwischen Service und Controller
DAO - Data Access Objekt - Schnittstelle zwischen Service und Datenbank
@Entity verbrennt/kontaminiert ein Objekt für das Repository. Damit die Klasse an den Controller übergeben werden kann, brauchen wir das DTO.

Wenn ich @Responsebody nicht an die Klasse setze, muss ich es an die Methoden setzen, ansonsten wird der Body für die entsprechenden Methoden nicht zurückgegeben:

Wenn wir anstelle des @Controller den @RestController verwenden, brauchen wir @Responsebody nicht mehr, weil er im @RestController enthalten ist.
Wir bauen auch jetzt schon mal @CrossOrigin(origins = "*") ein. Es geht dabei um CrossSiteScripting und wir werden es später (bei Webservices) tiefer erklären.

--> Kleiner Exkurs: Fehler bei der Erstellung der Applikation:
Sollte man mal aus versehen das falsche Package erstellt haben (also das Projekt aus versehen eine Ebene zu tief eingebaut haben), kann man z.B. mit @ComponentScan das Package angeben, wo Spring die Beans rekursiv suchen soll:

<-- Ende Exkurs
Uebung ueb02-kehrwertservice
- Controller(RestController)
- Service: Der macht die Kehrwertberechnung 1/n (in einer Utility Klasse)
- Readme-Datei erstellen
- Testen mit
- Curl
- Postman

Wir öffnen das gedownloadete und ausgepackte Jar-File mit Eclipse.
Wir setzen den Port in application.properties:

Wir bauen ein Interface:

Und implementieren es in unserer Klasse, wo der Kehrwehrt tatsächlich berechnet wird:

Wir erstellen den Controller, damit die Logik von außen erreicht werden kann:

Und so sieht das Ergebnis aus:

Wenn ich etwas anderes als eine Zahl eingebe, erhalte ich eine Fehlermeldung Status=400, Error="Bad Request":

Auch im Log steht etwas:
2022-01-25 11:09:13.700 WARN 26176 --- [io-8099-exec-10] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'double'; nested exception is java.lang.NumberFormatException: For input string: "ABC"]
Im Postman sieht die Anfrage wie folgt aus:

Man kann auch den Header beeinflussen. Im curl haben wir Accept / in text/plain umgewandelt:

Mit Postman kann man den Header gut manipulieren:

Mit Pragma und Cache-Control schalten wir die Proxies ab (also löschen die Chaches und laden direkt vom Server):

Das geht natürlich auch mit curl:

curl-Parameter:

Bei Postman steht im oberen Feld der Client-Request und im unteren die Server Response. In beiden Fällen wird, hier durch die Auswahl, der Body gezeigt, der bei einer GET-Anfrage leer ist:

Uebung ueb03-kreisservice
- Controller(RestController)
- Service (Kreis-Berechnung: Interface und Implementierung für Flaeche, Umfang)
- Testen
- curl
- Postman
Hier unsere funktionierende Lösung:


Application.properties:
server.port=8099
Interface KreisRechner.java:
package de.firma.services;public interface KreisRechner {
public double flaeche (double radius);public double umfang (double radius);
}
Klasse KreisrechnerImpl.java
package de.firma.services;import org.springframework.stereotype.Service;
@Service
public class KreisRechnerImpl implements KreisRechner{@Override public double flaeche (double radius){ return Math.PI*Math.pow(radius,2); } @Override public double umfang (double radius){ return 2*Math.PI*radius; }
}
KreisrechnerController.java:
package de.firma.controller;import de.firma.services.KreisRechner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@CrossOrigin(origins = "*")
@RequestMapping("/kreisrechner")public class KreisRechnerController {
@Autowired
KreisRechner kreisRechner;@GetMapping("/flaeche") //http://localhost:8099/kreisrechner/flaeche?zahl=42 public double flaeche (@RequestParam double zahl){ return kreisRechner.flaeche(zahl); } @GetMapping("/umfang") //http://localhost:8099/kreisrechner/umfang?zahl=42 public double umfang (@RequestParam double zahl){ return kreisRechner.umfang(zahl); }
}
Ueb03KreisserviceApplication.java:
package de.firma;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Ueb03KreisserviceApplication {public static void main(String[] args) { SpringApplication.run(Ueb03KreisserviceApplication.class, args); }
}
MVC am Beispiel Projekt kap0101-jaxrs
Man kann Request-Mapping noch mehr Parameter übergeben. Neben value benutzen wir hier method und produces. Bei letzterem können wir die Medientypen definieren:

JPA (Java Persistence API) - In Richtung Datenbank
DTO (Data Transfer Objekt) - In Richtung WebService

Im Prinzip sind die folgenden drei Empoyee-Klassen gleich, sie werden aber, je nach Richtung kontaminiert:

Da der Client *.* akzeptiert, liefert der Server das Json Format, da es an der ersten Stelle steht:

Jetzt ändern wir den Header und sagen, dass unser Content Typ XML sein soll:

Wenn ich etwas wünsche, z.B. Plain/Text, was der Server nicht unterstützt, gibt es die Fehlermeldung 406:

Wenn im Server nichts definiert wird, ist Json das Default-Format für Objekte. Für primitive Daten ist es plain Text.
Hier noch mal, wie man einstellt, dass nur xml zurückgegeben wird:

Bei einem Post, kann der Client über @RequestBody Dateninhalt an den Server übergeben:

Dazu muss mit dem "Consumer" definiert werden, welche Formate der Server versteht:

Hochgeladen wird der Datensatz wie folgt:
curl -v -X POST http://localhost:8080/employee -H "Content-Type:application/json" -d "{\"empNo\":\"E04\",\"empName\":\"King\",\"position\":\"President\"}"

In Postman schicke ich die Daten wie folgt an den Server:

Der Body sieht so aus:

Hier noch Update und Delete:

Update:

Delete:

Hier mal die Liste aller CRUD Befehle für unser Projekt kap0101-jaxrs:

Disclaimer
Alles was ich mitschrieb und verstanden habe ist ohne Gewähr. Die Bilder stammen teilweise aus dem Internet und wir haben keine Urheberansprüche darauf.
Besten Dank an unseren sehr empfehlenswerten
Trainer: Hans-Joachim Blanke blanke@4point.de

In den nächsten Tagen und Wochen geht’s weiter, so: stay tuned!
Gruß, Achim Mertens
Notiz für mich selber:
curl -s --data '{"jsonrpc":"2.0", "method":"condenser_api.lookup_account_names", "params":[["achimmertens"]], "id":1}' https://api.hive.blog