首页 新闻 会员 周边 捐助

如何在后台接收到正确的值

0
悬赏园豆:50 [已解决问题] 解决于 2025-10-24 16:39

如题,在一个html中指定编码为GBK,后台代码编码为UTF-8,在不修改html代码的情况下,如何在接口中获取或者转换成正确的值

按时睡觉。的主页 按时睡觉。 | 初学一级 | 园豆:197
提问于:2022-12-07 09:22
< >
分享
最佳答案
0

多年后chatGPT给的方案

@GetMapping(value = "test", produces = BaseConstant.REQUEST_HEADERS_CONTENT_TYPE)
@ApiOperation(value = "test", notes = "test")
public String test(HttpServletRequest request) throws Exception {
/// 尝试从原始位置获取参数(优先 GET queryString,再尝试 POST body)
String retMsg = getRawParameter(request, "ret_msg", "GBK");
if (retMsg == null) {
// 回退到常规方式(容器解析)——但注意:如果容器已错误解码,可能是 "????"
String normal = request.getParameter("ret_msg");
return normal != null ? ("fallback:" + normal) : "no ret_msg";
}
System.out.println("decoded ret_msg = " + retMsg);
return retMsg;
}

/**
 * 从原始请求(queryString 或 body)中解析指定参数,使用指定 charset 进行 URL 解码。
 * 仅适用于 application/x-www-form-urlencoded 的场景。
 *
 * @param request HttpServletRequest
 * @param name 参数名
 * @param charsetName 如 "GBK"
 * @return 解码后的参数值 或 null(未找到)
 */
private String getRawParameter(HttpServletRequest request, String name, String charsetName) throws IOException {
    // 1) 优先处理 GET query string(raw)
    String query = request.getQueryString();
    if (query != null && !query.isEmpty()) {
        String v = extractFromUrlEncoded(query, name, charsetName);
        if (v != null) return v;
    }

    // 2) 如果是 POST 并且 content-type 是 application/x-www-form-urlencoded,读取 raw body
    String method = request.getMethod();
    String contentType = request.getContentType();
    if ("POST".equalsIgnoreCase(method) && contentType != null &&
            contentType.toLowerCase().startsWith("application/x-www-form-urlencoded")) {

        // 注意:如果其他过滤器/拦截器/框架早已读取过 request.getInputStream() 或 getParameter,
        // 那这里就无法再次读取到原始 body。确保此段在参数被访问之前运行。
        byte[] bodyBytes = readRequestBody(request);
        if (bodyBytes != null) {
            // body 是 URL encoded 的字节序列,用给定 charset 解析
            String body = new String(bodyBytes, charsetName);
            String v = extractFromUrlEncoded(body, name, charsetName);
            if (v != null) return v;
        }
    }

    // 3) 未命中,返回 null
    return null;
}

// 读取 request body 原始字节
private byte[] readRequestBody(HttpServletRequest request) throws IOException {
    int contentLength = request.getContentLength();
    ServletInputStream in = request.getInputStream();
    if (contentLength > 0) {
        byte[] buf = new byte[contentLength];
        int read = 0;
        while (read < contentLength) {
            int r = in.read(buf, read, contentLength - read);
            if (r < 0) break;
            read += r;
        }
        return buf;
    } else {
        // contentLength 未提供时,读取到 EOF
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] tmp = new byte[4096];
        int r;
        while ((r = in.read(tmp)) != -1) {
            baos.write(tmp, 0, r);
        }
        return baos.toByteArray();
    }
}

// 从 URL-encoded 的字符串里提取指定参数(支持多个同名参数,返回第一个)
private String extractFromUrlEncoded(String urlEncoded, String name, String charsetName) throws UnsupportedEncodingException {
    if (urlEncoded == null || urlEncoded.length() == 0) return null;
    // 例如 urlEncoded: "ret_msg=%B1%...&x=1"
    String[] pairs = urlEncoded.split("&");
    for (String p : pairs) {
        int idx = p.indexOf('=');
        String k, v;
        if (idx >= 0) {
            k = p.substring(0, idx);
            v = p.substring(idx + 1);
        } else {
            k = p;
            v = "";
        }
        // 名称与值均是 URL encoded bytes,先按给定 charset 解码
        String dk = urlDecode(k, charsetName);
        if (name.equals(dk)) {
            return urlDecode(v, charsetName);
        }
    }
    return null;
}

// URL decode 指定编码(与 java.net.URLDecoder 不同:URLDecoder.decode 默认用 platform 编码,显式指定 charset)
private String urlDecode(String s, String charsetName) throws UnsupportedEncodingException {
    if (s == null) return null;
    // Use URLDecoder with charset
    return java.net.URLDecoder.decode(s, charsetName);
}
按时睡觉。 | 初学一级 |园豆:197 | 2025-10-24 16:38
其他回答(3)
0

public void test3() throws UnsupportedEncodingException {
String test = "测试";
String test_gbk_utf8 = new String(test.getBytes(StandardCharsets.UTF_8), "gbk");
System.out.println(test_gbk_utf8);//娴嬭瘯
String test_utf8_gbk = new String(test_gbk_utf8.getBytes("gbk"), StandardCharsets.UTF_8);
System.out.println(test_utf8_gbk);//测试

}

 

Biuget-Golang | 园豆:838 (小虾三级) | 2022-12-07 16:48

String test_gbk_utf8 = new String(test.getBytes("gbk"),StandardCharsets.UTF_8 );
实际上我需要的是这种,把这个test_gbk_utf8转换成正确的值。。。

支持(0) 反对(0) 按时睡觉。 | 园豆:197 (初学一级) | 2022-12-07 17:37

@我恰芙蓉王: 思路就是这样,转成你想要的码就行。让别人直接写出答案是不现实的

支持(0) 反对(0) Biuget-Golang | 园豆:838 (小虾三级) | 2022-12-07 17:42

@Biuget-Golang: 没办法,试过很多种方式,new String("字符串".getBytes("gbk"), "utf-8"),这种怎么样都转不回来

支持(0) 反对(0) 按时睡觉。 | 园豆:197 (初学一级) | 2022-12-07 17:46
0

gbk 解码 然后utf编码试试

_Y_h | 园豆:416 (菜鸟二级) | 2022-12-07 16:48
0

接口中获取时不能用string, 用ArrayBuffer 进行两次转换就可以了
用了string就可能会数据错误

收获园豆:50
Yofoo | 园豆:478 (菜鸟二级) | 2024-02-15 00:55
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册