2014-01-30 3 views
0

Я работаю над проектом, в котором я звоню на один из моих серверов, используя RestTemplate, который работает с обслуживанием и получает ответ от них.Эффективный способ обнаружения строк?

Ответ, что я буду получать от моего сервера может быть любой из этих ответов об ошибках (это все, что у меня есть для ответа ошибки), если что-то пошло не так -

{"warning": "user_id not found", "user_id": some_user_id} 
{"error": "user_id for wrong partition", "user_id": some_user_id, "partition": some_partition} 
{"error": "missing client id", "client_id":2000} 

или ниже успешного ответа (это может быть любой случайный ключ JSON строка может также быть разными) -

{"@data": {"oo":"1205000384","p":"2047935"} 
  1. Если я получаю никакого ответа об ошибке, как упоминалось выше, то я десериализации его (мой плохой :(), так что я могу войти в их ошибка с специфический error или warning Я получил перед сервером, который может быть, например, - user_id not found или missing client id.
  2. Если это удачный ответ, я также десериализую его, который мне не нужен для моего прецедента, так как у нас нет POJO, и мне просто нужно вернуть ответ, который я получил от сервер.

В моем случае использования мне не нужно десериализовать мою строку ответа, если это удачный ответ, поскольку у нас нет POJO для этого, и мы возвращаем строку ответа, поскольку она есть с сервера. Но просто для регистрации конкретных сообщений об ошибках (если я получаю сообщение об ошибке с сервера), я десериализую его, что, я думаю, не нужно. Возможно, лучшее решение для моего варианта использования.

Ниже мой Java-клиент, который звонит Callable задачу с помощью future.get -

public class TestingClient implements IClient { 

    private ExecutorService service = Executors.newFixedThreadPool(10); 
    private RestTemplate restTemplate = new RestTemplate(); 

    @Override 
    public String executeSync(ClientKey keys) { 

     String response = null; 
     try { 

      ClientTask ClientTask = new ClientTask(keys, restTemplate); 
      Future<String> future = service.submit(ClientTask); 
      response = handle.get(keys.getTimeout(), TimeUnit.MILLISECONDS); 
     } catch (TimeoutException e) { 

     } catch (Exception e) { 

     } 

     return response; 
    } 
} 

А теперь ниже мой ClientTask класс, который реализует интерфейс отзывной. В методе вызова, я генерация URL, а затем нажмите на сервер с помощью RestTemplate и получить ответ обратно -

class ClientTask implements Callable<String> { 

    private ClientKey cKeys; 
    private RestTemplate restTemplate; 

    public ClientTask(ClientKey cKeys, RestTemplate restTemplate) { 
     this.restTemplate = restTemplate; 
     this.cKeys = cKeys; 
    } 

    @Override 
    public String call() throws Exception { 

     // .. some code here 
     String url = "some_url";    
     String response = restTemplate.getForObject(url, String.class); 

     String test = checkJSONResponse(response); 

     return test; 
    } 

    private String checkJSONResponse(final String response) throws Exception { 

     // may be there are some better way of doing it for my scenario instead of using GSON 
     Gson gson = new Gson(); 
     String str = null; 
     JsonObject jsonObject = gson.fromJson(response, JsonObject.class); // parse it, may be performance issues here/ 
     if (jsonObject.has("error") || jsonObject.has("warning")) { 

     final String error = jsonObject.get("error") != null ? jsonObject.get("error").getAsString() : jsonObject 
     .get("warning").getAsString(); 

     // log specific `error` here using log4j 
     str = response; 
     } else { 
      str = response; 
     } 

     return str; 
    } 
} 

Как вы можете увидеть в моем коде выше мы десериализация строки JSON только для регистрации сообщения об ошибках если мы получим ответ об ошибке. Но для успешного ответа нам не нужна десериализация, но мы это делаем.

Есть ли лучший способ решить эту проблему? Поскольку в настоящее время я вижу некоторые проблемы с производительностью при десериализации GSON.

Единственный способ, которым я могу идентифицировать успешный ответ вместе с ответом об ошибке, - это ответ error или warning, поэтому я думаю об использовании регулярных выражений, которые могут идентифицировать ошибку или предупреждение как ключ в строке ответа. Если они содержат ошибку или предупреждение в строке ответа, извлеките конкретное сообщение об ошибке или предупреждение и запишите его. Но не уверен, будет ли это иметь какое-либо преимущество в производительности или нет.

Есть ли другой лучший способ решить эту проблему без использования десериализации GSON.

+1

Лот JSON LIBS там для Java, рекомендовал бы смотреть на [Джексон] (https://github.com/FasterXML/jackson) Лот предмета в этой теме тоже: http://stackoverflow.com/questions/338586/a-better-java-json-library – Durandal

+0

Мне любопытно, какие ваши «проблемы с производительностью», если не предполагалось. В стороне, вы можете просто * разобрать * JSON с использованием класса JsonParser Gson, а затем работать с объектами дерева разбора напрямую, а не десериализовать POJO. Регулярные выражения * намного дороже простого, линейного разбора. –

+0

@BrianRoach: Итак, вы говорите, что я не должен использовать метод 'gson.fromJson' для моего варианта использования, поскольку он будет десериализовать его на POJO. Я не уверен в Gson' JsonParser', можете ли вы привести пример в моем примере используя JsonParser. Это заставит меня понять лучше. –

ответ

0

Рекомендуется использовать коды состояния HTTP для ваших ответов (например, BAD_REQUEST, NOT_FOUND). Верните один из них с сервера, а затем проверьте клиент. Это позволит анализировать ответ только если какой-то возвращается код ошибки:

String result = restTemplate.execute("url", HttpMethod.GET, null, new HttpMessageConverterExtractor<String> { 
     @Override 
     public MyEntity extractData(ClientHttpResponse response) 
     throws IOException { 
      String result = super.extractData(response); 
      if (response.getStatusCode() != HttpStatus.OK) { 
       // parse message and log only for some error code 
       JsonObject errorJson = parse(result); 
       log.warn("Got {} status error, with message [{}]", response.getStatusCode(), errorJson.get("warning")); 
      } 
      return result; 
     } 

    }); 
0

Вам не нужно десериализовать POJO.

Простой парсер JSON, такой как тот, который найден на json.org, предоставит минимальный JSON, анализирующий возврат JSONObject, который вы можете запросить.

Я очень сильно сомневаюсь, что

  • вы можете придумать более быстрый синтаксический анализ ваших ответов JSON с помощью регулярных выражений или иным образом, не принимая риск неудачи в угловых случаях
  • учитывая размер вашего строки ответа, что JSON синтаксический является узким местом в вашем коде

Если вы не сделали некоторое серьезное профилирование, я хотел бы играть безопасно и следовать the first rule of program optimization

Смежные вопросы