Регистрация вызовов JSON-RPC с использованием jsonrpc4j

Я уверен, что если вы использовали jsonrpc4j (вне контейнера для пружин), вы узнаете следующую стандартную схему.

public class MyServletJsonRpc extends HttpServlet {
   private MyService myService;
   private JsonRpcServer jsonRpcServer;

   @Override
   protected void doPost(HttpServletRequest request
                      , HttpServletResponse response) throws IOException {
      jsonRpcServer.handle(request, response);
   }
   @Override
   public void init(ServletConfig config) {
       myService = new MyServiceImpl();
       jsonRpcServer = new JsonRpcServer(myService, MyService.class);
       jsonRpcServer.set...
   }

Я пытаюсь создать файл журнала, содержащий все запросы JSON и ответы JSON. то есть я хотел бы записать входящий запрос JSON RPC до его десериализации и записать исходящий запрос сразу после его сериализации.

Я читал код, и, похоже, нет простого способа сделать это. Кто-нибудь может помочь?

Решение, которое я придумал (которое работает), использует своего рода декорацию, но я не доволен этим:

public class MyServletJsonRpc extends HttpServlet {
   private MyService myService;
   private JsonRpcServer jsonRpcServer;

   @Override
   protected void doPost(HttpServletRequest request
                      , HttpServletResponse response) throws IOException {
      jsonRpcServer.handle(request, response);
   }
   @Override
   public void init(ServletConfig config) {
       myService = new MyServiceImpl();
       ObjectMapper mapper = new MyObjectMapper(null, null, null);
       jsonRpcServer = new MyJsonRpcServer(mapper, myService, null);
       jsonRpcServer.set...
   }
}

Используя следующие 2 перегруженных класса:

class MyObjectMapper extends ObjectMapper {
    private static final Logger L = LoggerFactory.getLogger(MyObjectMapper.class);

    public MyObjectMapper(JsonFactory jf, DefaultSerializerProvider sp, DefaultDeserializationContext dc) {
        super(jf, sp, dc);
    }

    @Override
    public void writeValue(OutputStream out, Object value) throws IOException, JsonGenerationException,
JsonMappingException {
        super.writeValue(out, value);
        L.info("Out: " + writeValueAsString(value));
    }

}

а также

class MyJsonRpcServer extends JsonRpcServer {
    private static final Logger L = LoggerFactory.getLogger(MyJsonRpcServer.class);

    public MyJsonRpcServer(ObjectMapper mapper, Object handler, Class<?> remoteInterface) {
        super(mapper, handler, remoteInterface);
    }

    @Override
    public void handleNode(JsonNode node, OutputStream ops) throws IOException {
        L.info("In: " + (node == null ? "(null)" : node.toString()));
        super.handleNode(node, ops);
    }
}

Я думаю, что это выглядит и ощущается как неприятный хак. Есть ли лучший способ сделать это?

2 ответа

Решение

Библиотека поддерживает использование InvocationListener: https://github.com/briandilley/jsonrpc4j/blob/master/src/main/java/com/googlecode/jsonrpc4j/InvocationListener.java

вы можете добавить его на сервер в ваших сервлетах init() метод и все вызовы пройдут через него.

вот установщик: https://github.com/briandilley/jsonrpc4j/blob/cfdaea92fedf7b43be9d93420df168fe69a5a4fa/src/main/java/com/googlecode/jsonrpc4j/JsonRpcBasicServer.java#L994

Так что просто позвоните server.setInvocationListener и ты в порядке.

Обновление: установка уровня журнала на DEBUG теперь включает журналы с полезными данными.

Другие вопросы по тегам