EzyHTTP Introduction
EzyHTTP (Easy going to HTTP Interaction) is a framework support to interact to HTTP, it includes both http server and http client.
1. 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
2. Install EzyHTTP
To create a http server application we need add dependency
To use http client we need add dependency
<dependency>
<groupId>com.tvd12</groupId>
<artifactId>ezyhttp-server-boot</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>com.tvd12</groupId>
<artifactId>ezyhttp-client</artifactId>
<version>1.1.3</version>
</dependency>
The latest version can be found in the Maven Central repository.
3. Example
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
3.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);
}
}
3.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;
}
3.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);
}
}
3.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");
}
}
3.4 Create logback.xml file in src/resources folder with content:
<configuration>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} %msg%n
</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="console"/>
</root>
</configuration>
Ok, we done all, let’s start main class ‘App’ and great! We’ve had a http server application
3.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.
4. 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
4.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
4.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"}
5. 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
6. List of examples
- ezydata-jpa: an example uses EzyHTTP and ezydata-jpa
- ezydata-mongodb: an example uses EzyHTTP and ezydata-mongodb
- ezydata-redis: an example uses EzyHTTP and ezydata-redis
- ezyhttp-login: an example uses EzyHTTP to login via google and facebook or username and password
- ezyhttp-thymeleaf: an example uses EzyHTTP and ezyhttp-thymeleaf
Next
We can see how to handle client request