检测字符串的有效方法?

时间:2014-01-30 04:07:35

标签: java json deserialization gson

我正在开展一个项目,我正在使用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. 如果我收到上面提到的任何错误响应,那么我将其反序列化(我的错误:()以便我可以将它们记录为具有特定errorwarning的错误在服务器前面,例如 - user_id not foundmissing client id
  2. 如果它是一个成功的回复,那么我也反序列化它我不需要我的用例,因为我们没有任何POJO我只需要返回响应,因为它是我来自服务器。
  3. 在我的用例中,如果响应成功,我不需要反序列化我的响应字符串,因为我们没有任何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类,它实现了Callable接口。在call方法中,我正在生成一个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反序列化的一些性能问题。

    我能够识别成功响应以及错误响应的唯一方法是在响应中使用errorwarning,因此我正在考虑使用正则表达式来识别错误或警告作为关键字响应字符串。如果它们在响应字符串中包含错误或警告,则提取特定的错误或警告消息并进行记录。但不确定这是否会带来任何性能上的好处。

    如果不使用GSON反序列化,还有其他更好的解决方法吗?

2 个答案:

答案 0 :(得分:0)

您无需反序列化为POJO。

一个简单的JSON解析器,例如在json.org上找到的解析器,将提供最小的JSON解析,并返回一个可以查询的JSONObject。

我非常怀疑

  • 您可以使用正则表达式或其他方式更快地解析您的json响应,而不会冒着在极端情况下失败的风险
  • 根据响应字符串的大小,JSON解析是代码中的性能瓶颈

除非你做了一些严肃的剖析,否则我会安全地遵循the first rule of program optimization

答案 1 :(得分: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;
        }

    });