public static ETag parseETag(final String tag) {
        if (tag == null) {
            return null;
        }
        char[] headerChars = tag.toCharArray();
        SearchingFor searchingFor = SearchingFor.START_OF_VALUE;
        int valueStart = 0;
        boolean weak = false;
        boolean malformed = false;
        for (int i = 0; i < headerChars.length; i++) {
            switch (searchingFor) {
                case START_OF_VALUE:
                    if (headerChars[i] != COMMA && !Character.isWhitespace(headerChars[i])) {
                        if (headerChars[i] == QUOTE) {
                            valueStart = i + 1;
                            searchingFor = SearchingFor.LAST_QUOTE;
                            weak = false;
                            malformed = false;
                        } else if (headerChars[i] == W) {
                            searchingFor = SearchingFor.WEAK_SLASH;
                        }
                    }
                    break;
                case WEAK_SLASH:
                    if (headerChars[i] == QUOTE) {
                        valueStart = i + 1;
                        searchingFor = SearchingFor.LAST_QUOTE;
                        weak = true;
                        malformed = false;
                    } else if (headerChars[i] != SLASH) {
                        return null; //malformed
                    }
                    break;
                case LAST_QUOTE:
                    if (headerChars[i] == QUOTE) {
                        String value = String.valueOf(headerChars, valueStart, i - valueStart);
                        return new ETag(weak, value.trim());
                    }
                    break;
                case END_OF_VALUE:
                    if (headerChars[i] == COMMA || Character.isWhitespace(headerChars[i])) {
                        if (!malformed) {
                            String value = String.valueOf(headerChars, valueStart, i - valueStart);
                            return new ETag(weak, value.trim());
                        }
                    }
                    break;
            }
        }
        if (searchingFor == SearchingFor.END_OF_VALUE || searchingFor == SearchingFor.LAST_QUOTE) {
            if (!malformed) {
                // Special case where we reached the end of the array containing the header values.
                String value = String.valueOf(headerChars, valueStart, headerChars.length - valueStart);
                return new ETag(weak, value.trim());
            }
        }

        return null;
    }
copy from io.undertow.util.ETagUtils
web/src/main/java/com/navercorp/pinpoint/web/util/etag/ETagUtils.java