首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2ME

J2ME 平台 URLEncoder 實作類:支援 UTF-8 中文編碼

     編輯:J2ME

背景

J2ME 無 java.net.URLEncoder,需自行實作 application/x-www-form-urlencoded 編碼,以便向伺服器傳送中文參數。

使用範例

String data = "param=" + URLEncoder.encode("中文參數");
outputStream.write(data.getBytes());
// 伺服端 (Servlet): request.getParameter("param") 即得 "中文參數"

核心代碼 (URLEncoder.java)

package com.j2medev.httpme.tools;

import java.io.*;

public class URLEncoder {
    private static boolean[] dontNeedEncoding;
    private static String defaultEncName;
    static final int CASE_DIFF = 'a' - 'A';

    static {
        dontNeedEncoding = new boolean[256];
        for (int i = 'a'; i <= 'z'; i++) dontNeedEncoding[i] = true;
        for (int i = 'A'; i <= 'Z'; i++) dontNeedEncoding[i] = true;
        for (int i = '0'; i <= '9'; i++) dontNeedEncoding[i] = true;
        dontNeedEncoding[' '] = true; // 空格稍後轉 '+'
        dontNeedEncoding['-'] = true;
        dontNeedEncoding['_'] = true;
        dontNeedEncoding['.'] = true;
        dontNeedEncoding['*'] = true;
        defaultEncName = System.getProperty("microedition.encoding");
        if (defaultEncName == null || defaultEncName.trim().length() == 0) {
            defaultEncName = "UTF-8";
        }
    }

    private URLEncoder() {}

    public static String encode(String s) {
        return encode(s, defaultEncName);
    }

    public static String encode(String s, String enc) {
        StringBuffer out = new StringBuffer(s.length());
        ByteArrayOutputStream buf = new ByteArrayOutputStream();
        OutputStreamWriter writer = null;
        try { writer = new OutputStreamWriter(buf, enc); }
        catch (UnsupportedEncodingException e) {
            try { writer = new OutputStreamWriter(buf, defaultEncName); }
            catch (UnsupportedEncodingException ignored) {}
        }

        boolean needToChange = false;
        boolean wroteUnencoded = false;

        for (int i = 0; i < s.length(); i++) {
            int c = s.charAt(i);
            if (c < 256 && dontNeedEncoding[c]) {
                if (c == ' ') { c = '+'; needToChange = true; }
                out.append((char) c);
                wroteUnencoded = true;
            } else {
                // 需編碼字元
                try {
                    if (wroteUnencoded) {
                        writer = new OutputStreamWriter(buf, enc);
                        wroteUnencoded = false;
                    }
                    if (writer != null) writer.write(c);
                    // 處理 Surrogate Pair
                    if (c >= 0xD800 && c <= 0xDBFF && i + 1 < s.length()) {
                        int d = s.charAt(i + 1);
                        if (d >= 0xDC00 && d <= 0xDFFF) {
                            writer.write(d);
                            i++;
                        }
                    }
                    writer.flush();
                } catch (IOException e) {
                    buf.reset(); continue;
                }
                byte[] ba = buf.toByteArray();
                for (byte b : ba) {
                    out.append('%');
                    char ch = forDigit((b >> 4) & 0xF, 16);
                    if (isLetter(ch)) ch -= CASE_DIFF;
                    out.append(ch);
                    ch = forDigit(b & 0xF, 16);
                    if (isLetter(ch)) ch -= CASE_DIFF;
                    out.append(ch);
                }
                buf.reset();
                needToChange = true;
            }
        }
        return needToChange ? out.toString() : s;
    }

    private static boolean isLetter(char c) {
        return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
    }
    private static char forDigit(int digit, int radix) {
        if (digit < 0 || digit >= radix) return '\0';
        if (radix < 2 || radix > 36) return '\0';
        return (char) (digit < 10 ? '0' + digit : 'a' - 10 + digit);
    }
}

測試驗證

已於多款手機 (Nokia, Sony Ericsson, Motorola) 實測通過,正確編碼中文並被伺服端 (Servlet/PHP/ASP.NET) 正確解碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved