http framework -- the use of Forest

import jar package

<dependency>
  <groupId>com.dtflys.forestgroupId>
  <artifactId>spring-boot-starter-forestartifactId>
  <version>1.3.0version>
dependency>

Define your own interface class

public interface MyClient {

    @Request(url = "http://baidu.com")
    String simpleRequest();

    @Request(
            url = "http://ditu.amap.com/service/regeo",
            dataType = "json"
    )
    Map getLocation(@DataParam("longitude") String longitude, @DataParam("latitude") String latitude);
  
}

Configure the scanning package of the proxy interface class in the startup class

@SpringBootApplication
@ForestScan(basePackages = "com.example.demo.forest")
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

 

At this time, you can inject your proxy interface from the spring container and call the http api like a local method.

@Autowired
private MyClient myClient;

@Override
public void yourMethod throws Exception {
    Map result = myClient.getLocation("124.730329","31.463683");
    System.out.println(JSON.toJSONString(result,true));
}

Log printing, Forest prints the http frame used internally, and the actual request url and return. Of course, the log can be configured to control the switch.

 

 

Forest encapsulates two different http frameworks at the bottom: Apache httpClient and OKhttp. Therefore, this open source framework does not reinvent the wheel for the underlying implementation, but puts a lot of effort into ease of use.

I used Forest to finally complete the project of docking with multiple service providers' APIs. These APIs with different styles were converted into native methods in only 1 hour. Then the project went live smoothly.

As a higher-level http framework, Forest does not need to write a lot of code. Most of the time, you can complete http localization calls with only some configuration. And the scope that this framework can cover is very wide, satisfying most of your http call requests.

Forest has the following characteristics:

  • Using Httpclient and OkHttp as the backend framework
  • By calling local methods to send Http requests, the decoupling between business logic and Http protocol is realized
  • Lighter than Feign, does not depend on Spring Cloud and any registry
  • All request methods supported: GET, HEAD, OPTIONS, TRACE, POST, DELETE, PUT, PATCH
  • Support for flexible template expressions
  • Supports filters to filter incoming data
  • Define Http requests based on annotations and configuration
  • Support for Spring and Springboot integration
  • Serialize and deserialize JSON and XML
  • Support JSON conversion framework: Fastjson,Jackson, Gson
  • Supports XML conversion in JAXB form
  • One-way and two-way encryption with SSL support
  • Support the setting of http connection pool
  • The callback of the request result can be implemented through the OnSuccess and OnError interface parameters
  • The configuration is simple, generally only one @Request annotation is needed to complete the definition of most requests
  • Support for asynchronous request calls

 

Detailed documentation: https://dt_flys.gitee.io/forest

 

 

4.1 Mapping binding function of template expressions and parameters

Template expressions are particularly convenient when used, for example

@Request(
    url = "${0}/send?un=${1}&pw=${2}&ph=${3}&ct=${4}",
    type = "get",
    dataType = "json"
)
public Map send(
    String base,
    String userName,
    String password,
    String phone,
    String content
);

The above is to use the serial number subscript to take the value, and you can also take the value by the name:

@Request(
    url = "${base}/send?un=${un}&pw=${pw}&ph=${3}&ct=${ct}",
    type = "get",
    dataType = "json"
)
public Map send(
    @DataVariable("base") String base,
    @DataVariable("un") String userName,
    @DataVariable("pw") String password,
    @DataVariable("ph") String phone,
    @DataVariable("ct") String content
);

It can even be simplified like this:

@Request(
    url = "${base}/send",
    type = "get",
    dataType = "json"
)
public Map send(
    @DataVariable("base") String base,
    @DataParam("un") String userName,
    @DataParam("pw") String password,
    @DataParam("ph") String phone,
    @DataParam("ct") String content
);

 

The above three expressions are equivalent

Of course, you can also bind parameters to the header and body, and you can even use some expressions to simply serialize objects into json or xml:

@Request(
    url = "${base}/pay",
   contentType = "application/json",
    type = "post",
    dataType = "json",
    headers = {"Authorization: ${1}"},
    data = "${json($0)}"
)
public PayResponse pay(PayRequest request, String auth);

Of course, please refer to the documentation for data binding details.

 

4.2 Support for HTTPS

In the past, when dealing with https with other http frameworks, I always found it very troublesome, especially the two-way certificate. Every time I encounter a problem, I can only go to baidu. Then modify your own code based on the experience of others.

Forest is also very thoughtful in this regard, and the bottom layer perfectly encapsulates the support for https one-way and two-way certificates. It can also be completed quickly with a simple configuration. For a two-way certificate chestnut:

@Request(
    url = "${base}/pay",
   contentType = "application/json",
    type = "post",
    dataType = "json",
   keyStore = "pay-keystore",
   data = "${json($0)}"
)
public PayResponse pay(PayRequest request);

The pay-keystore corresponds to the ssl-key-stores in application.yml

forest:
  ...
  ssl-key-stores:
    - id: pay-keystore
      file: test.keystore
      keystore-pass: 123456
      cert-pass: 123456
      protocols: SSLv3

This setting is ok, and the rest is the call in the form of native code.

 

 

Original link: https://mp.weixin.qq.com/s/MGgd9yqMm1SC0pd2M6szJA

 

Tags: IDE

Posted by andysez on Sun, 22 May 2022 06:06:16 +0300