0

@wenshao springmvc を使用して他の API インターフェイスを要求する Web サイトがあります。メソッドを使用し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 インターフェイスが表示されます。 springmvc を使用してリクエストすると -1 になります。

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の実際の長さを返しますが、スプリングは返しません。 壊れたリクエスト

郵便配達員を使用してリクエストを修正する

正しい長さ

編集:エラーが発生した理由を見つけました.リクエストjsonで中国語を渡したので.どうすれば解決できますか?

4

1 に答える 1

1

私はそれを解決しました。正しいコード:

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

不正なコード:

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

私のシステムのデフォルトのエンコーディングは utf-8 ではなく gbk であるためです。

于 2017-08-15T09:07:07.283 に答える