Java生成字符串到编码字符串

Java生成字符串到编码字符串,java,encoding,utf-8,Java,Encoding,Utf 8,从服务器获取http的路径是: //HTTP获取请求 私有静态列表sendGet()引发异常{ String url = "http://********/ReciveMessage"; URL obj = new URL(url); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); // optional default is GET con.setRequestMet

从服务器获取http的路径是: //HTTP获取请求 私有静态列表sendGet()引发异常{

    String url = "http://********/ReciveMessage";

    URL obj = new URL(url);
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();

    // optional default is GET
    con.setRequestMethod("GET");

    //add request header

    con.setRequestProperty("Accept-Charset", "UTF-8");

    int responseCode = con.getResponseCode();

    BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream(),"UTF-8"));
    String inputLine;
    StringBuffer response = new StringBuffer();

    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
        System.out.println(inputLine);
    }
    in.close();


    String str = response.toString(); //str is the problem


}
我从服务器上得到一个字符串, 看起来是这样的:

str = "\\u05d0";
我注意到我无法解码字符串

所以我很想知道如何做到这一点

str = "\u05d0";

假设您的服务器只返回按您描述的格式编码的Unicode码点流(例如,没有原始字符,仅返回
\u1234
格式的码点),则以下代码将把这样的序列转换为解码字符:

public class UnicodeDecoder {

    private static final Pattern UNICODE_CHARACTER_PATTERN =
            Pattern.compile("\\\\u([0-9A-Fa-f]{2,4})");

    public static void main(String[] args) {
        String raw = "\\u05d0\\u05d1\\u05d2\\u05d3";

        StringBuilder sb = new StringBuilder(raw.length() / 7);

        Matcher matcher = UNICODE_CHARACTER_PATTERN.matcher(raw);
        while (matcher.find()) {
            String hexCode = matcher.group(1);
            char[] decodedChars = Character.toChars(
                    Integer.valueOf(hexCode, 16));
            sb.append(decodedChars);
        }

        System.out.println("Raw:\n"+raw);
        System.out.println("Decoded:\n"+sb.toString());
    }   
}
此示例代码给出了以下输出:

Raw:
\u05d0\u05d1\u05d2\u05d3
Decoded:
אבגד
请注意,此方法效率不高。如果性能很重要,则可以重新编写此方法,手动获取每个
\u1234
序列的子字符串,然后将解码字符添加到子字符串中。这将消除正则表达式匹配器的成本


如果您的服务器返回的字符不是Unicode代码点,那么您必须逐个字符浏览服务器的响应,检查
\u1234
序列。任何不是Unicode代码点序列的内容都应直接添加到
StringBuilder
;任何Unicode代码点的内容应该先将t解码为字符。

我使用Bobulus解决方案并对其进行了修改,现在它可以在同一字符串中使用ASCII和UTF-8:

private String Decode(String raw) {
    final Pattern UNICODE_CHARACTER_PATTERN = Pattern.compile("\\\\u([0-9A-Fa-f]{2,4})");

    StringBuilder sb = new StringBuilder(raw.length() / 7);

    Matcher matcher = UNICODE_CHARACTER_PATTERN.matcher(raw);

    while (raw.length() != 0) {
        if (raw.charAt(0) == '\\') {
            matcher = UNICODE_CHARACTER_PATTERN.matcher(raw);
            String hexCode = "";
            char[] decodedChars = null;
            boolean find = false;
            if (matcher.find()) {
                find = true;
                hexCode = matcher.group(1);
                decodedChars = Character.toChars(Integer.valueOf(hexCode, 16));
                sb.append(decodedChars);
            }
            if(find)
                raw = raw.substring(matcher.group(0).length());
            else {
                if(raw.length() > 2) {
                    char c = (raw.charAt(1));
                    raw = raw.substring(2);
                    switch(c) {
                        case 'n':
                            sb.append("\n");
                            break;
                        case 't':
                            sb.append("\t");
                            break;
                        case 'b':
                            sb.append("\b");
                            break;
                        case 'r':
                            sb.append("\r");
                            break;
                        case 'f':
                            sb.append("\f");
                            break;
                        case '\'':
                            sb.append("\\");
                            break;
                        case '\"':
                            sb.append("\"");
                            break;
                        default:
                            sb.append("\\"+c);
                            break;
                    }
                }else {
                    raw = raw.substring(1);
                    sb.append("\\");
                }
            }
        } else {
            sb.append(raw.charAt(0));
            raw = raw.substring(1);
        }
    }       

    return sb.toString();
}

更新:添加\n、\t等的大小写。

啊,添加了很好的详细信息。还有一个:HTTP响应头内容类型的值是多少?我猜是JSON。我怎么也可以包含ascii字符呢?@yeo4你的意思是什么?如果不是,你说的哪个标准或规范引用了ascii的使用?你从哪里得到“{2,4}”(与“{4}”相反)?这与Java、JavaScript、JSON、C#、..@TomBlodget不兼容。字符类后面的语法
{2,4}
表示“需要前面字符类中至少两个字符,最多四个字符”,并且它在Java和JavaScript中的正则表达式模式中有效。我不知道C#,也不知道JSON块如何包含正则表达式。此实现效率非常低,不适合很长的输入字符串。正在为每个字符创建一个新的正则表达式匹配器对象和一个新的字符串对象,并且此我会造成大量垃圾堆积。正如我在回答中提到的,一个严肃的解决方案将需要手动解析输入字符串,而不是使用正则表达式。如果还要匹配和提取文字字符,这一点就变得尤为重要。@Bobulus确信正则表达式是有意义的,但问题是输入的格式是什么。\u是否使用正则表达式d在各种编程语言和数据交换格式中,但我所知道的所有格式都需要4个十六进制数字。HTTP响应头内容类型应该说明这一点。(是的,正则表达式中的术语是贪婪的,因此会像预期的那样解析4个十六进制数字,但它可能会产生误导,并避免了基本问题。)