REST jezik upita - Implementacija ILI Operacija

OSTALO Vrh

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ Ovaj je članak dio serije: • REST jezik upita s proljetnim i JPA kriterijima

• REST jezik upita s Spring Data JPA specifikacijama

• REST jezik upita s Spring Data JPA i Querydsl

• REST jezik upita - Napredno pretraživanje

• REST jezik upita - Implementacija ILI operacija (trenutni članak) • REST jezik upita s RSQL-om

• OSTALI jezik upita s web podrškom Querydsl

1. Pregled

U ovom ćemo kratkom članku proširiti napredne operacije pretraživanja koje smo implementirali u prethodnom članku i uključiti ih Kriteriji pretraživanja utemeljeni na ILI u našem jeziku upita REST API.

2. Pristup provedbi

Prije su svi kriteriji u traži parametar upita formirani predikati grupirani samo po operatoru AND. Promijenimo to.

Morali bismo biti u mogućnosti implementirati ovu značajku ili kao jednostavnu, brzu promjenu postojećeg pristupa ili novu od nule.

Jednostavnim pristupom označit ćemo kriterije kako bismo naznačili da se oni moraju kombinirati pomoću operatora OR.

Na primjer, ovdje je URL za testiranje API-ja na “ime ILI prezime ":

// localhost: 8080 / users? search = firstName: john, 'lastName: doe

Imajte na umu da smo označili kriterije prezime s jednim citatom kako bi se to razlikovalo. Snimit ćemo ovaj predikat za operater OR u naš objekt vrijednosti kriterija - Kriteriji pretraživanja spec:

javni SpecSearchCriteria (String orPredicate, String key, SearchOperation operation, Object value) {super (); this.orPredicate = orPredicate! = null && iliPredicate.equals (SearchOperation.OR_PREDICATE_FLAG); this.key = ključ; this.operation = operacija; this.value = vrijednost; }

3. UserSpecificationBuilder Poboljšanje

Sada, izmijenimo naš graditelj specifikacija, UserSpecificationBuilder, razmotriti ILI kvalificirane kriterije prilikom izrade Specifikacija:

javna specifikacija build () {if (params.size () == 0) {return null; } Rezultat specifikacije = nova korisnička specifikacija (params.get (0)); za (int i = 1; i <params.size (); i ++) {rezultat = params.get (i) .isOrPredicate ()? Specification.where (rezultat) .ili (nova UserSpecification (params.get (i))): Specification.where (rezultat) .i (nova UserSpecification (params.get (i))); } vratiti rezultat; }

4. UserController Poboljšanje

Konačno, postavimo novu REST krajnju točku u našem kontroleru da bismo koristili ovu funkciju pretraživanja s operatorom OR. Poboljšana logika raščlanjivanja izdvaja posebnu zastavicu koja pomaže u identificiranju kriterija s operatorom OR:

@GetMapping ("/ users / espec") @ResponseBody javni popis findAllByOrPredicate (traženje niza @RequestParam) {Specifikacija specifikacija = razriješiSpecifikacija (pretraživanje); return dao.findAll (spec); } zaštićena specifikacija resolSpecification (String searchParameters) {UserSpecificationsBuilder builder = new UserSpecificationsBuilder (); String operationSetExper = Joiner.on ("|") .join (SearchOperation.SIMPLE_OPERATION_SET); Uzorak uzorka = Pattern.compile ("(\ p {Punct}?) (\ w +?) (" + OperationSetExper + ") (\ p {Punct}?) (\ w +?) (\ p { Točnost}?), "); Podudaranje podudaranja = pattern.matcher (searchParameters + ","); while (matcher.find ()) {builder.with (matcher.group (1), matcher.group (2), matcher.group (3), matcher.group (5), matcher.group (4), matcher. skupina (6)); } return builder.build (); }

5. Test uživo sa ILI Stanje

U ovom primjeru testiranja uživo, s novom API završnom točkom, tražit ćemo korisnike prema imenu "john" ILI prezimenu "doe". Imajte na umu taj parametar prezime ima jedan navodnik, što ga kvalificira kao „ILI predikat“:

privatni niz EURL_PREFIX = "// localhost: 8082 / spring-rest-full / auth / users / espec? search ="; @Test javna praznina givenFirstOrLastName_whenGettingListOfUsers_thenCorrect () {Response response = givenAuth (). Get (EURL_PREFIX + "firstName: john, 'lastName: doe"); Rezultat niza = response.body (). AsString (); assertTrue (result.contens (userJohn.getEmail ())); assertTrue (result.contens (userTom.getEmail ())); }

6. Test postojanosti sa ILI Stanje

Izvršimo sada isti test kao i gore, na razini trajnosti za korisnike s imenom "john" ILI prezimenom "srna":

