Classe MyHttpClient effectuant une requete synchrone et asynchrone au Server MyHttpServer qui renvoie une réponse
package fr.dyma;
import com.fasterxml.jackson.core.type.TypeReference;
import fr.dyma.model.Article;
import fr.dyma.model.Client;
import fr.dyma.service.util.ObjectJsonMapper;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.time.OffsetDateTime;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import static java.lang.StringTemplate.STR;
public class MyHttpClient {
public static void main(String[] args) throws IOException, ExecutionException, InterruptedException {
var articleJsonMapper = new ObjectJsonMapper<Article>();
Article articleClient = new Article("article client", "From client", ":D", OffsetDateTime.now());
var articleClientJson = articleJsonMapper.toJson(articleClient);
var clientJsonMapper = new ObjectJsonMapper<Client>();
Client clientClient = new Client("Tuan", "NGUYEN", "tuanounet@gmail.com");
var clientClientJson = clientJsonMapper.toJson(clientClient);
// HttpClient client = HttpClient.newBuilder()
// .version(HttpClient.Version.HTTP_1_1)
// .build();
// HttpClient client = HttpClient.newHttpClient();
HttpRequest requetePost = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:8000/obj"))
.setHeader("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(clientClientJson))
.timeout(Duration.ofSeconds(20)) // Duration.of(20, ChronoUnit.SECONDS)
.build();
// Réponse synchrone
try {
HttpResponse response = HttpClient.newHttpClient().send(requetePost, HttpResponse.BodyHandlers.ofString());
printInfoServer(articleJsonMapper, response);
System.out.println("END OF SYNCHRONOUS SERVER RESPONSE");
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
// Réponse asynchrone
CompletableFuture<Void> responseAsync = HttpClient.newHttpClient().sendAsync(requetePost, HttpResponse.BodyHandlers.ofString()).thenAcceptAsync(
resp -> {
printInfoServer(articleJsonMapper, resp);
System.out.println(Thread.currentThread().getName());
},
Executors.newFixedThreadPool(10)
);
try {
responseAsync.get(); //wait for API response
} catch (InterruptedException e) {
System.out.println("Interrupted server response");
} catch (ExecutionException e) {
System.out.println("Interrupted server execution");
}
System.out.println("END OF ASYNCHRONOUS SERVER RESPONSE");
}
private static void printInfoServer(ObjectJsonMapper<Article> articleJsonMapper, HttpResponse response) {
System.out.println(STR."Status : \{response.statusCode()}");
System.out.println(STR."Headers : \{response.headers()}");
System.out.println(STR."Body : \{response.body()}");
String body = String.valueOf(response.body());
Article serverArticle = articleJsonMapper.toObject(new TypeReference<>() {}, body);
System.out.println(STR."RETRIEVED FROM SERVER : \{serverArticle}");
}
}
Réponse du server MyHttpServer au client MyHttpClient
package fr.dyma;
import com.sun.net.httpserver.HttpServer;
import fr.dyma.model.Article;
import fr.dyma.service.ObjectHandler;
import fr.dyma.service.impl.ObjectHandlerImpl;
import java.io.IOException;
import java.net.InetSocketAddress;
public final class MyHttpServer {
public static void main(String[] args) throws IOException {
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
Article serverArticle = new Article("Server article", "From the server", ":)", null);
// Création d'un flux de communicaton Client/Server
ObjectHandler<Article> articleHandler = new ObjectHandlerImpl<>(serverArticle);
// Réponse server au requête client
startServer(server, articleHandler);
}
public static <T> void startServer(HttpServer server, ObjectHandler<T> handler) throws IOException {
server.createContext("/obj", handler);
server.setExecutor(null); // creates a default executor
server.start();
System.out.println("Server started on port 8000 !");
}
}
Classe générique de serialisation des objets java
package fr.dyma.service.util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.io.IOException;
import static java.lang.StringTemplate.STR;
public final class ObjectJsonMapper<T> {
/**
* From Json to Object
* @param typeReference the serialized object type reference
* @param json the json ton convert to object
* @return T the type of object that will be serialized
*/
public T toObject(TypeReference<T> typeReference, String json) {
var objectMapper = new ObjectMapper();
// To fix jackson error unknown or transient field
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// To fix jackson data/time error
objectMapper.registerModule(new JavaTimeModule());
T data = null;
try {
data = objectMapper.readValue(json, typeReference);
} catch (IOException e) {
System.out.println(STR."Error reading \{json}: \{e.getMessage()}");
}
return data;
}
/**
* From Object to Json
* @param obj The Object to convert to Json format
* @return The Json representation
* @throws JsonProcessingException
*/
public String toJson(T obj) throws JsonProcessingException {
var objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
return objectMapper.writeValueAsString(obj);
}
}
Classe se de gestion de flux HTTP Sever / Client
package fr.dyma.service.impl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.sun.net.httpserver.HttpExchange;
import fr.dyma.service.ObjectHandler;
import fr.dyma.service.util.ObjectJsonMapper;
import java.io.IOException;
public class ObjectHandlerImpl<T> implements ObjectHandler<T> {
private final T obj;
public ObjectHandlerImpl(T object) {
this.obj = object;
}
@Override
public void handle(HttpExchange exchange) throws IOException {
// Read client body
var body = new String(exchange.getRequestBody().readAllBytes());
var objectJsonMapper = new ObjectJsonMapper<T>();
var clientObject = objectJsonMapper.toObject(new TypeReference<>() {}, body);
System.out.println(STR."Object from client : \{clientObject}");
// Return object to client
String serverJson = objectJsonMapper.toJson(this.obj);
byte[] serverJsonBytes = serverJson.getBytes();
exchange.sendResponseHeaders(200, serverJsonBytes.length);
var out = exchange.getResponseBody();
out.write(serverJsonBytes);
}
}