# Compte Rendu TP Java REST
# Stevan Mercier et Adrien Gauthier
## Introduction
Le but de ce TP était d'utiliser des services REST en utilisant des API. Pour y parvenir nous allons devoir mettre en place un serveur Apache pour y intégrer un chat qui utilisera des méthodes HTTP.
## Partie 1: Ecriture d'un serveur chat
Comme pour le TP en période 2 nous allons créer une application de chat annonyme.
Dans un premier temps nous allons nous contanter de mettre en place nos methodes HTTP dans le but de pouvoir réaliser différentes actions tel que lire des messages, en créer ou bien en supprimer.
Pour y parvenir nous allons utiliser 3 class différentes.
* **La premiere** "Message" à pour but de représenté les messages à manipuler.
* **La seconde** "MessageList" permet d'initialiser nos message et de mettre en place les méthodes qui nous permettrant de les manipulés.
* **La dernières** "MessageRessource" va nous permettre d'initaliser nos méthodes HTTP pour recevoir nos messages, en ecrire des nouveaux ou bien les supprimer. Cette dernière class est celle que nous avons du codé.
Durant ce TP il nous a été demandé de réaliser différentes méthodes :
| URL | Type de requête | Description |
| -------------------- | ------------------------ | --------------------------------------------------------------------------------------------------- |
| /messages | GET | avoir la liste des messages |
| /messages/after/{id} | GET | avoir les messages compris entre {id} et le dernier message du serveur |
| /messages | POST | ajouter un message. Le message envoyé n'a pas d'id ni de date. C'est le serveur qui les initialise. |
| /messages/{id} | GET | avoir le message d'ID {id} |
| /messages/{id} | DELETE | effacer le message d'ID {id} |
Nous avions déja la requête /messages/after/{ID} de donné à titre d'exemple. ous devions donc réaliser les autres requêtes.
### /messages
```java=
@GET
@Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
public List<Message> getMessages(){
System.out.println("liste complète des messages: "+ MessageList.getInstance().getMessages());
return MessageList.getInstance().getMessages();
}
```
Pour cette requête, comme le path de la class était déja /messages pas besoin de le rajouté. Pour fonctionner elle appelle la méthode getMessage présent dans la class MessageList.
Pour vérifier si elle fonctione bien nous pouvons ensuite utilisé notre navigateur et entré l'URL lui correspondant ou bien passé par un client REST comme Postman.

Nous voyons bien les 3 messages pré enregistré.
### /message/{id}
Pour cette requête nous voulons récuperer un seul message en fonction de son id.
```java=
@Path("/{id}")
@GET
@Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
public Message getMessage(@PathParam("id") Long id){
System.out.println("message " + id);
System.out.println(MessageList.getInstance().getMessage(id));
return MessageList.getInstance().getMessage(id);
}
```
Cette fois nous devons indiquer dans le path de l'URL l'id du message que nous devons récuperer puis puis recupérer ce numero en paramètre.
### POST /messages
Cette fois à la différence d'afficher un des messages deja présent dans notre code nous voulons en créer un. Pour y parvenir il faut faire une requête de type POST.
```java=
@POST
@Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
@Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
public Message createMessage(JAXBElement<Message>element){
Message message = element.getValue();
System.out.println("message à créer: "+ message);
return MessageList.getInstance().createMessage(message);
}
```
Pour le POST nous devons ajouter un produces en plus pour indiquer que l'on souhaite créer un message et non pas seulement le lire. J'affiche un message dans la console pour me savoir si le message à bien pu être créer et on retourne notre message.
Puis à l'aide d'un client postman nous pouvons remplir le body pour y inserer notre message.

### DELETE /messages/{ID}
Nous devions également pouvoir supprimer un message. Pour y parvenir nous avons donc utilisé la méthode DELETE pour supprimer le message en fonction de l'ID donnée en paramètre.
```java=
@Path("del/{id}")
@DELETE
public void delMessage(@PathParam("id") Long id){
//Message message = MessageList.getInstance();
MessageList.getInstance().delMessage(id);
System.out.println("le message à été supprimé");
}
```
Pour supprimer un message pas besoin de produces ou de consumes, nous devons juste faire appel à la méthode delMessage de la class MessageList.
## Partie 2: Test en Java
Dans cette partie il nous ai demmander de remplacer notre client POSTMAN par du code java qui puisse réaliser les mêmes taches.
Nous avons donc du codé pour chaque méthode la requêtes en Java à l'aide de l'API de cliente de Jersey 2.
### Recevoir un message en particulier:
```java=
//Get one message
ChatMessage[] messages1 = client.target(URL).path("messages").path("2").request(MediaType.APPLICATION_JSON_TYPE).get(ChatMessage[].class);
System.out.println(messages1);
```
Résultat:

Nous recuperons bien le syso 'message 2' produis par notre méthode ainsi que le message en question.
### MessageAfter:
```java=
//Get all messages after
ChatMessage[] messages2 = client.target(URL).path("messages").path("after").path("2").request(MediaType.APPLICATION_JSON_TYPE).get(ChatMessage[].class);
for (ChatMessage chatMessage : messages2) {
System.out.println(chatMessage);
}
```
Résultat:

