Declarative HTTP client framework, reducing your development burden

Declarative HTTP client framework, reducing your development burden

2022-12-12 0 1,608
Resource Number 49631 Last Updated 2025-02-21
¥ 0HKD Upgrade VIP
Download Now Matters needing attention
Can't download? Please contact customer service to submit a link error!
Value-added Service: Installation Guide Environment Configuration Secondary Development Template Modification Source Code Installation

This issue recommends a declarative HTTP framework – Forest.

Declarative HTTP client framework, reducing your development burden插图

Forest is an open-source Java HTTP client framework that can bind all HTTP request information (including URL, Header, Body, etc.) to your custom Interface method and send HTTP requests by calling local interface methods.

Using Forest is like using an RPC framework like Dubbo, where you only need to define and call the interface, without worrying about the details of sending HTTP requests. At the same time, decoupling HTTP request information from business code facilitates unified management of a large amount of HTTP URLs, headers, and other information. And the caller of the request does not need to pay attention to the specific content of the HTTP, even if the HTTP request information changes, in most cases there is no need to modify the code that calls and sends the request.

Functional characteristics

  • Declarative interface: Encapsulates HTTP requests through defined interfaces and annotations, achieving decoupling between business logic and HTTP protocol
  • Multiple underlying HTTP frameworks: using Httpclient and OkHttp as backend frameworks (optional)
  • Not dependent on middleware: As it targets third-party interfaces, there is no need to rely on Spring Cloud or any registry
  • Supports all request methods: GET, HEAD, OPTIONS, TRACE, POST, DELETE, PUT, PATCH
  • Agreement is greater than configuration: as long as dependencies are added, basically nothing can be configured and it can run immediately
  • Automatic JSON Conversion: Built in Jackson, Fastjson, and Gson JSON converters
  • Automatic XML Conversion: Built in JAXB based XML Converter
  • Automatic Protobuf Conversion: Built in Protobuf Format Data Converter
  • Multiple verification methods: Basic Auth, OAuth2, and verification through custom interceptors or annotations
  • Spring/Spring boot: Supports integration of Spring and Springboot
  • Upload and download: supports multiple upload and download methods, and can monitor data transmission progress
  • Template expression: Supports flexible template expressions to be used in conjunction with declarative annotations
  • Interceptor: Supports interceptors to handle various lifecycles of requests
  • Custom Annotations: Supports custom annotations to greatly enhance scalability
  • Callback function: supports callback of request results through OnSuccess and OnError interface parameters
  • Asynchronous request: supports convenient asynchronous request invocation methods
  • Programming interfaces: In addition to declarative interfaces, intuitive programming interfaces are also supported

working principle

Forest will generate a concrete implementation class through dynamic proxy based on the interface you have defined, and then organize and validate HTTP request information, bind dynamic data, convert data forms, SSL verify signatures, call backend HTTP APIs (such as httpclient) to execute actual requests, wait for responses, retry failures, convert response data to Java types, and other dirty and tiring tasks are all covered by this dynamic proxy implementation class. When requesting the sender to call this interface, it is actually calling the implementation class that does the dirty and tiring work.

 

Quick StartDeclarative HTTP client framework, reducing your development burden插图1

1 Add Maven dependency

Springboot environment:

<dependency>
  <groupId>com.dtflys.forest</groupId>
  <artifactId>forest-spring-boot-starter</artifactId>
  <version>1.5.25</version>
</dependency>

Spring environment:

<dependency>
    <groupId>com.dtflys.forest</groupId>
    <artifactId>forest-core</artifactId>
    <version>1.5.25</version>
</dependency>

<dependency>
  <groupId>com.dtflys.forest</groupId>
  <artifactId>forest-spring</artifactId>
  <version>1.5.25</version>
</dependency>

Native Java environment:

<dependency>
  <groupId>com.dtflys.forest</groupId>
  <artifactId>forest-core</artifactId>
  <version>1.5.25</version>
</dependency>

