Changes

Jax-rs 2.0

5,313 bytes added, 16:25, 26 April 2019
Service osztály definiálása
===Path paraméterek kezelése===<br>===Query paraméterek kezelése===<br> ===Header paraméterek kezelése=== <source lang="java"> @GET @Path("/book/") public Book getBook(@HeaderParam("Authorization") String token) { ...  }</source> <br> ==Response objektum előállítása=manuális összeállítása==
A @GET/POST/PUT annotációkkal ellátott metódusoknál a visszatérési objektum típus meghatározására két lehetőségünk van.
A státuszt kétféle képen határozhatjuk meg A Resonse osztálynak többféle metódusa van, ami beállítja a státuszt: ok=200, created=204 ..., vagy mi állítjuk be kézzel: .status(int)
 
<source lang="java">
public Response getContract() {
...
return Response.status(Status.OK).type(MediaType.APPLICATION_JSON).build();
}
</source>
 
<br>
==Hibakezelés==
https://dennis-xlc.gitbooks.io/restful-java-with-jax-rs-2-0-en/cn/part1/chapter8/building_and_invoking_requests.html
==Kliens bemutatása==
Maven dependecia:
<source lang="java">
<dependency>
</source>
A JAX-RS kliens használata magáért beszél, elég intuitív. A ClientBuilder-el csinálunk egy globális kliens példányt, majd a klienssel készítünk sorban egy target-et, hozzáadunk path-t, request-et, metódust stb... A post(), put() metódusok két paramétert várnak, az első a request body objektum (ha van ilyen az interfészen), a második a válasz típusa. A get() csak egy paramétert vár, a válasz típusát. A JSON<->Java mappelést a JAX-RS automatikusan el fogja végezni.
 
 
===Request és Response megadása===
Nézzünk egy példát ahol a kliens meghívja a POST:login interfészt, a request body JSON stukturáját a LoginRequest objektum írja le, a választ pedig a LoginResponse.
<source lang="java">
public class LoginResponse {
private String user;
private String pass;
//getters and setters ...
}
 
public class LoginResponse {
private String userId;
private String token;
//getters and setters ...
}
</source>
 
Ekkor a request így fog kinézni:
<pre>
$ curl -XPOST 'localhost:8080/rest/login?' -H 'Content-Type: application/json' -d'
{ "user":"adam", "pass":"1234" }
</pre>
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Response;
private static Client client = ClientBuilder.newClient();
LoginRequst loginRequest = new LoginRequest();
LoginRequst loginRequest LoginResponse loginResponse = client.target(baseUrl).path("login"). request(MediaType.APPLICATION_JSON).post(Entity.json(loginRequest), LoginRequstLoginResponse.class);
</source>
A válaszban az alábbi JSON fog visszaérkezni:
<pre>
{ "userId":"11111", "token":"XXXXXX"}
</pre>
Amit a JAX-RS mappelni fog egy LoginResponse objektumba.
 
 
===Templét használata a request-ben===
A request URL-ben használhatunk PATH és request paramétereket is, amikhez a JAX-RS kliens behelyettesítő metódusokat biztosít. A PAHT paramétereket a resolveTemplate() metódussal, míg a QUERY paramétereket a queryParam() metódussal helyettesíthetjük be:
<source lang="java">
===Listák kezelése a válaszban===
Ha az interfész válaszában egy POJO listát kapunk vissza, akkor a válasz típusának a megadását az alábbiak szerint kell megadni: ű
<source lang="java">
Client client = ClientBuilder.newClient();
List<Book> books = client.target(url)
.request(MediaType.APPLICATION_JSON).get(new GenericType<List<Book>>(){});
</source>
 
==Hibakezelés==
 