Nous récuperons bien tout les messages après l'ID 2 c'est à dire un seul.
### MessageBeteween
```java=
//Get all messages betwenn
ChatMessage[] messages3 = client.target(URL).path("messages").path("between").path("1").path("2").request(MediaType.APPLICATION_JSON_TYPE).get(ChatMessage[].class);
for (ChatMessage chatMessage : messages3) {
System.out.println(chatMessage);
}
```
Résultat:

### DELETE
Dans un premier temps nous créons un messages à l'aide d'un post.

Puis à l'aide de notre code nous le supprimons:
```java=
//Delete a message :
Response del = client.target(URL).path("messages").path("del").path("4").request().delete();
System.out.println("Response "+ del.getStatus());
```

le code 204 nous indique qu'il n'y rien dans cette URL cela signie que notre message à bien été supprimé.
## Partie 3: Client du chat avec Javascript
Dans cette partie on nous demande à l'aide d'un code html et js déja fournit de lancé une interface web de chat qui réutilise nos méthodes HTTP.

Une fois le code insérer dans Eclipse et les URL modifiées pour qu'elles correspondent a nos requêtes voila le resultat final.
Nous pouvons voir l'appelle de la méthode messageAfter toute les seconde à l'aide de la console de notre navigateur.

Cette méthode permet de vérifier toute les secondes si il y a un nouveaux message en prenant en compte le dernier ID qu'aura le message qui sera créer.
Nous avons ajouter à ce chat un second bouton dans le but de supprimer le dernier message écrit.
```htmlmixed=
<form name="chatForm" action="" method="DELETE">
<button type="button" id="delButton">delete</button>
</form>
```
Nous avons donc ajouté un second formulaire dans notre code html avec un bouton qui va servir a supprimer le dernier message.
Puis dans le code js nous avons donc créer une fonction pour supprimer notre message:
```javascript=
function delMessage() {
$.ajax({
type : 'DELETE',
url : rootURL+"/del/" + lastID1,
success : function(data) {
console.log('message delete');
},
error : function(jqXHR, textStatus, errorThrown) {
console.log('updateMessages error: ' + textStatus);
}
});
}
```
Cette fonction reprend la fonction appendMessage qu'utilise le GET pour récuperer le dernier ID.
Nous avons donc réutiliser le LASTID-1 pour supprimer le dernier message déja présent que nous avons initialiser comme varibale au préalable.
Puis plus bas dans notre code js nous faison un appelle de cette méthode lorsque il y un évemenement comme un clique sur notre bouton.
```javascript=
$("#delButton").click(function() {
delMessage();
window.location.reload();
});
```
Nous avons également ajouté un reload a notre click pour actualiser la page et voir le message disparraitre

Nous pouvons alors voir la requête DELETE passer dans la console de notre navigateur en plus de voir le message disparaitre.
### Client API OpenWeatherMap
En plus du chat nous avons également mis en place une interface pour utiliser les API fournis par OWM pour récuperer la méteo de différentes villes.
Nous avions déja réaliser une interface lors de la prise en main d'un projet l'année passée pour comprendre le principe des API nous l'avons donc réutiliser et quelque peu modifié pour le TP.

Nous l'avons réaliser sur un code html tout en y ajoutant des script js pour faire les appelles de nos méthodes.
```htmlmixed=
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title> Test API</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div class="MainBlock">
<h1 id="H1">AppControl</h1> <br>
<input id="ville" type="text" placeholder="Entre une ville ;)" ><br>
<div id="tempe"></div>
<input id="button" type="button" value="Température" onclick="clickTemp()"><br>
<div id="hum"></div>
<input id="button" type="button" value="Humidité" onclick="clickHum()"><br>
</div>
<script>
var callBackSuccess = function (data){
console.log("Données api", data)
result = Math.round(data.main.temp);
var element = document.getElementById("tempe");
element.innerHTML = " La température est de : " + result + ' °C';
}
function clickTemp() {
var city = document.getElementById("ville").value; //permet de recup la valeur du champ input text est de la stocké dans city
var url = "https://api.openweathermap.org/data/2.5/weather?q="+city+"&units=metric&appid=134505649c1d6843ac5a31cb348993e4"
$.get(url,callBackSuccess).done(function(){
})
.fail(function(){
alert("Il faut mettre le nom d'une ville !!!");
})
.always(function(){
});
}
function clickHum() {
var city = document.getElementById("ville").value; //permet de recup la valeur du champ input text est de la stocké dans city
var url = "https://api.openweathermap.org/data/2.5/weather?q="+city+"&units=metric&appid=134505649c1d6843ac5a31cb348993e4"
$.get(url,callBackSuccess2).done(function(){
})
.fail(function(){
alert("Il faut mettre le nom d'une ville !!!");
})
// .always(function(){
// });
}
var callBackSuccess2 = function (data){
console.log("Données api", data)
result = Math.round(data.main.humidity);// valeurs arrondi
var element = document.getElementById("hum");
element.innerHTML = " L'humidité est de : " + result + ' %';
}
</script>
<style>
```
Nous avons deux fonctions pour récuperer l'humidité et la température de la ville souhaité.
Notre URL comprend le chemin de base pour accéder à l'API de owm puis le nom de la ville où nous voulons les infos, ensuite le type d'infos que nous voulons (humidité ou temp dans notre cas) et enfin la clé pour avoir accès à l'API.
Nous avons également ajouté la possibilité d'accéder à toute les donner méteorologique de la ville depuis la console du navigateur.
