簡體   English   中英

檢測字符串的有效方法?

[英]Efficient way to detect strings?

我正在一個項目中,在該項目中,我正在使用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,所以我不需要用例,我只需要返回從服務器獲得的響應即可。

在我的用例中,如果它是成功的響應,則不需要反序列化我的響應字符串,因為我們對此沒有任何POJO,並且將返回從服務器獲得的響應字符串。 但是只是為了記錄特定的錯誤消息(如果我從服務器獲取錯誤響應),我正在反序列化它,我認為這是不必要的。 對於我的用例,可能會有更好的解決方案。

下面是我的Java客戶端,它使用future.get調用Callable任務-

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反序列化。

您不需要反序列化為POJO。

一個簡單的JSON解析器(例如在json.org上找到的解析器)將提供最少的JSON解析,以返回您可以查詢的JSONObject。

我非常懷疑

  • 您可以使用正則表達式或其他方式更快地解析json響應,而不會冒在極端情況下失敗的風險
  • 給定響應字符串的大小,JSON解析是代碼中的性能瓶頸

除非您進行了認真的分析,否則我會放心地遵循程序優化的第一條規則

最好將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;
        }

    });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM