【问题标题】:Print JSON requests/responses for each JAX-RS service打印每个 JAX-RS 服务的 JSON 请求/响应
【发布时间】:2016-08-03 09:31:11
【问题描述】:

我有一些具有如下方法签名的 JAX-RS Web 服务。是否可以打印出来自客户端的原始 JSON 请求和返回给客户端的原始 JSON 响应?

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response XXX(@Context HttpServletRequest request, Parameters requestParameters) {
    ...
}

提前致谢。

【问题讨论】:

  • 用于返回 json return Response.ok(returnedJsonString, MediaType.APPLICATION_JSON).build();
  • 你误解了我的要求。我想打印出来自客户端的 JSON 请求,并打印出返回给客户端的 JSON 响应。例如,如果客户端发送了 {“x”:“123”},那么我希望能够打印出这个确切的字符串,用于调试目的。

标签: java json jax-rs


【解决方案1】:

这可以通过请求过滤器为您完成。这是我的实现:

@Path("test")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class HelloResource {

    private static final Logger log = Logger.getLogger(HelloResource.class);

    @POST
    @Path("/test")
    public Response test(String body) {
        Map<String, String> tmp = new HashMap<>();
        tmp.put("test", "value");
        return Response.ok(tmp).build();
    }

}

用于测试的资源。只是把身体当作一个字符串。

现在您可以注册一个 ContainerResponseFilter 和一个 ContainerRequestFilter。

这些过滤器将在请求之前和之后调用。之前将打印传入的正文,之后将打印响应正文。

重要的是不要在响应过滤器中同时执行这两种操作,因为请求实体 Stream 在执行响应过滤器时已关闭。

那是你想要打印你的身体的时候,例如。像这样:

public class PrintFilter implements ContainerResponseFilter, ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
            throws IOException {


        System.out.println("Response body: " + responseContext.getEntity());
    }

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        String string = IOUtils.toString(requestContext.getEntityStream());
        System.out.println("request body: " + string);
    }


}

我正在使用 apache-commons 将请求流读入字符串。

对于我的 json 文件,看起来像这样:

artur@pandaadb:~/tmp/test$ cat 1.json 
{
  "eventType": 1,
  "params": {
    "field1" : 10
  }
}

我可以做一个卷曲,看起来像这样:

artur@pandaadb:~/tmp/test$ curl -XPOST "localhost:9085/api/test/test" -H "Content-Type: application/json" --data @1.json 
{"test":"value"}

这将打印到我的控制台:

request body: {  "eventType": 1,  "params": {    "field1" : 10  }}
Response body: {test=value}

这显然只是众多解决方案中的一种。这适用于所有 json 内容类型(坦率地说,我期望的大多数其他内容类型也是如此)。

希望对你有帮助,

阿图尔

【讨论】:

  • 感谢 pandaadb。您的请求部分对我来说很好。对于响应部分,它没有记录确切的 JSON 响应。我实际上怀疑是否有可能记录对客户端的确切 JSON 响应。无论如何,请求日志记录对我来说更重要,您的解决方案已经足够好了。
  • 嗨@user3573403,请确保在您使用过滤器中的输入流并打印后,将其设置回请求。一个流只能被读取一次,您可能需要创建一个新流以供读取后使用的请求。请调试并确保资源正在检索您期望的内容!
猜你喜欢
  • 2016-08-09
  • 2017-04-29
  • 1970-01-01
  • 2016-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-07
  • 1970-01-01
相关资源
最近更新 更多