2016-08-03 1 views
2

У меня есть некоторые веб-службы JAX-RS с сигнатурами методов, как показано ниже. Возможно ли распечатать необработанные запросы JSON, поступающие от клиентов, и необработанный ответ JSON, возвращаемый клиентам?Печать запросов и ответов JSON для каждого сервиса JAX-RS

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

Заранее спасибо.

+0

Для возвращения JSON 'вернуть Response.ok (returnedJsonString, MediaType.APPLICATION_JSON) .build();' –

+0

Вы не поняли мое требование. Я хочу ПЕЧАТЬ запросами JSON, которые поступают от клиентов, и ПЕЧАТЬ ответы JSON, которые возвращаются клиентам. Например, если клиент отправил {"x": "123"}, то я хочу, чтобы иметь возможность распечатать эту точную строку для цели отладки. – user3573403

ответ

2

это можно сделать с помощью фильтра запросов для вас. Это моя реализация:

@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 для чтения запроса Stream в строку.

Для моего файла JSON, похожий на что:

[email protected]:~/tmp/test$ cat 1.json 
{ 
    "eventType": 1, 
    "params": { 
    "field1" : 10 
    } 
} 

я могу сделать завиток, похожий на этот:

[email protected]:~/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 (и, откровенно говоря, большинства других типов контента, как и ожидалось).

Надежда, что помогает,

Артур

+0

Спасибо pandaadb. Ваша часть запроса работает отлично для меня. Для части ответа он не регистрирует точный ответ JSON. Я действительно сомневаюсь, что можно зарегистрировать точный ответ JSON клиенту. Во всяком случае, регистрация запросов важнее для меня, и ваше решение достаточно хорошее. – user3573403

+0

Здравствуйте, @ user3573403, убедитесь, что после того, как вы потребляете INputstream в своем фильтре и распечатаете его, вы установите его обратно на запрос. Поток может быть прочитан только один раз, и вам может понадобиться создать новый поток для запроса, который будет использоваться после его чтения. Пожалуйста, отлаживайте и убедитесь, что ресурс извлекает то, что вы ожидаете! – pandaadb