如何打印/记录Jersey客户端请求?请求日志未输出排查
问题排查:Jersey客户端400错误+LoggingFeature日志不输出
一、400错误的直接原因
你的请求存在媒体类型不匹配的核心问题:
- 代码里用
target.request(MediaType.APPLICATION_FORM_URLENCODED)声明接收表单格式响应,但发送请求时却通过Entity.entity(postBody, MediaType.APPLICATION_JSON)把HashMap以JSON格式发送。 - IRS的OAuth Token接口要求请求体为
application/x-www-form-urlencoded格式,服务器解析不到正确参数,因此返回invalid_request错误。
修复方法:改用Form类构建表单请求体,指定正确的媒体类型:
// 替换HashMap为Form构建表单参数 Form postBody = new Form(); postBody.param("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer"); postBody.param("assertion", "1234567890"); postBody.param("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"); postBody.param("client_assertion", "1234567890"); // 请求时使用表单媒体类型 Response response = builder.post(Entity.entity(postBody, MediaType.APPLICATION_FORM_URLENCODED));
二、LoggingFeature不输出日志的原因
Jersey的LoggingFeature依赖java.util.logging(JUL),但你的项目引入了log4j2却未配置JUL到log4j2的桥接,导致JUL日志无法被log4j2捕获输出。
修复步骤:
- 在pom.xml中添加log4j-jul依赖实现日志桥接:
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-jul</artifactId> <version>2.19.0</version> <scope>runtime</scope> </dependency>
- 确保JUL日志级别足够开放,可直接在代码中配置:
Logger logger = Logger.getLogger(JerseyTest.class.getName()); logger.setLevel(Level.ALL); // 添加控制台处理器 ConsoleHandler consoleHandler = new ConsoleHandler(); consoleHandler.setLevel(Level.ALL); logger.addHandler(consoleHandler); logger.setUseParentHandlers(false); // 避免重复输出
完整修改后的测试代码
import java.util.logging.ConsoleHandler; import java.util.logging.Level; import java.util.logging.Logger; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.client.JerseyClient; import org.glassfish.jersey.client.JerseyClientBuilder; import org.glassfish.jersey.client.JerseyWebTarget; import org.glassfish.jersey.client.JerseyInvocation.Builder; import org.glassfish.jersey.logging.LoggingFeature; import org.glassfish.jersey.logging.LoggingFeature.Verbosity; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.core.Form; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; public class JerseyTest { public static void main(String[] args) { ClientConfig config = new ClientConfig(); Logger logger = Logger.getLogger(JerseyTest.class.getName()); // 配置JUL控制台输出 ConsoleHandler consoleHandler = new ConsoleHandler(); consoleHandler.setLevel(Level.ALL); logger.addHandler(consoleHandler); logger.setLevel(Level.ALL); logger.setUseParentHandlers(false); LoggingFeature feature = new LoggingFeature(logger, Level.ALL, Verbosity.PAYLOAD_ANY, 50000); config.register(feature); JerseyClient client = JerseyClientBuilder.createClient(config); JerseyWebTarget target = client.target("https://api.alt.www4.irs.gov/auth/oauth/v2/token"); // 使用Form构建表单请求体 Form postBody = new Form(); postBody.param("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer"); postBody.param("assertion", "1234567890"); postBody.param("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"); postBody.param("client_assertion", "1234567890"); // 服务器返回JSON格式,这里指定响应类型为JSON更合理 Builder builder = target.request(MediaType.APPLICATION_JSON); Response response = builder.post(Entity.entity(postBody, MediaType.APPLICATION_FORM_URLENCODED)); System.out.println(response.getStatus()); System.out.println(response.readEntity(String.class)); } }
补充说明
- 代码中把
request(MediaType.APPLICATION_FORM_URLENCODED)改为APPLICATION_JSON,因为服务器返回的是JSON格式,这样更匹配响应类型。 - 若不需要log4j2,也可在
src/main/resources下创建logging.properties文件直接配置JUL:
handlers=java.util.logging.ConsoleHandler .level=ALL java.util.logging.ConsoleHandler.level=ALL java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
内容的提问来源于stack exchange,提问作者Neil
相关产品推荐
相关产品推荐