2 Create an interface

Taking Gaode Map API as an example:


package com.yoursite.client;

import com.dtflys.forest.annotation.Request;
import com.dtflys.forest.annotation.DataParam;

public interface AmapClient {

    /**
     * You must have noticed that the @ Get annotation represents that this method is specifically designed for GET requests
     * {0} in the URL represents referencing the first parameter, and {1} refers to the second parameter
     */
    @Get("http://ditu.amap.com/service/regeo?longitude={0}&latitude={1}")
    Map getLocation(String longitude, String latitude);
}

3 Scan interface

Add the @ ForestScan annotation to the configuration or boot class of Spring Boot, and fill in the package name of the remote interface in the basePackages property

@SpringBootApplication
@Configuration
@ForestScan(basePackages = "com.yoursite.client")
public class MyApplication {
  public static void main(String[] args) {
      SpringApplication.run(MyApplication.class, args);
   }
}

4 Call interface

// Inject interface instance

@Autowired

private AmapClient amapClient;

...

// Call interface

Map result = amapClient.getLocation("121.475078", "31.223577");

System.out.println(result);

Send JSON data

/**
 * Parse object parameters into JSON strings and transmit them in the requested Body
 */
@Post("/register")
String registerUser(@JSONBody MyUser user);

/**
 * Parse Map type parameters into JSON strings and transmit them in the requested Body
 */
@Post("/test/json")
String postJsonMap(@JSONBody Map mapObj);

/**
 * Directly input a JSON string and place it in the requested body for transmission
 */
@Post("/test/json")
String postJsonText(@JSONBody String jsonText);

Sending XML data

/**
 * Parse a type object modified with JAXB annotations into an XML string
 * And put it in the requested body for transmission
 */
@Post("/message")
String sendXmlMessage(@XMLBody MyMessage message);

/**
 * Directly input an XML string and transmit it in the requested body
 */
@Post("/test/xml")
String postXmlBodyString(@XMLBody String xml);

Send Protobuf data

/**
 * ProtobufProto.MyMessage is the data class generated by Protobuf
 * Convert the data objects generated by Protobuf into a byte stream in Protobuf format
 * And put it in the requested body for transmission
 * 
 * Note: Need to introduce Google Protobuf dependency
 */
@Post(url = "/message", contentType = "application/octet-stream")
String sendProtobufMessage(@ProtobufBody ProtobufProto.MyMessage message);

File upload

/**
 * Decorate the parameter object to be uploaded with @ DataMile annotation
 * The PnP rogress parameter is a callback function that listens for upload progress
 */
@Post("/upload")
Map upload(@DataFile("file") String filePath, OnProgress onProgress);

A method can be used to add Lambda to simultaneously solve file upload and upload progress monitoring

Map result = myClient.upload("D:\\TestUpload\\xxx.jpg", progress -> {
    System.out.println("progress: " + Math.round(progress.getRate() * 100) + "%");  // Percentage uploaded
    if (progress.isDone()) {   // Is the upload completed
        System.out.println("--------   Upload Completed!   --------");
    }
});

Batch upload of multiple files

/**
 * Upload a list of files packaged in Map, where {_key} represents the key values in each iteration of the Map
 */
@Post("/upload")
ForestRequest<Map> uploadByteArrayMap(@DataFile(value = "file", fileName = "{_key}") Map<String, byte[]> byteArrayMap);

/**
 * Upload the file list packaged with List, where {_index} represents the loop count of List for each iteration (starting from zero)
 */
@Post("/upload")
ForestRequest<Map> uploadByteArrayList(@DataFile(value = "file", fileName = "test-img-{_index}.jpg") List<byte[]> byteArrayList);

File Download

Downloading files is equally simple

/**

* Add @ DownloadFile annotation on the method

* The dir attribute indicates which directory the file is downloaded to

* The PnP rogress parameter is a callback function that listens for upload progress

* {0} represents referencing the first parameter

*/