A hibák kezelésére három megközelítést fogunk alkalmazni, amik egybevágnak a server implementációnál tárgyalt megközelítésekkel.
# Exception kezelés: A get(), put(), post().. metódusoknál továbbra is megadjuk a válasz objektum típusát. 200 -as válasz esetében a JAX-RS automatikusan mappelni fogja a választ a megadott objektumba, így ha nem volt hiba, egy Java objektumban megkapjuk a választ. Ha bármilyen hiba dobódik az interfész hívása közben, akkor a JAX-RS kivétel típusából tudhatjuk, hogy milyen hiba történt. A kivételből ki tudjuk szedni a válasz body-ban esetlegesen küldött objektumot.
# A get(), post().. HTTP metódusokban nem mondjuk meg a válasz típusát. Ekkor a kliens a HTTP státusztól függetlenül egy '''javax.ws.rs.core.Response''' objektummal fog visszatérni ha volt hiba hanem. Ekkor a Response-ból nekünk kell kiszedni a válasz objektumot a '''readEntity(Class<T> entityType)''' metódussal és a HTTP státuszt a '''getStatus()''' metódussal.
# A harmadik megközelítés egy változata a másodiknak. Ahelyett, hogy a readEntity() hívással a JAX-RS -e bíznánk a parszolást, a JSON/XML String reprezentációját kérjük el a válaszból, és azt manuálisan parszoljuk.
 
 
===Exception kezelés===
https://dennis-xlc.gitbooks.io/restful-java-with-jax-rs-2-0-en/cn/part1/chapter7/exception_handling.html<br>
Talán ez a legtisztább megközelítés, megadjuk a HTTP metódusban a válasz objektum típusát, amit sikeres futás esetén (HTTP 200) meg fogunk kapni a megadott JAVA objektumban out-of-the-box.
 
<source lang="java">
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Response;
 
private static Client client = ClientBuilder.newClient();
 
LoginRequst loginRequest = new LoginRequest();
try {
LoginRequst loginRequest = client.target(baseUrl).path("login").
request(MediaType.APPLICATION_JSON).post(Entity.json(loginRequest), LoginRequst.class);
 
// 400-as hibák
} catch (ClientErrorException e) {
 
ErrorMessageResponse errorMessageResponse = e.getResponse().readEntity(ErrorMessageResponse.class);
int status = e.getResponse().getStatus();
 
// 500-as hibák
} catch (ServerErrorException e) {
...
// 300-as redirekt hibák
} catch (RedirectionException e) {
...
}
</source>
 
 
 
{| class="wikitable"
! style="font-weight:bold; background-color:#c0c0c0;" | Base Exception
! style="font-weight:bold; background-color:#c0c0c0;" | Status code range
! style="font-weight:bold; background-color:#c0c0c0;" | Description
|-
| ClientErrorException
| 4XX
| Client side error
|-
| ServerErrorException
| 5XX
| Server side error
|-
| RedirectionException
| 3XX
| Redirect
|}
 
 
 
{| class="wikitable"
! style="font-weight:bold; background-color:#c0c0c0;" | Exception
! style="font-weight:bold; background-color:#c0c0c0;" | Status code
! style="font-weight:bold; background-color:#c0c0c0;" | Description
|-
| BadRequestException
| 400
| Malformed message
|-
| NotAuthorizedException
| 401
| Authentication failure
|-
| ForbiddenException
| 403
| Not permitted to access
|-
| NotFoundException
| 404
| Couldn’t find resource
|-
| NotAllowedException
| 405
| HTTP method not supported
|-
| NotAcceptableException
| 406
| Client media type requested not supported
|-
| NotSupportedException
| 415
| Client posted media type not supported
|-
| InternalServerErrorException
| 500
| General server error
|-
| ServiceUnavailableException
| 503
| Server is temporarily unavailable or busy
|}
 
===Response objektum használata===
<source lang="java">
===Response as String===
<source lang="java">
LoginResponse loginResponse = objectMapper.readValue(responseString,LoginResponse.class);
</source>
 
 
<source lang="java">
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Response;
 
private static Client client = ClientBuilder.newClient();
 
LoginRequst loginRequest = new LoginRequest();
try {
LoginRequst loginRequest = client.target(baseUrl).path("login").
request(MediaType.APPLICATION_JSON).post(Entity.json(loginRequest), LoginRequst.class);
 
// 400-as hibák
} catch (ClientErrorException e) {
 
ErrorMessageResponse errorMessageResponse = e.getResponse().readEntity(ErrorMessageResponse.class);
int status = e.getResponse().getStatus();
 
// 500-as hibák
} catch (ServerErrorException e) {
...
// 300-as redirekt hibák
} catch (RedirectionException e) {
...
}
</source>