0

@wenshao 我有一个网站使用 springmvc 来请求其他 api 接口。我使用HttpHelper.doPost请求的方法。

public static String doPost(String url, String json,String... args) throws Exception {
    URL localURL = new URL(url);

    URLConnection connection = localURL.openConnection();
    HttpURLConnection httpURLConnection = (HttpURLConnection) connection;

    String encoding = getEncoding(args);
    int connectTimeout = getConnectTimeout(args);
    int readTimeout = getReadTimeout(args);

    httpURLConnection.setDoOutput(true);
    httpURLConnection.setRequestMethod("POST");
    httpURLConnection.setRequestProperty("Accept-Charset", encoding);
    httpURLConnection.setConnectTimeout(connectTimeout);
    httpURLConnection.setReadTimeout(readTimeout);
    httpURLConnection.setRequestProperty("Content-Type", "application/json");
    httpURLConnection.setRequestProperty("Content-Length", String.valueOf(json.length()));

    OutputStream outputStream = null;
    OutputStreamWriter outputStreamWriter = null;
    InputStream inputStream = null;
    InputStreamReader inputStreamReader = null;
    BufferedReader reader = null;
    StringBuffer resultBuffer = new StringBuffer();
    String tempLine;

    try {
        outputStream = httpURLConnection.getOutputStream();
        outputStreamWriter = new OutputStreamWriter(outputStream);

        outputStreamWriter.write(json);
        outputStreamWriter.flush();

        if (httpURLConnection.getResponseCode() >= 400) {
            inputStream = httpURLConnection.getErrorStream();
        } else {
            inputStream = httpURLConnection.getInputStream();
        }
        inputStreamReader = new InputStreamReader(inputStream, encoding);
        reader = new BufferedReader(inputStreamReader);

        while ((tempLine = reader.readLine()) != null) {
            resultBuffer.append(tempLine);
        }
    } finally {
        close(outputStreamWriter, outputStream, reader, inputStreamReader, inputStream);
    }
    return String.valueOf(resultBuffer);
}

如果我使用上面的代码使用单元测试来请求 api,它工作正常。但是当我使用 springmvc 操作来请求它时,它给了我服务器错误 500:index out of range -1 from the api interface。下面的代码总是返回-1 当我使用 springmvc 请求它时。

public static int decodeUTF8(byte[] sa, int sp, int len, char[] da) {
    final int sl = sp + len;
    int dp = 0;
    int dlASCII = Math.min(len, da.length);

    // ASCII only optimized loop
    while (dp < dlASCII && sa[sp] >= 0)
        da[dp++] = (char) sa[sp++];

    while (sp < sl) {
        int b1 = sa[sp++];
        if (b1 >= 0) {
            // 1 byte, 7 bits: 0xxxxxxx
            da[dp++] = (char) b1;
        } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) {
            // 2 bytes, 11 bits: 110xxxxx 10xxxxxx
            if (sp < sl) {
                int b2 = sa[sp++];
                if ((b2 & 0xc0) != 0x80) { // isNotContinuation(b2)
                    return -1;
                } else {
                    da[dp++] = (char) (((b1 << 6) ^ b2)^
                                   (((byte) 0xC0 << 6) ^
                                    ((byte) 0x80 << 0)));
                }
                continue;
            }
            return -1;
        } else if ((b1 >> 4) == -2) {
            // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx
            if (sp + 1 < sl) {
                int b2 = sa[sp++];
                int b3 = sa[sp++];
                if ((b1 == (byte) 0xe0 && (b2 & 0xe0) == 0x80) //
                    || (b2 & 0xc0) != 0x80 //
                    || (b3 & 0xc0) != 0x80) { // isMalformed3(b1, b2, b3)
                    return -1;
                } else {
                    char c = (char)((b1 << 12) ^
                                      (b2 <<  6) ^
                                      (b3 ^
                                      (((byte) 0xE0 << 12) ^
                                      ((byte) 0x80 <<  6) ^
                                      ((byte) 0x80 <<  0))));
                    boolean isSurrogate =  c >= Character.MIN_SURROGATE && c < (Character.MAX_SURROGATE + 1);
                    if (isSurrogate) {
                        return -1;
                    } else {
                        da[dp++] = c;
                    }
                }
                continue;
            }
            return -1;
        } else if ((b1 >> 3) == -2) {
            // 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
            if (sp + 2 < sl) {
                int b2 = sa[sp++];
                int b3 = sa[sp++];
                int b4 = sa[sp++];
                int uc = ((b1 << 18) ^
                          (b2 << 12) ^
                          (b3 <<  6) ^
                          (b4 ^
                           (((byte) 0xF0 << 18) ^
                           ((byte) 0x80 << 12) ^
                           ((byte) 0x80 <<  6) ^
                           ((byte) 0x80 <<  0))));
                if (((b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80 || (b4 & 0xc0) != 0x80) // isMalformed4
                    ||
                    // shortest form check
                    !Character.isSupplementaryCodePoint(uc)) {
                    return -1;
                } else {
                    da[dp++] =  (char) ((uc >>> 10) + (Character.MIN_HIGH_SURROGATE - (Character.MIN_SUPPLEMENTARY_CODE_POINT >>> 10))); // Character.highSurrogate(uc);
                    da[dp++] = (char) ((uc & 0x3ff) + Character.MIN_LOW_SURROGATE); // Character.lowSurrogate(uc);
                }
                continue;
            }
            return -1;
        } else {
            return -1;
        }
    }
    return dp;
}

正常将返回我的请求 json 的实际长度,但 spring 不会。 请求中断

使用邮递员请求的正确请求

正确的长度

编辑:我找到了发生错误的原因。因为我在请求json中传递了中文。我该如何解决?

4

1 回答 1

1

我已经解决了。正确的代码:

new String(request.getRealName().getBytes(),"utf-8")

错误代码:

new String(request.getRealName().getBytes("utf-8"),"utf-8")

因为我系统的默认编码是 gbk 而不是 utf-8。

于 2017-08-15T09:07:07.283 回答