@Get("http://localhost:8080/images/xxx.jpg")

@DownloadFile(dir = "{0}")

File downloadFile(String dir, OnProgress onProgress);

The code for calling the download interface and monitoring the download progress is as follows:

File file = myClient.downloadFile("D:\\TestDownload", progress -> {

System.out.println("progress: " + Math.round(progress.getRate() * 100) + "%"); // Downloaded percentage

if (progress.isDone()) { // Is the download complete

System.out.println("-------- Download Completed! --------");

}

});

—END—

Open source license: MIT

资源下载此资源为免费资源立即下载
Telegram:@John_Software

Disclaimer: This article is published by a third party and represents the views of the author only and has nothing to do with this website. This site does not make any guarantee or commitment to the authenticity, completeness and timeliness of this article and all or part of its content, please readers for reference only, and please verify the relevant content. The publication or republication of articles by this website for the purpose of conveying more information does not mean that it endorses its views or confirms its description, nor does it mean that this website is responsible for its authenticity.

Ictcoder Free Source Code Declarative HTTP client framework, reducing your development burden https://ictcoder.com/declarative-http-client-framework-reducing-your-development-burden/

Qizhuwang Source Code Trading Platform

Q&A
  • 1. Automatic: After making an online payment, click the (Download) link to download the source code; 2. Manual: Contact the seller or the official to check if the template is consistent. Then, place an order and make payment online. The seller ships the goods, and both parties inspect and confirm that there are no issues. ICTcoder will then settle the payment for the seller. Note: Please ensure to place your order and make payment through ICTcoder. If you do not place your order and make payment through ICTcoder, and the seller sends fake source code or encounters any issues, ICTcoder will not assist in resolving them, nor can we guarantee your funds!
View details
  • 1. Default transaction cycle for source code: The seller manually ships the goods within 1-3 days. The amount paid by the user will be held in escrow by ICTcoder until 7 days after the transaction is completed and both parties confirm that there are no issues. ICTcoder will then settle with the seller. In case of any disputes, ICTcoder will have staff to assist in handling until the dispute is resolved or a refund is made! If the buyer places an order and makes payment not through ICTcoder, any issues and disputes have nothing to do with ICTcoder, and ICTcoder will not be responsible for any liabilities!
View details
  • 1. ICTcoder will permanently archive the transaction process between both parties and snapshots of the traded goods to ensure the authenticity, validity, and security of the transaction! 2. ICTcoder cannot guarantee services such as "permanent package updates" and "permanent technical support" after the merchant's commitment. Buyers are advised to identify these services on their own. If necessary, they can contact ICTcoder for assistance; 3. When both website demonstration and image demonstration exist in the source code, and the text descriptions of the website and images are inconsistent, the text description of the image shall prevail as the basis for dispute resolution (excluding special statements or agreements); 4. If there is no statement such as "no legal basis for refund" or similar content, any indication on the product that "once sold, no refunds will be supported" or other similar declarations shall be deemed invalid; 5. Before the buyer places an order and makes payment, the transaction details agreed upon by both parties via WhatsApp or email can also serve as the basis for dispute resolution (in case of any inconsistency between the agreement and the description of the conflict, the agreement shall prevail); 6. Since chat records and email records can serve as the basis for dispute resolution, both parties should only communicate with each other through the contact information left on the system when contacting each other, in order to prevent the other party from denying their own commitments. 7. Although the probability of disputes is low, it is essential to retain important information such as chat records, text messages, and email records, in case a dispute arises, so that ICTcoder can intervene quickly.
View details
  • 1. As a third-party intermediary platform, ICTcoder solely protects transaction security and the rights and interests of both buyers and sellers based on the transaction contract (product description, agreed content before the transaction); 2. For online trading projects not on the ICTcoder platform, any consequences are unrelated to this platform; regardless of the reason why the seller requests an offline transaction, please contact the administrator to report.
View details

Related Source code

ICTcoder Customer Service

24-hour online professional services