1. Introduct to EzyHTTP
EzyHTTP (Easy going to HTTP Interaction) is a framework support to interact to HTTP, it includes both http server and http client.
2. Structure of EzyHTTP Server

- When client request to server, Servlet receive the request first
- The request must pass through the list of interceptor before pass to controller
- The controller handle the request and return response to the Servlet
- If have any exceptions unprocessed by the Interceptor and the Controller, an ExcetionHandler will process that exception and return result to the Servlet
- After all the Servlet will send the response to client
3. Install EzyHTTP
To create a http server application we need add dependency
<dependency>
<groupId>com.tvd12</groupId>
<artifactId>ezyhttp-server-boot</artifactId>
<version>0.0.9</version>
</dependency>
To use http client we need add dependency
<dependency>
<groupId>com.tvd12</groupId>
<artifactId>ezyhttp-client</artifactId>
<version>0.0.9</version>
</dependency>
The latest version can be found in the Maven Central repository.
Let’s say we need create an http server application to manage user, we need 2 apis
- - api/v1/users/add: Add user to system
- - api/v1/users/{username}: Get user by name
- - name: user-management-application
- - package: com.example.user_management
- - java version: 1.8
4.1 Create the application entry point class
package com.example.user_management;
import com.tvd12.ezyhttp.core.boot.EzyHttpApplicationBootstrap;
import com.tvd12.ezyhttp.server.core.asm.RequestHandlerImplementer;
public class App {
public static void main(String[] args) throws Exception {
RequestHandlerImplementer.setDebug(true);
EzyHttpApplicationBootstrap.start(App.class);
}
}
4.2 Create User class to keep user information
package com.example.user_management.entity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class User {
protected String username;
protected String password;
}
4.3 Create UserService class to manage user information
public class UserService {
protected final Map<String, User> users = new ConcurrentHashMap<>();
public User addUser(User user) {
return users.put(user.getUsername(), user);
}
public User getUser(String username) {
return users.get(username);
}
}
4.4 Create UserController class to handle request from client
package com.example.user_management.controller;
import com.example.user_management.entity.User;
import com.example.user_management.service.UserService;
import com.tvd12.ezyfox.bean.annotation.EzyAutoBind;
import com.tvd12.ezyhttp.core.exception.HttpConflictException;
import com.tvd12.ezyhttp.core.exception.HttpNotFoundException;
import com.tvd12.ezyhttp.core.response.ResponseEntity;
import com.tvd12.ezyhttp.server.core.annotation.*;
import lombok.Setter;
@Setter
@Controller("/api/v1/users")
public class UserController {
@EzyAutoBind
protected UserService userService;
@DoPost("/add")
public ResponseEntity addUser(@RequestBody User user) {
User existed = userService.addUser(user);
if(existed == null)
return ResponseEntity.ok(Boolean.TRUE);
throw new HttpConflictException("user: " + user.getUsername() + " existed");
}
@DoGet("/{username}")
public User getUser(@PathVariable("username") String username) {
User user = userService.getUser(username);
if(user != null)
return user;
throw new HttpNotFoundException("user: " + username + " not found");
}
}
4.4 Create log4j.properties file in src/resources folder with content:
# Root logger option
log4j.rootLogger=INFO, stdout
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
Ok, we done all, let’s start main class ‘App’ and great! We’ve had a http server application
4.5 Let’s take a test on postman
With api: /api/v1/users/add we have:

With api: /api/v1/users/{username} we have:

Awesome! Everything ok.
5. Create a client example
With client, we have 2 way (2 class) to call http request
- - HttpClient: A simple http client, it simply open a connection, send the request and return the response, it only supports sync method
- - HttpClientProxy: It use HttpClient class to send the request, but every request will add to a queue, and we need config number of threads to process this queue. It supports both sync and async method
Firstly, we need add ezyhttp-client dependency to maven
Next, create a test package with name: com.example.user_management.test in src/test/java folder
5.1 To test /api/v1/users/add api, we need create a class ApiAddUserTest with content:
package com.example.user_management.test;
import com.example.user_management.entity.User;
import com.tvd12.ezyhttp.client.HttpClient;
import com.tvd12.ezyhttp.client.request.PostRequest;
import com.tvd12.ezyhttp.client.request.Request;
import com.tvd12.ezyhttp.client.request.RequestEntity;
import com.tvd12.ezyhttp.core.constant.StatusCodes;
public class ApiAddUserTest {
public static void main(String[] args) throws Exception {
HttpClient httpClient = HttpClient.builder()
.build();
User body = new User();
body.setUsername("dev");
body.setPassword("123456");
RequestEntity entity = RequestEntity.body(body);
Request request = new PostRequest()
.setURL("http://localhost:8080/api/v1/users/add")
.setEntity(entity)
.setResponseType(Boolean.class)
.setResponseType(StatusCodes.CONFLICT, String.class);
Boolean reponse = httpClient.call(request);
System.out.println("add user reponse: " + reponse);
}
}
And we get output: add user reponse: true
5.2 To test /api/v1/users/add api, we need create a class ApiAddUserTest with content:
package com.example.user_management.test;
import com.tvd12.ezyhttp.client.HttpClientProxy;
import com.tvd12.ezyhttp.client.request.GetRequest;
import com.tvd12.ezyhttp.client.request.Request;
import com.tvd12.ezyhttp.client.request.RequestEntity;
import com.tvd12.ezyhttp.core.constant.StatusCodes;
public class ApiGetUserTest {
public static void main(String[] args) throws Exception {
HttpClientProxy httpClient = HttpClientProxy.builder()
.build();
httpClient.start();
RequestEntity entity = RequestEntity.builder().build();
Request helloRequest = new GetRequest()
.setURL("http://localhost:8080/api/v1/users/dev")
.setEntity(entity)
.setResponseType(String.class)
.setResponseType(StatusCodes.NOT_FOUND, String.class);
String reponse = httpClient.call(helloRequest, 10000);
System.out.println("get user reponse: " + reponse);
}
}
And get get output: get user reponse: {"username":"dev","password":"123456"}
6. Conclusion
With EzyHTTP everything are simple, you don’t need care about HttpServlet, HttpRequest, HttpResponse, how to serialize/deserialize request/response and bean management, with IOC EzyHTTP will care for you