dromara / forest Goto Github PK
View Code? Open in Web Editor NEWA high-level and lightweight declarative HTTP client framework for Java. it makes sending HTTP requests in Java easier.
License: MIT License
A high-level and lightweight declarative HTTP client framework for Java. it makes sending HTTP requests in Java easier.
License: MIT License
使用forest-spring-boot-starter执行HTTP请求时,默认backend为okhttp3。
debug发现并未对Query参数进行URL Encode,
调用链路
com.dtflys.forest.backend.okhttp3.executor.AbstractOkHttp3Executor#execute(com.dtflys.forest.handler.LifeCycleHandler, int)
com.dtflys.forest.backend.url.SimpleURLBuilder#buildUrl
backend修改为httpclient调用的com.dtflys.forest.backend.url.QueryableURLBuilder则进行了正常URL Encode。
请修复
详细文档的网站打不开啊
fastjson2 github地址:https://github.com/alibaba/fastjson2
com.dtflys.forest.backend.AsyncHttpExecutor当前是硬编码SynchronousQueue
pool = new ThreadPoolExecutor(
coreSize, maxAsyncThreadSize != null ? maxAsyncThreadSize : DEFAULT_MAX_THREAD_SIZE,
3, TimeUnit.MINUTES,
new SynchronousQueue<>(),
tf -> {
Thread thread = new Thread(tf, "forest-async-" + threadCount.getAndIncrement());
thread.setDaemon(true);
return thread;
}, new AsyncAbortPolicy());
我希望使用LinkedBlockingQueue希望能给一个配置选项
这里有关于线程池的相关配置么,默认线程池大小是多少
package com.example.request;
import com.dtflys.forest.annotation.Body;
import com.dtflys.forest.annotation.Get;
import com.dtflys.forest.annotation.Post;
public interface Client {
@Post(url = "http://127.0.0.1:8090/api/admin/login/precheck", contentType = "application/json")
public String login(@Body("username") String username, @Body("password") String password);
}
package com.example;
import com.dtflys.forest.config.ForestConfiguration;
import com.example.request.Client;
public class main {
public static void main(String[] args) {
Client myClient = ForestConfiguration.configuration().createInstance(Client.class);
myClient.login("[email protected]", "123456789");
}
}
运行报错:
[main] INFO com.dtflys.forest.config.ForestConfiguration - [Forest] Http Backend: okhttp3
Exception in thread "main" java.lang.NullPointerException
at com.dtflys.forest.backend.body.AbstractBodyBuilder.buildBody(AbstractBodyBuilder.java:151)
at com.dtflys.forest.backend.okhttp3.executor.AbstractOkHttp3Executor.prepareBody(AbstractOkHttp3Executor.java:171)
at com.dtflys.forest.backend.okhttp3.executor.AbstractOkHttp3Executor.execute(AbstractOkHttp3Executor.java:181)
at com.dtflys.forest.backend.okhttp3.executor.AbstractOkHttp3Executor.execute(AbstractOkHttp3Executor.java:281)
at com.dtflys.forest.http.ForestRequest.execute(ForestRequest.java:1608)
at com.dtflys.forest.http.ForestRequest.execute(ForestRequest.java:1625)
at com.dtflys.forest.reflection.ForestMethod.invoke(ForestMethod.java:1143)
at com.dtflys.forest.proxy.InterfaceProxyHandler.invoke(InterfaceProxyHandler.java:121)
at com.sun.proxy.$Proxy9.login(Unknown Source)
at com.example.main.main(main.java:16)
postman 中 start_dt=2021-06-10T08:00:00Z 没问题, 通过 forest 报 404 ,请求的是 gitlab的openapi,1.5.0-RC6
Error creating bean with name 'helloworld': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'amap': FactoryBean threw exception on object creation; nested exception is com.dtflys.forest.exceptions.ForestRuntimeException: java.lang.NoSuchMethodException: java.lang.invoke.MethodHandles$Lookup.<init>(java.lang.Class,int)
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>demo</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-resolver-dns-native-macos</artifactId>
<scope>runtime</scope>
<classifier>osx-x86_64</classifier>
<version>4.1.59.Final</version>
</dependency>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.3.8</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 对象池,使用redis时必须引入 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-redis-reactive</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-quartz</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>forest-spring-boot-starter</artifactId>
<version>1.5.8</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.mybatis.spring.boot</groupId>-->
<!-- <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!-- <version>2.2.0</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.dtflys.forest</groupId>-->
<!-- <artifactId>forest-spring-boot-starter</artifactId>-->
<!-- <version>1.5.14</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-devtools</artifactId>-->
<!-- <scope>runtime</scope>-->
<!-- <optional>true</optional>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
代码
Ammp.java
package com.example.demo.client;
import com.dtflys.forest.annotation.BaseRequest;
import com.dtflys.forest.annotation.Query;
import com.dtflys.forest.annotation.Request;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* 高德地图服务客户端接口
*
* @author gongjun
*/
@BaseRequest(baseURL = "http://ditu.amap.com")
@Component
public interface Amap {
/**
* 根据经纬度获取详细地址
*
* @param longitude 经度
* @param latitude 纬度
* @return
*/
@Request(url = "/service/regeo")
Map getLocation(@Query("longitude") String longitude, @Query("latitude") String latitude);
}
Helloworld (controller)
package com.example.demo.controller;
import com.example.demo.client.Amap;
import com.example.demo.service.userService;
import com.example.demo.task.AsyncTask;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.Map;
@RestController
public class Helloworld {
@Resource
protected AsyncTask asyncTask;
@Resource
protected userService UserService;
@Resource
private Amap amap;
@RequestMapping("/httpclient")
public String httpclient() {
Map result = amap.getLocation("121.475078", "31.223577");
System.out.println(result);
return "444";
}
}
main
package com.example.demo;
import com.dtflys.forest.springboot.annotation.ForestScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableAsync;
@EnableAsync
@EnableCaching
@SpringBootApplication
@ForestScan(basePackages = "com.example.demo.client")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
// ApplicationContext ctx = SpringApplication.run(DemoApplication.class, args);
// String[] beanNames = ctx.getBeanDefinitionNames();
// Arrays.sort(beanNames);
// for (String beanName : beanNames) {
// System.out.println(beanName);
// }
}
}
URL查询参数在有些特殊的网站无法生效,并且会有查询参数丢失的问题。
具体表现如下:
/template/file/?${name}
会导致 ${name}
参数值丢失,实际只请求了 /template/file/
地址,导致请求结果不正确。
经过个人断点调试,解决该问题的大致范围在 QueryableURLBuilder.java
的第32-34行,以及 MappingTemplate.java
的第364-366行
看源代码里有NoneRetryer和BackOffRetryer;不是很清晰他的作用,或者能否自定义Retryer
springboot jdk17环境启动报错
Caused by: com.dtflys.forest.exceptions.ForestRuntimeException: java.lang.NoSuchMethodException: java.lang.invoke.MethodHandles$Lookup.(java.lang.Class,int)
at com.dtflys.forest.proxy.InterfaceProxyHandler.(InterfaceProxyHandler.java:69) ~[forest-core-1.5.19.jar:?]
at com.dtflys.forest.proxy.ProxyFactory.createInstance(ProxyFactory.java:42) ~[forest-core-1.5.19.jar:?]
at com.dtflys.forest.config.ForestConfiguration.createInstance(ForestConfiguration.java:1521) ~[forest-core-1.5.19.jar:?]
at com.dtflys.forest.Forest.client(Forest.java:56) ~[forest-core-1.5.19.jar:?]
很抱歉在文档中没有看到
目前在baserequest只有设置字符串类型变量的header
在项目中 需要使用https方式请求 但是需要忽略证书 想知道如何设置
当使用自定义注解时,注解变量的值引用Forest全局变量进行赋值,当全局变量定义不存在时,
会报空指针异常。此处建议优化为,当全局变量的引用值为空时,使用自定义注解的对应字段的默认值,
没有默认值时再抛异常。
举例如下:
public @interface ForestPorxy {
String isProxy() default "false";
}
@GETrequest(url = "https:.//www.baidu.com")
@ForestPorxy(isProxy = "${proxy.baidui}")
ForestResponse evtBaidu();
如果proxy.baidui 在配置文件中不存在,现在的版本为直接抛出异常,且不会进入自定义注解的生命周期。
文档(上传下载)给出:
@PostRequest(url = "/upload")
Map upload(@DataFile(value = "file") MultipartFile multipartFile, OnProgress onProgress);
上传文件为图片时multipartFile的contentType= image/jpeg
,upload给另外一个接口时,另外接口接收到的multipartFile的contentType= multipart/form-data
。
Hi, In forest-master/forest-core,there is a dependency org.apache.httpcomponents:httpclient:4.5.2 that calls the risk method.
The scope of this CVE affected version is [,4.5.13)
After further analysis, in this project, the main Api called is <org.apache.http.client.utils.URIUtils: org.apache.http.HttpHost extractHost(java.net.URI)>
Risk method repair link : GitHub
CVE Bug Invocation Path--
Path Length : 4
<org.apache.http.client.utils.URIUtils: org.apache.http.HttpHost extractHost(java.net.URI)>
at <org.apache.http.impl.client.DecompressingHttpClient: org.apache.http.HttpHost getHttpHost(org.apache.http.client.methods.HttpUriRequest)> (org.apache.http.impl.client.DecompressingHttpClient.java:[137]) in /.m2/repository/org/apache/httpcomponents/httpclient/4.5.2/httpclient-4.5.2.jar
at <org.apache.http.impl.client.DecompressingHttpClient: org.apache.http.HttpResponse execute(org.apache.http.client.methods.HttpUriRequest)> (org.apache.http.impl.client.DecompressingHttpClient.java:[123]) in /.m2/repository/org/apache/httpcomponents/httpclient/4.5.2/httpclient-4.5.2.jar
at <com.dtflys.forest.backend.httpclient.request.SyncHttpclientRequestSender: void sendRequest(com.dtflys.forest.http.ForestRequest,com.dtflys.forest.backend.httpclient.response.HttpclientResponseHandler,org.apache.http.client.methods.HttpUriRequest,com.dtflys.forest.handler.LifeCycleHandler,org.apache.http.client.CookieStore,java.util.Date,int)> (com.dtflys.forest.backend.httpclient.request.SyncHttpclientRequestSender.java:[98]) in /detect/unzip/forest-master/forest-core/target/classes
Dependency tree--
[INFO] com.dtflys.forest:forest-core:jar:1.5.2-BETA
[INFO] +- com.googlecode.juniversalchardet:juniversalchardet:jar:1.0.3:compile
[INFO] +- org.apache.httpcomponents:httpclient:jar:4.5.2:compile
[INFO] | \- commons-codec:commons-codec:jar:1.13:compile
[INFO] +- org.apache.httpcomponents:httpclient-cache:jar:4.5.2:compile
[INFO] +- org.apache.httpcomponents:httpcore:jar:4.4.5:compile
[INFO] +- org.apache.httpcomponents:httpmime:jar:4.5.2:compile
[INFO] +- org.apache.httpcomponents:httpcore-nio:jar:4.4.5:compile
[INFO] +- org.apache.httpcomponents:httpasyncclient:jar:4.1.2:compile
[INFO] +- com.squareup.okhttp3:okhttp:jar:3.14.9:compile
[INFO] | \- com.squareup.okio:okio:jar:1.17.2:compile
[INFO] +- com.google.code.findbugs:jsr305:jar:3.0.1:compile
[INFO] +- commons-io:commons-io:jar:2.4:compile
[INFO] +- com.alibaba:fastjson:jar:1.2.48:provided
[INFO] +- com.fasterxml.jackson.core:jackson-core:jar:2.9.10:provided
[INFO] +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.10.7:provided
[INFO] +- com.fasterxml.jackson.core:jackson-annotations:jar:2.9.10:provided
[INFO] +- com.google.code.gson:gson:jar:1.7.1:provided
[INFO] +- commons-logging:commons-logging:jar:1.1:compile
[INFO] | +- log4j:log4j:jar:1.2.12:compile
[INFO] | +- logkit:logkit:jar:1.0.1:compile
[INFO] | \- avalon-framework:avalon-framework:jar:4.1.3:compile
[INFO] +- org.slf4j:slf4j-api:jar:1.7.10:compile
[INFO] +- xerces:xercesImpl:jar:2.12.0:provided
[INFO] | \- xml-apis:xml-apis:jar:1.4.01:provided
[INFO] +- org.mock-server:mockserver-netty:jar:3.10.4:provided
[INFO] | +- org.mock-server:mockserver-client-java:jar:3.10.4:provided
[INFO] | | \- org.apache.commons:commons-lang3:jar:3.9:provided
[INFO] | +- org.mock-server:mockserver-core:jar:3.10.4:provided
[INFO] | | +- javax.servlet:javax.servlet-api:jar:4.0.1:provided
[INFO] | | +- com.twitter:finagle-native_2.11:jar:6.33.0:provided
[INFO] | | | +- org.scala-lang:scala-library:jar:2.11.7:provided
[INFO] | | | +- com.twitter:finagle-core_2.11:jar:6.33.0:provided
[INFO] | | | | +- com.twitter:util-app_2.11:jar:6.32.0:provided
[INFO] | | | | +- com.twitter:util-cache_2.11:jar:6.32.0:provided
[INFO] | | | | +- com.twitter:util-codec_2.11:jar:6.32.0:provided
[INFO] | | | | +- com.twitter:util-collection_2.11:jar:6.32.0:provided
[INFO] | | | | | +- javax.inject:javax.inject:jar:1:provided
[INFO] | | | | | \- commons-collections:commons-collections:jar:3.2.1:provided
[INFO] | | | | +- com.twitter:util-core_2.11:jar:6.32.0:provided
[INFO] | | | | | +- com.twitter:util-function_2.11:jar:6.32.0:provided
[INFO] | | | | | \- org.scala-lang.modules:scala-parser-combinators_2.11:jar:1.0.4:provided
[INFO] | | | | +- com.twitter:util-hashing_2.11:jar:6.32.0:provided
[INFO] | | | | +- com.twitter:util-jvm_2.11:jar:6.32.0:provided
[INFO] | | | | +- com.twitter:util-lint_2.11:jar:6.32.0:provided
[INFO] | | | | +- com.twitter:util-logging_2.11:jar:6.32.0:provided
[INFO] | | | | +- com.twitter:util-registry_2.11:jar:6.32.0:provided
[INFO] | | | | +- com.twitter:util-stats_2.11:jar:6.32.0:provided
[INFO] | | | | +- com.twitter:jsr166e:jar:1.0.0:provided
[INFO] | | | | \- io.netty:netty:jar:3.10.1.Final:provided
[INFO] | | | \- com.twitter:finagle-http_2.11:jar:6.33.0:provided
[INFO] | | | \- commons-lang:commons-lang:jar:2.6:provided
[INFO] | | +- com.jcraft:jzlib:jar:1.1.3:provided
[INFO] | | +- org.bouncycastle:bcmail-jdk15on:jar:1.52:provided
[INFO] | | +- org.bouncycastle:bcpkix-jdk15on:jar:1.52:provided
[INFO] | | +- org.skyscreamer:jsonassert:jar:1.5.0:provided
[INFO] | | | \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:provided
[INFO] | | \- com.github.fge:json-schema-validator:jar:2.2.6:provided
[INFO] | | +- joda-time:joda-time:jar:2.10.5:provided
[INFO] | | +- com.googlecode.libphonenumber:libphonenumber:jar:6.2:provided
[INFO] | | +- com.github.fge:json-schema-core:jar:1.2.5:provided
[INFO] | | | +- com.github.fge:uri-template:jar:0.9:provided
[INFO] | | | | \- com.github.fge:msg-simple:jar:1.1:provided
[INFO] | | | | \- com.github.fge:btf:jar:1.2:provided
[INFO] | | | +- com.github.fge:jackson-coreutils:jar:1.8:provided
[INFO] | | | \- org.mozilla:rhino:jar:1.7R4:provided
[INFO] | | +- javax.mail:mailapi:jar:1.4.3:provided
[INFO] | | | \- javax.activation:activation:jar:1.1:provided
[INFO] | | \- net.sf.jopt-simple:jopt-simple:jar:4.6:provided
[INFO] | +- org.bouncycastle:bcprov-jdk15on:jar:1.52:provided
[INFO] | +- com.google.guava:guava:jar:18.0:provided
[INFO] | +- ch.qos.logback:logback-classic:jar:1.2.3:provided
[INFO] | | \- ch.qos.logback:logback-core:jar:1.2.3:provided
[INFO] | +- janino:janino:jar:2.5.10:provided
[INFO] | \- org.mock-server:mockserver-logging:jar:3.10.4:provided
Suggested solutions:
Update dependency version to 4.5.13 or higher
Thank you very much.
在使用文件上传的时候发现指定了backend:httpclient时,文件上传接口返还的json数据为 forestResponse中的content内容,而forestResponse中result没有数据导致json解析失败。
默认的okhttp3来实现上传请求没有问题。
项目是spring boot,@OAuth2
中的的配置信息需要做到配置化,如果再代码中硬编码灵活性太差。于是想通过forest变量来解决,如下
@OAuth2(
tokenUri = "${testaouth2.tokenUri}",
clientId = "${testaouth2.clientId}",
clientSecret = "${testaouth2.clientSecret}",
grantType = OAuth2.GrantType.PASSWORD,
scope = "${testaouth2.scope}",
username = "${testaouth2.username}"
password = "${testaouth2.password}"
)
grantType 是一个枚举,如何做到外部传参呢?
RT
forest-spring-boot-starter 1.5.0 版本, 接口调用上不能读取父接口上的注解信息. 比如@BaseRequest 注解
在解析双层泛型对象的时候 会报类转换异常
ForestJacksonConverter 可否支持一下自定义配置,比如 下划线 转驼峰支持 一些 api 接口 返回数据是 下划线格式的字段,需要自动映射为 驼峰格式,需要
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
我有一个dto实体类Entity{ String a,int b,List c },在get请求中他被@query修饰作为url上的参数,如下getReuest(@query Entity e),但是实际拼出来的url是http://xxxxx?a=xx&b=xx&c=[\"xxx\",\“xxxx\”],他把我的list序列化了,然后我试着把List c单独拿出来,并把Entity修改为{ String a,int b},而c作为第二个参数如下getReuest(@query Entity e,@query("c") List c),拼出来的url是http://xxxxx?a=xx&b=xx&c=xxx&c=xxxx,这是否是一个缺陷?
当调用接口失败时,方法的返回值通常是null,例如方法:
@request(url = "${0}",
interceptor = {VerifyInvoiceInterceptor.class},
type = "post",
contentType = "application/json",
dataType = "json")
VerifyInvoiceResponse verifyInvoice(String url, @dataobject VerifyInvoiceDTO verifyInvoiceDTO);
如果方法调用异常,返回值verifyInvoiceResponse是null,是否可通过拦截器重新自定义返回值,使得verifyInvoiceResponse 不为null
这框架支持在Android项目内使用吗?需要什么特别的配置吗?
如题,希望可支持配置httpclient原生的HttpRequestInterceptor
使用forest拦截器,请求成功,有数据和200响应体状态码返回,但是却没有进入拦截器的onSuccess方法
Hi, Thank you for making such an excellent framework.
Now my new project still chose forest.
But now I have encountered some mistakes and need your help. As the title indicates.
My development environment:
There are detailed error logs here:
2022-03-08 13:51:14.848 INFO 2345 --- [ main] c.a.***.Application : Starting Application using Java 17.0.2 on ***-Mac.local with PID 2345 (/Users/loadClass/IdeaProjects/target/classes started by *** in /Users/***/IdeaProjects/***)
2022-03-08 13:51:14.849 INFO 2345 --- [ main] c.a.***.Application : No active profile set, falling back to default profiles: default
2022-03-08 13:51:15.207 WARN 2345 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getForestBeanRegister' defined in class path resource [com/dtflys/forest/springboot/ForestAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.dtflys.forest.springboot.ForestBeanRegister]: Factory method 'getForestBeanRegister' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'forestConfiguration': Bean instantiation via factory method failed; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
2022-03-08 13:51:15.220 INFO 2345 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-03-08 13:51:15.232 ERROR 2345 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getForestBeanRegister' defined in class path resource [com/dtflys/forest/springboot/ForestAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.dtflys.forest.springboot.ForestBeanRegister]: Factory method 'getForestBeanRegister' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'forestConfiguration': Bean instantiation via factory method failed; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:634) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:622) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1310) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1161) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:566) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:526) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:266) ~[spring-context-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:762) ~[spring-context-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:567) ~[spring-context-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-3.0.0-M1.jar:3.0.0-M1]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:719) ~[spring-boot-3.0.0-M1.jar:3.0.0-M1]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:401) ~[spring-boot-3.0.0-M1.jar:3.0.0-M1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302) ~[spring-boot-3.0.0-M1.jar:3.0.0-M1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1290) ~[spring-boot-3.0.0-M1.jar:3.0.0-M1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1279) ~[spring-boot-3.0.0-M1.jar:3.0.0-M1]
at com.allinprogram.***.Application.main(Application.java:12) ~[classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.dtflys.forest.springboot.ForestBeanRegister]: Factory method 'getForestBeanRegister' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'forestConfiguration': Bean instantiation via factory method failed; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:161) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:630) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
... 19 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'forestConfiguration': Bean instantiation via factory method failed; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:634) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:622) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1310) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1161) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:566) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:526) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1138) ~[spring-context-6.0.0-M2.jar:6.0.0-M2]
at com.dtflys.forest.springboot.ForestBeanRegister.registerForestConfiguration(ForestBeanRegister.java:134) ~[forest-spring-boot-starter-1.5.19.jar:na]
at com.dtflys.forest.springboot.ForestAutoConfiguration.getForestBeanRegister(ForestAutoConfiguration.java:42) ~[forest-spring-boot-starter-1.5.19.jar:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:130) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
... 20 common frames omitted
Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
at com.dtflys.forest.config.ForestConfiguration.createConfiguration(ForestConfiguration.java:336) ~[forest-core-1.5.19.jar:na]
at com.dtflys.forest.config.ForestConfiguration.configuration(ForestConfiguration.java:320) ~[forest-core-1.5.19.jar:na]
at com.dtflys.forest.config.ForestConfiguration.configuration(ForestConfiguration.java:306) ~[forest-core-1.5.19.jar:na]
at com.dtflys.forest.config.ForestConfiguration.<clinit>(ForestConfiguration.java:99) ~[forest-core-1.5.19.jar:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:130) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:630) ~[spring-beans-6.0.0-M2.jar:6.0.0-M2]
... 37 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na]
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na]
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[na:na]
... 47 common frames omitted
Disconnected from the target VM, address: '127.0.0.1:50713', transport: 'socket'
Process finished with exit code 1
I may have found some helpful information: https://stackoverflow.com/questions/43574426/how-to-resolve-java-lang-noclassdeffounderror-javax-xml-bind-jaxbexception
Please contact me if you need more information about the exception.
I think the httpclient/okhttpclient should singleton in connectionManager. Now the per request has a client. It’s so heavy and the most import is that the connection pool of client doesn‘t work.
有一个这样的配置,读取就会报错
forest:
variables:
xxx-search: http://baidu.com
版本:
<dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>forest-spring-boot-starter</artifactId>
<version>1.5.2-BETA</version>
</dependency>
forst 1.5.21,java 17,kotlin 1.6.10,springboot 2.7.0 启动报错
2022-05-29 16:33:02.677 [main] WARN o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Test': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'client': FactoryBean threw exception on object creation; nested exception is java.lang.StackOverflowError 2022-05-29 16:33:02.679 [main] INFO o.a.catalina.core.StandardService - Stopping service [Tomcat] 2022-05-29 16:33:02.714 [main] ERROR o.s.boot.SpringApplication - Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Test': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'client': FactoryBean threw exception on object creation; nested exception is java.lang.StackOverflowError at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:332) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) at com.liusibo.blog.BlogApplicationKt.main(BlogApplication.kt:15) Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'client': FactoryBean threw exception on object creation; nested exception is java.lang.StackOverflowError at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:176) at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:101) at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1884) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getObjectForBeanInstance(AbstractAutowireCapableBeanFactory.java:1284) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:267) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeanByName(AbstractAutowireCapableBeanFactory.java:479) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:550) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:520) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:673) at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:228) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:329) ... 17 common frames omitted Caused by: java.lang.StackOverflowError: null at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936) at java.base/java.lang.ClassLoader.definePackage(ClassLoader.java:2096) at java.base/java.lang.ClassLoader.definePackage(ClassLoader.java:2079) at java.base/java.lang.Class.getPackage(Class.java:1045) at com.dtflys.forest.reflection.ForestMethod.getAnnotationLifeCycleClassMap(ForestMethod.java:302) at com.dtflys.forest.reflection.ForestMethod.getAnnotationLifeCycleClassMap(ForestMethod.java:308) at com.dtflys.forest.reflection.ForestMethod.getAnnotationLifeCycleClassMap(ForestMethod.java:308) at com.dtflys.forest.reflection.ForestMethod.getAnnotationLifeCycleClassMap(ForestMethod.java:308) at com.dtflys.forest.reflection.ForestMethod.getAnnotationLifeCycleClassMap(ForestMethod.java:308) at com.dtflys.forest.reflection.ForestMethod.getAnnotationLifeCycleClassMap(ForestMethod.java:308)
调用spring boot actuator接口,响应头中的Transfer-Encoding为chunked,解析内容错误
请问是否支持http2协议?在文档中没有找到对应的说明
官方提供的例子:
public class ErrorInterceptor implements Interceptor {
@OverRide
public void onError(ForestRuntimeException ex, ForestRequest request, ForestResponse response) {
int status = response.getStatusCode(); // 获取请求响应状态码
String content = response.getContent(); // 获取请求的响应内容
Object result = response.getResult(); // 获取方法返回类型对应的返回数据结果
}
}
onError无法捕获ForestHandlerException异常
forest version:v1.5.16
使用拦截器添加body体参数,如下:
public class UnitySignInterceptor implements Interceptor {
@Override
public boolean beforeExecute(ForestRequest request) {
Map<String, Object> addMap = new HashMap<>();
addMap.put("version", "text");
request.addBody(JSON.toJSONString(addMap));
return Interceptor.super.beforeExecute(request);
}
}
实体字段如下:
@JSONField(format = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime createDateTime;
补救方案,配置全局时间格式化配置对 LocalDateTime 类型无效:
forest:
converters:
json:
type: com.dtflys.forest.converter.json.ForestFastjsonConverter
# 转换器的参数设置
parameters:
# JSON数据转换器的全局日期格式化配置
dateFormat: "yyyy-MM-dd'T'HH:mm:ss"
请问还有其他解决方案吗?
获取响应的API应该开放出来
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.