Usługi Restful
Usługi Restful
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Book {
@XmlAttribute
private Integer id;
@XmlAttribute
private String title;
@XmlAttribute
private Double price;
public Book() {
}
set/get...
}
Usługi RESTful
import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;
@ApplicationPath("resources")
public class ApplicationConfig extends Application {
}
Usługi RESTful
Przykład klienta
// pobranie (GET)
response = client.target(bookURI).request().get();
book = response.readEntity(Book.class);
System.out.println("Status code 2:"+response.getStatusInfo().getStatusCode());
System.out.println(book);
// usunięce (DELETE
String bookId = bookURI.toString().split("/")[6];
response = client.target(uri).path(bookId).request().delete();
System.out.println("Status code 3:"+response.getStatusInfo().getStatusCode());
}
}
Usługi RESTful
Przykład klienta
●
zależności maven
….
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>ver</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-jaxb</artifactId>
<version>ver.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-processing</artifactId>
<version>ver1</version>
</dependency>
</dependencies>
...
Usługi RESTful
Obsługa wyjątków
●
metody klas implementujących usługę REST mogą wyrzucać wyjątki (unchecked i checked)
●
wyjątki mogą być obsłużone przez środowisko JAX-RS z użyciem klas odwzorowujących wyjątek
na odpowiedź HTTP, która będzie wysłana do klienta
●
klasa odpowiedzialna za odwzorowanie wyjątku powinna implementować interfejs
javax.ws.rs.ext.ExceptionMapper i mieć adnotację @jakarta.ws.rs.ext.Provider
Przykład
@Provider
public class ServiceExceptionMapper implements ExceptionMapper<UnsupportedOperationException> {
@Override
public Response toResponse(UnsupportedOperationException e) {
return Response.status(Response.Status.SERVICE_UNAVAILABLE).build();
}
}
@Path("book")
public class BookService {
@GET
public List<Book> findAll() {
throw new UnsupportedOperationException();
}
}
Usługi RESTful
Obsługa wyjątków
●
JAX-RS posiada też własną hierarchię wyjątków, które są automatycznie zamieniane na
odpowiednie odpowiedzi HTTP – nie wymagają tworzenia własnych klas odwzorowujących
●
bazową klasą dla wyjątków JAX-RS, które metody usług mogą wyrzucać jest
javax.ws.rs.WebApplicationException
●
dla standardowych typów błędów są też dostępne podklasy, np.: ,
BadRequestExceptionNotFoundException, NotAuthorizedException,
ServiceUnavailableException, ...
Przykład
@Path("book")
public class BookService {
@GET
public List<Book> findAll() {
// użycie bazowego typu wyjątku
throw new
WebApplicationException(Response.status(Response.Status.SERVICE_UNAVAILABLE).build());
// lub skorzystanie z podklasy
throw new ServiceUnavailableException();
}
}
Usługi RESTful
Przykład
public class App {
public static void main(String[] args) {
URI uri = UriBuilder.fromUri("http://localhost:8080/appname/rest/book").port(8080).build();
// HTTP Basic
HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic("user", "secretPassword");
// lub HTTP Digest
HttpAuthenticationFeature feature = HttpAuthenticationFeature.digest("user", "secretPassword");
client.register(feature);
… client.target(uri).get() ….
}
}
Usługi RESTful
Uwierzytelnianie klienta per żądanie przez HTTP Basic/Digest z użyciem referencyjnej implementacji
JAX_RS: Jersey
Przykład
public class App {
public static void main(String[] args) {
URI uri = UriBuilder.fromUri("http://localhost:8080/appname/rest/book").port(8080).build();
// HTTP Basic
Response response = client.target("http://localhost:8080/rest/homer/contact").request()
.property(HTTP_AUTHENTICATION_BASIC_USERNAME, "user")
.property(HTTP_AUTHENTICATION_BASIC_PASSWORD, "secretPassword").get();
Wsparcie dla web services na platformach Java SE/Java EE/Jakarta EE jest oparte głównie na
następujących specyfikacjach:
●
JAX-WS – API umożliwiające tworzenie i komunikowanie się z usługami webowymi
●
Web Services – określa model programowania, format dystrybucji i zachowanie usług w
kontenerach EE
●
Web Services Metadata ( – udostępnia adnotacje ułatwiające definicję usług webowych
●
JAXB – ułatwia odwzorowanie pomiędzy obiektami a formatem XML
Referencyjna implementacja to Metro, inne przykłady implementacji to:Apache CXF i Apache Axis2
Web Services (usługi webowe)
package webws1.model;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlAttribute;
import jakarta.xml.bind.annotation.XmlRootElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Message implements Serializable {
@XmlAttribute
private Integer id;
@XmlAttribute
private String title;
@XmlAttribute
private String body;
public Message() {
}
… get.../set...
}
Web Services (usługi webowe)
package webws1.api;
import jakarta.jws.WebService;
import webws1.model.Message;
@WebService
public interface MessageProviderAPI {
Message getMessage(String name);
}
import jakarta.jws.WebService;
import webws1.api.MessageProviderAPI;
import webws1.model.Message;
@WebService(endpointInterface = "webws1.api.MessageProviderAPI")
public class MessageProvider implements MessageProviderAPI {
@Override
public Message getMessage(String name) {
return new Message(1, "Hello", "Hi "+name+", this is message from MessageProvider");
}
}
Web Services (usługi webowe)
Przykład klienta
●
wywołanie metody usługi z klienta odbywa się zazwyczaj z użyciem obiektu proxy, który lokalnie
udostępnia interfejs usługi i wykonuje niezbędne operacje do wywołania usługi web (konwertuje
wywołanie i parametry do wiadomości SOAP, wysyła żądanie na serwer, odbiera i parsuje
odpowiedź, tworzy obiekty reprezentujące wynik i je zwraca)
●
proxy oraz klasy modelu danych można wygenerować na podstawie plików WSDL oraz XSD,
które opisują interfejs usługi i struktury danych z użyciem narzędzia wsimport - dostępne w JDK i
implementacji JWS; w przypadku projektu Maven wystarczy użyć odpowiedniego plugin’a, który
pobierze wymagane pliki WSDL/XSD i wygeneruje odpowiednie klasy
Web Services (usługi webowe)
Przykład klienta
●
konfiguracja Maven, która tworzy w fazie generate-sources tworzy odpowiednie klasy w projekcie
klienta:
….
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<wsdlUrls>
<wsdlUrl>
http://localhost:8080/WebWS1/MessageProviderService?wsdl
</wsdlUrl>
</wsdlUrls>
<!-- Needed with JAXP 1.5 -->
<vmArgs>
<vmArg>-Djavax.xml.accessExternalSchema=all</vmArg>
</vmArgs>
<keep>true</keep>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
Web Services (usługi webowe)
import javax.xml.ws.BindingProvider;
public class App {
public static void main(String[] args) {
MessageProviderAPI ms = new MessageProviderService().getMessageProviderPort();
Message m = ms.getMessage("Joe");
System.out.println("Message id:"+m.getId()+", title:"+m.getTitle()+", body:"+m.getBody());
}
}
Web Services (usługi webowe)
Obsługa wyjątków
●
Wyjątki wyrzucane przez metody komponentu WebService są komunikat błędu wysyłany do
klienta (SOAP fault message)
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>java.lang.NullPointerException</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
try {
...
}
} catch (ServerSOAPFaultException ex) {
System.out.println(ex.getMessage());
System.out.println( ex.getFault().getFaultCode());
System.out.println(ex.getFault().getFaultString());