@Test javna praznina givenFirstOrLastName_whenGettingListOfUsers_thenCorrect () {BuildSpecificationsBuilder builder = new UserSpecificationsBuilder (); SpecSearchCriteria spec = new SpecSearchCriteria ("firstName", SearchOperation.EQUALITY, "john"); SpecSearchCriteria spec1 = novi SpecSearchCriteria ("'", "lastName", SearchOperation.EQUALITY, "doe"); Popis rezultata = spremište .findAll (builder.with (spec) .with (spec1) .build ()); assertThat (rezultati, hasSize (2)); assertThat (userJohn, isIn (rezultati)); assertThat (userTom, isIn (rezultati)); }

7. Alternativni pristup

U alternativnom pristupu, upit za pretraživanje mogli bismo pružiti više kao cjelovit GDJE klauzula SQL upita.

Na primjer, ovdje je URL za složenije pretraživanje po ime i dob:

// localhost: 8080 / users? search = (firstName: john ILI firstName: tom) I dob> 22

Imajte na umu da smo razdvojili pojedinačne kriterije, operatore i zagrade za grupiranje razmakom kako bismo oblikovali valjani infix izraz.

Analizirajmo izraz infiksa s a CriteriaParser. Naše CriteriaParser dijeli dati infiksni izraz na tokene (kriteriji, zagrade, I & ILI operatori) i stvara izraz postfiksa za isti:

javni Deque parse (String searchParam) {Deque output = novi LinkedList (); Deque stog = novi LinkedList (); Arrays.stream (searchParam.split ("\ s +")). ForEach (token -> {if (ops.containsKey (token)) {while (! Stack.isEmpty () && isHigerPrecedenceOperator (token, stack.peek () )) {output.push (stack.pop (). equalsIgnoreCase (SearchOperation.OR_OPERATOR)? SearchOperation.OR_OPERATOR: SearchOperation.AND_OPERATOR);} stack.push (token.equalsIgnoreCase (SearchOperation.OR_OPERATOR)? SearchOperation.OR_OPERATION.OPERATION.OPERATION.OR_OPERATION.OR_OPERATION.OPERATION.OPERATION.OPERATOR );} else if (token.equals (SearchOperation.LEFT_PARANTHESIS)) {stack.push (SearchOperation.LEFT_PARANTHESIS);} else if (token.equals (SearchOperation.RIGHT_PARANTHESIS)) {while (! stack.peek (). jednako ( SearchOperation.LEFT_PARANTHESIS)) {output.push (stack.pop ());} stack.pop ();} else {Matcher matcher = SpecCriteraRegex.matcher (token); while (matcher.find ()) {output.push ( novi SpecSearchCriteria (matcher.group (1), matcher.group (2), matcher.group (3), matcher.group (4), matcher.group (5)));}}}); while (! stack.isEmpty ()) {output.push (stack.pop ()); } povratni izlaz; }

Dodajmo novu metodu u naš graditelj specifikacija, GenericSpecificationBuilder, za konstrukciju pretraživanja Specifikacija iz izraza postfiksa:

 izgradnja javnih specifikacija (Deque postFixedExprStack, funkcija pretvarač) {Deque specStack = novi LinkedList (); while (! postFixedExprStack.isEmpty ()) {Objekt mayBeOperand = postFixedExprStack.pollLast (); if (! (MayBeOperand instance of String)) {specStack.push (converter.apply ((SpecSearchCriteria) mayBeOperand)); } else {Specifikacija operand1 = specStack.pop (); Specifikacija operand2 = specStack.pop (); if (mayBeOperand.equals (SearchOperation.AND_OPERATOR)) {specStack.push (Specification.where (operand1) .and (operand2)); } else if (mayBeOperand.equals (SearchOperation.OR_OPERATOR)) {specStack.push (Specification.where (operand1) .or (operand2)); }}} vrati specStack.pop ();

Napokon, dodajmo još jednu REST krajnju točku u naš UserController kako bi raščlanio složeni izraz s novim CriteriaParser:

@GetMapping ("/ users / spec / adv") @ResponseBody javni popis findAllByAdvPredicate (traženje niza @RequestParam) {Specifikacija specifikacija = RiješiSpecificationFromInfixExpr (pretraživanje); return dao.findAll (spec); } zaštićena specifikacija razlučivostFromInfixExpr (String searchParameters) {CriteriaParser parser = new CriteriaParser (); GenericSpecificationsBuilder specBuilder = novi GenericSpecificationsBuilder (); vrati specBuilder.build (parser.parse (searchParameters), UserSpecification :: novo); }

8. Zaključak

U ovom uputstvu poboljšali smo jezik upita za REST s mogućnošću pretraživanja pomoću operatora OR.

Potpuna provedba ovog članka može se naći u projektu GitHub. Ovo je projekt zasnovan na Mavenu, pa bi ga trebalo lako uvesti i pokrenuti kakav jest.

Sljedeći » REST upitni jezik s RSQL-om « Prethodni REST jezik upita - Napredno pretraživanje REST dno

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ

$config[zx-auto] not found$config[zx-overlay] not found