Introduce EzyHTTP
Updated at 1747230710000Structure 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
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.4.5</version> </dependency>
<dependency> <groupId>com.tvd12</groupId> <artifactId>ezyhttp-client</artifactId> <version>1.4.5</version> </dependency>
The latest version can be found in the Maven Central repository.
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
Firstly, we need create a maven project with
- name: user-management-application
- package: com.example.user_management
- java version: 1.8
Next, we need add ezyhttp-server-boot dependency We use lombok to generate getter, setter, constructor so you need install and add lombok dependency to pom.xm
Create the application entry point class
package com.example.user_management;
import com.tvd12.ezyhttp.server.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);
}
}
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;
}
Create UserService class to manage user information
public class UserService {
protected final Map users = new ConcurrentHashMap<>();
public User addUser(User user) {
return users.put(user.getUsername(), user);
}
public User getUser(String username) {
return users.get(username);
}
}
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");
}
}
Create logback.xml file in src/resources folder with content:
<configuration> <appender name="console"> <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"></appender-ref> </root> </configuration>
Ok, we done all, let’s start main class ‘App’ and great! We’ve had a http server application.
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.
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
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 response: true.
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 we can see the output:
get user reponse: {"username":"dev","password":"123456"}
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.
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.