来自API的奇怪字符串的java字符编码

2024-02-11

我对 API 的响应遇到了奇怪的问题。我正在使用 apache HTTP 客户端来获取响应。响应头有以下内容

Content-Type=[application/json; charset=utf-16]
Transfer-Encoding=[chunked]
X-Powered-By=[ASP.NET] // Yes, people using ASP.NET

因此,基于此,当我收到回复时,我的回复如下所示

笀∀匀琀愀琀甀猀䌀漀搀攀∀㨀㈀ 

所以我尝试了以下方法。

String body = "笀∀匀琀愀琀甀猀䌀漀搀攀∀㨀㈀";
String charSetString = "utf-8|utf-16|utf-16le, all possible combination"
body = new String(body.getBytes(Charset.forName(charSetString));
body = body.replaceAll("[^\\x00-\\x7F]", "");

但没有运气。开始看第一个字符。第一个字符的实际响应是{我将第一个字符从响应转换为 ascii

(int)body.charAt(0) 

值为31488;而 Ascii 值{是 123;如果我做31488/256 = 123并将其转换为 char 给我{所以我做了以下事情

String encoded = "";
for(int i=0; i< body.length(); i++) {
    encoded += ((char) ((int)body.charAt(i) / 256 ));
}

它起作用了。但对于单个 API 来说,这是非常糟糕的对话。我缺少什么,如果我得到响应的字符集到底是什么31488 for {

Update

我的API调用代码。

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.util.SerializationUtils;
import org.springframework.web.client.RestTemplate;


public class HTTPClientManager {
    RestTemplate restTemplate = null;

    public void setup() {

        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = null;
            clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(
                    HttpClientBuilder.create().build());
        clientHttpRequestFactory.setReadTimeout(5 * 1000);
        clientHttpRequestFactory.setConnectTimeout(5 * 1000);
        restTemplate = new RestTemplate(clientHttpRequestFactory);
    }

    public static void main(String...strings) throws FileNotFoundException, IOException {
        HTTPClientManager ht = new HTTPClientManager();
        ht.setup();
        Map<String, Object> properties = new LinkedHashMap<>();
        properties.put(Const.METHOD, "GET");
        properties.put(Const.URL, strings[0]);
        properties.put(Const.CHAR_SET, "UTF-16LE");

        Map<String, Object> ob = ht.getResponse(properties);
        try {
            String res = ob.get(Const.RESPONSE).toString();
            System.out.println("Response ->>>>>>>>> \n " + res);
        }catch(Exception e) {
            e.printStackTrace();
        }

       try (FileOutputStream fos = new FileOutputStream("response")) {
            fos.write(SerializationUtils.serialize(ob));
       }
    }

    public static class Const {
        public static final String REQUEST = "request";
        public static final String URL = "url";
        public static final String CHAR_SET = "charSet";
        public static final String RESPONSE = "response";
        public static final String METHOD = "method";
        public static final String REQUEST_HEADER = "reqHeader";
        public static final String RESPONSE_HEADER = "resHeader";
    }



    public Map<String, Object> getResponse(Map<String, Object> properties) {
        HttpHeaders headers = new HttpHeaders();
        HttpEntity requestEntity = null;
        Map<String, Object> responseReturn = new LinkedHashMap<>();
        HttpMethod method = null;

        if (properties.get(Const.METHOD).toString().equals("GET")) {
            method = HttpMethod.GET;
            requestEntity = new HttpEntity<String>("", headers);
        } else if (properties.get(Const.METHOD).toString().equals("POST")) {
            method = HttpMethod.POST;
            requestEntity = new HttpEntity<String>(properties.get(Const.REQUEST).toString(), headers);
        }else if (properties.get(Const.METHOD).toString().equals("PUT")) {
            method = HttpMethod.PUT;
            requestEntity = new HttpEntity<String>(properties.get(Const.REQUEST).toString(), headers);
        }else if (properties.get(Const.METHOD).toString().equals("DELETE")) {
            method = HttpMethod.DELETE;
            requestEntity = new HttpEntity<String>(properties.get(Const.REQUEST).toString(), headers);
        }
        ResponseEntity<String> response = null;
        try {
            response = restTemplate.exchange(properties.get(Const.URL).toString(), method, requestEntity, String.class);
            String body = response.getBody();
            if(properties.get(Const.CHAR_SET) != null) {
                try {
                body = new String(body.getBytes(Charset.forName(properties.get(Const.CHAR_SET).toString())));
                body = body.replaceAll("[^\\x00-\\x7F]", "");
                }catch(Exception e) {
                    e.printStackTrace();
                }
            }
            responseReturn.put(Const.RESPONSE, body!=null?body:"");
            responseReturn.put(Const.RESPONSE_HEADER, response.getHeaders());
        } catch (org.springframework.web.client.HttpClientErrorException |org.springframework.web.client.HttpServerErrorException  exception) {
            exception.printStackTrace();
        }catch(org.springframework.web.client.ResourceAccessException exception){
            exception.printStackTrace();
        }catch(Exception exception){
            exception.printStackTrace();
        }

        return responseReturn;
    }

}

我认为你的问题是你错误地假设你的回复是UTF-16,即你的行Content-Type=[application/json; charset=utf-16]是错的。尝试删除字符集部分(Content-Type=[application/json]) 或将其设置为 UTF-8 (Content-Type=[application/json; charset=utf-8])然后看看会发生什么。我相信您得到的答复是:{"StatusCode":2。不知道为什么回复末尾似乎缺少“}”,但除此之外它是有道理的。顺便说一句,我设法通过将您的回复字符串转换为 unicode 序列来解释您的回复。这给了我顺序:\u7b00\u2200\u5300\u7400\u6100\u7400\u7500\u7300\u4300\u6f00\u6400\u6500\u2200\u3a00\u3200。这给出了这样的想法:通过强制将响应解释为 utf-16,你搞乱了内容。所以如果我将顺序更改为\u007b\u0022\u0053\u0074\u0061\u0074\u0075\u0073\u0043\u006f\u0064\u0065\u0022\u003a\u0032并将其从我得到的 unicodes 转换回 String{"StatusCode":2.

顺便说一句,如果您对将任何字符串转换为 unicode 序列(反之亦然)的工具感兴趣,那么您可以使用 MgntUtils 开源库(由我编写)。我所要做的就是转换您的响应字符串:

String result = "笀∀匀琀愀琀甀猀䌀漀搀攀∀㨀㈀";
        result = StringUnicodeEncoderDecoder.encodeStringToUnicodeSequence(result);
        System.out.println(result);

这里是link https://www.linkedin.com/pulse/open-source-java-library-some-useful-utilities-michael-gantman/到描述库中的实用程序以及从哪里获取它的文章(可在github https://github.com/michaelgantman/Mgnt and Maven中央 https://search.maven.org/#artifactdetails%7Ccom.github.michaelgantman%7CMgntUtils%7C1.5.0.2%7Cjar)

在文章中查找段落“字符串 Unicode 转换器” 来解释此功能。该库还包含一个简单的 Http 客户端功能(本文中未描述,但在其 javadoc 中进行了描述)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

来自API的奇怪字符串的java字符编码 的相关文章

随机推荐