Home » Java_Tricks
Archiv der Kategorie: Java_Tricks
Optional.ofNullable / Optional.map – Mehrstufig hierarchische NOT NULL Abfrage. Anstatt Abfrage auf != NULL
Schritt 1: Erstelle ein Optional auf dem Object auf das du null-wert-sicher zugreifen möchtest:
Optional isOptionallyNull = Optional.ofNullable(instOfClassANotShureIfNull);
Schritt 2: Greife auf Felder (und Child-Felder) zu Obwohl die Instanz selbst (oder ihre Children) ja null sein könnten: Map:
ClassC unterUnterObject = isOptionallyNull .map(ClassA::getSubObjB).map(ClassB::getSubC).orElseGet(ClassC::new)
Wie oben demonstriert können über mehrere Stufen aggregierte Sub-Objekte so abgefragt werden, obwohl man nicht weiss ob Vater- oder Zwischenobjekte NULL sein könnten.
Filtern von Stream-Objekten und Verarbeitung mit dem gefundenen Objekt (–> ifPresent)
if (v1 != null && issuerMap.containsKey(v1)) {
phcCr.setIssuer(issuerMap.get(v1));
}
… kann dasselbe erreicht werden mit:
Optional.ofNullable(v1).filter(value -> issuerMap.containsKey(value))
.ifPresent(value -> phcCr.setIssuer(issuerMap.get(value)));
Fehler: SunCertPathBuilderException: unable to find valid certification path to requested target (SSL handshake)
Fehler:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Lösung
In dem mir vorliegenden Fall musste die ein CA-Certifikat (welches das vom Server vorgezeigte Certifikat beglaubit) in den lokalen Truststore zugefügt werden.
–> Im vorliegenden Fall kann sich der Server nicht beim Caller authentifizieren.
Debugging-Möglichkeit:
-Djavax.net.debug=all
(In der Run-Config z.B. der Tomcat-Instanz)
Das bewirkt, dass interessantes geloggt wird unter: org.apache.cxf.transport.http.HTTPConduit
Auszüge davon:
Die Certificate-Chain
*** Certificate chain chain [0] = [ [ Version: V3 Subject: CN=myserver.hps.com, OU=Server, OU=CA, O=UBS, C=CH ... AuthorityInfoAccess [ [ accessMethod: caIssuers accessLocation: URIName: http://certinfo-http.hps.com/aia/HPS_Server_CA_Test_3.crt ... ] SubjectAlternativeName [ DNSName: hps.alternative.server.com ... ] ] chain [1] = [ [ Version: V3 Subject: CN=HPS Server CA Test 3, OU=CH 027, OU=CA, O=UBS, C=CH ... ]
Unter „AuthorityInfoAccess“ wird für das Certifikat ausgewiesen, durch welches andere Certifikat es beglaubigt ist. Jenes Certifikat ist auch weiter unten noch separat ausgewisen.
Das „SubjectAlternativeName“ weist alterntiven Addressen aus, für welche dieses Zertifikat als „Ausweis“ dienen kann. Alternatife zu jenem, welches in parameter „subject“ definiert ist.
Die folgende Zeile sagt, dann „certificate_unknown„, was darauf hin deutet, dass die CA (HPS Server CA Test 3) (das Ende der oben beschribenen Chain nicht bekannt is. Das heisst sie ist nicht in unserem TrustStore vorhanden.
http-apr-8080-exec-9, SEND TLSv1 ALERT: fatal, description = certificate_unknown
JavaScript in Java einlesen und ausführen
javax.script
Comparator – Schnelles Erstellen
Comparator personaComparator = Comparator.<strong>comparing</strong>(Persona::getAge).<strong>thenComparing</strong>(Persona::getName))
import static org.assertj.core.api.Assertions.assertThat; public class LerneComparator { final static Persona JONA = new Persona(7, "Jona"); final static Persona ZORA = new Persona(11, "Zora"); final static Persona NATASHA = new Persona(22, "Natasha"); final static Persona[] personas = {JONA, ZORA, NATASHA}; public static void main(String[] args) { List<Persona> personList = Arrays.asList(personas); System.out.println("Mit Comparator:"); Collections.sort(personList, Comparator.comparing(Persona::getAge).thenComparing(Persona::getName)); assertThat(personList).containsExactly(JONA, ZORA, NATASHA); System.out.println("Mit Comparator (reverse order):"); Collections.sort(personList, Comparator.comparing(Persona::getAge).thenComparing(Persona::getName).reversed()); assertThat(personList).containsExactly(NATASHA, ZORA, JONA); System.out.println("Mit Comparable Objects: "); Collections.sort(personList); //Persona must implement Comparable-Interface assertThat(personList).containsExactly(JONA, NATASHA, ZORA); } }
Kumulierbare/verknüpfbare Kriterien erstellen mit Hilfe von Functional interfaces/Lambda (Übung) / Fluent Interface / Method Chaining
Java 8 – Lösung:
public interface Specification<T> { default Specification<T> and(Specification spec){ Specification<T> outerSpec = this; return obj -> outerSpec.isSatisfiedBy(obj) && spec.isSatisfiedBy(obj); } boolean isSatisfiedBy(T obj); }
Erklärung:
Eine Spezifikation definiert (in isSatisfiedBy(T obj)) wann sie erfüllt ist.
Die and(..) Methode gibt eine Kombination aus der vorliegenden (this) und der übergebenen Spezifikation zurück.
Aufruf:
import static org.assertj.core.api.Assertions.assertThat; public class Test { public static void main(String[] args) { Specification<String> istHans = s -> s.equals("Hans"); Specification<String> laengeNichtNull = s -> !s.isEmpty(); Specification<String> kombinierteSpezifikation = istHans.and(laengeNichtNull); assertThat(kombinierteSpezifikation.isSatisfiedBy("Hans")) .as("Kombinierte Spezifikation trifft zu").isTrue(); assertThat(kombinierteSpezifikation.isSatisfiedBy("Peter")) .as("Kombinierte Spezifikation trifft nicht auf 'Peter' zu").isFalse(); assertThat(laengeNichtNull.isSatisfiedBy("Peter")) .as("Nur die eine Spezifikation (nicht leer) trifft zu").isTrue(); /** * Spezifikation kann auch anders parametrisiert werden: */ Specification<Integer> groesser7 = i -> i.compareTo(7) > 0; Specification<Integer> istGerade = i -> (i & 1) == 0; assertThat(groesser7.and(istGerade).isSatisfiedBy(8)).isTrue(); assertThat(groesser7.and(istGerade).isSatisfiedBy(9)).isFalse(); assertThat(groesser7.and(istGerade).isSatisfiedBy(6)).isFalse(); } }
Begriffe:
Fluent API: Wenn Aufrufe aneinander gekettet werden können, dass dabei eine natürlich verständliche Aussage wiedergegeben wird, z.B.:
assertThat(laengeNichtNull.isSatisfiedBy("Peter")) .as("Nur die eine Spezifikation (nicht leer) trifft zu").isTrue();
Method Chaining: Verkettung von Methoden-Aufrufen (wie eben gezeigtes Beispiel). Dabei wird oft ein Object derselben Klasse wir das Objekt auf der die Methode aufgerufen wird zurück gegeben:
public class Klasse { ... //Method that allows chaining Klasse addName(String s){ ... } }
Zum Vergleich eine Version ohne Java 8 Fetures:
public interface Specification<T> { Specification<T> and(Specification spec); boolean isSatisfiedBy(T obj); }
Da Default-Methoden als Sprachmittel fehlen wird die Methode and(..) in einer abstrakten Klasse implementiert:
public abstract class SpecificationImpl<T> implements Specification<T> { public Specification<T> and(Specification spec){ Specification<T> outerSpec = this; return new SpecificationImpl<T>() { @Override public boolean isSatisfiedBy(T obj) { return outerSpec.isSatisfiedBy(obj) && spec.isSatisfiedBy(obj); } }; } }
Aufruf:
Die konkreten Spezifikationen müssen (z.B. als anonyme) Klassen ausprogrammiert werden:
public class Test { public static void main(String[] args) { SpecificationImpl<String> istHans = new SpecificationImpl<String>() { @Override public boolean isSatisfiedBy(String s) { return s.equals("Hans"); } }; SpecificationImpl<String> laengeNichtNull = new SpecificationImpl<String>() { @Override public boolean isSatisfiedBy(String s) { return !s.isEmpty(); } }; Specification<String> kombinierteSpezifikation = istHans.and(laengeNichtNull); assertThat(kombinierteSpezifikation.isSatisfiedBy("Hans")) .as("Kombinierte Spezifikation trifft zu").isTrue(); assertThat(kombinierteSpezifikation.isSatisfiedBy("Peter")) .as("Kombinierte Spezifikation trifft nicht auf 'Peter' zu").isFalse(); assertThat(laengeNichtNull.isSatisfiedBy("Peter")) .as("Nur die eine Spezifikation (nicht leer) trifft zu").isTrue(); /** * Spezifikation kann auch anders parametrisiert werden: */ SpecificationImpl<Integer> groesser7 = new SpecificationImpl<Integer>() { @Override public boolean isSatisfiedBy(Integer i) { return i.compareTo(7) > 0; } }; Specification<Integer> istGerade = new SpecificationImpl<Integer>() { @Override public boolean isSatisfiedBy(Integer i) { return (i & 1) == 0; } }; assertThat(groesser7.and(istGerade).isSatisfiedBy(8)).isTrue(); assertThat(groesser7.and(istGerade).isSatisfiedBy(9)).isFalse(); assertThat(groesser7.and(istGerade).isSatisfiedBy(6)).isFalse(); } }
Zum Vergleich nochmals:
< Java 8: | Java 8: Lambda |
---|---|
SpecificationImpl<String> laengeNichtNull = new SpecificationImpl<String>() { @Override public boolean isSatisfiedBy(String s) { return !s.isEmpty(); } }; |
Specification<String> istHans = s -> s.equals("Hans"); |