我們學習java
基礎的時候.
我們都知道在main
方法中String
的getBytes()
方法如果不指定編碼格式,
默認是UTF-8
的方法進行的編碼.
我們一直認為默認的編碼格式就是UTF-8.
直到我們學習了javaWeb.
在Servlet
中.
我們通過getBytes()
獲取的是按照GBK
進行編碼的.
至此我們就有了疑惑.
這個getBytes()
方法到底是怎么選擇默認編碼的.
我們帶着疑惑,
去翻一下String
的源代碼.
[AppleScript]
純文本查看 復制代碼
1
2
3
|
public byte[] getBytes
(
)
{
return
StringCoding.encode
(
value
,
0
,
value
.length
)
;
}
|
繼續跟進StringCoding的encode方法
[AppleScript]
純文本查看 復制代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
static byte[] encode
(
char[] ca
,
int off
,
int len
)
{
String csn
=
Charset.defaultCharset
(
)
.
name
(
)
;
try
{
/
/
use charset
name
encode
(
)
variant which provides caching.
return
encode
(
csn
,
ca
,
off
,
len
)
;
}
catch
(
UnsupportedEncodingException x
)
{
warnUnsupportedCharset
(
csn
)
;
}
try
{
return
encode
(
"ISO-8859-1"
,
ca
,
off
,
len
)
;
}
catch
(
UnsupportedEncodingException x
)
{
/
/
If this code
is
hit during VM initialization
,
MessageUtils
is
/
/
the
only way we will be able
to
get
any kind
of
error
message
.
MessageUtils.err
(
"ISO-8859-1 charset not available: "
+
x.toString
(
)
)
;
/
/
If we can
not
find ISO
-8859
-1
(
a required encoding
)
then
things
/
/
are seriously wrong
with
the
installation.
System.exit
(
1
)
;
return
null;
}
}
|
從以上源碼中可以看出是通過
[AppleScript]
純文本查看 復制代碼
1
|
String csn
=
Charset.defaultCharset
(
)
.
name
(
)
;
|
來獲取默認編碼方式的.我們繼續跟進.查看Charset的defaultCharSet()方法.
[AppleScript]
純文本查看 復制代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
public static Charset defaultCharset
(
)
{
if
(
defaultCharset
=
=
null
)
{
synchronized
(
Charset.
class
)
{
String csn
=
AccessController.doPrivileged
(
new
GetPropertyAction
(
"file.encoding"
)
)
;
Charset cs
=
lookup
(
csn
)
;
if
(
cs !
=
null
)
defaultCharset
=
cs;
else
defaultCharset
=
forName
(
"UTF-8"
)
;
}
}
return
defaultCharset;
}
|
從以上源碼中我們不難看出,不出異常的情況下.默認編碼是由file.encoding決定的.我們分別在main方法和Servlet中去獲取file.encoding去測試一下.
[AppleScript]
純文本查看 復制代碼
1
2
3
4
5
6
7
|
public
class
Demo
{
public static void
main
(
String[] args
)
{
System.out.println
(
"file.encoding="
+
System.getProperty
(
"file.encoding"
)
)
;
byte[] bytes
=
"黑馬程序員"
.getBytes
(
)
;
System.out.println
(
Arrays.toString
(
bytes
)
)
;
}
}
|
輸出結果是
[AppleScript]
純文本查看 復制代碼
1
2
|
file
.encoding
=
UTF
-8
[
-23
,
-69
,
-111
,
-23
,
-87
,
-84
,
-25
,
-88
,
-117
,
-27
,
-70
,
-113
,
-27
,
-111
,
-104
]
|
在Servlet中的測試代碼:
[AppleScript]
純文本查看 復制代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
|
@WebServlet
(
"/user/findAllServlet"
)
public
class
ServletDemo
1
extends HttpServlet
{
protected void doPost
(
HttpServletRequest request
,
HttpServletResponse response
)
throws ServletException
,
IOException
{
System.out.println
(
"findAllServlet..."
)
;
System.out.println
(
"file.encoding="
+
System.getProperty
(
"file.encoding"
)
)
;
byte[] bytes
=
"黑馬程序員"
.getBytes
(
)
;
System.out.println
(
Arrays.toString
(
bytes
)
)
;
}
protected void doGet
(
HttpServletRequest request
,
HttpServletResponse response
)
throws ServletException
,
IOException
{
this.doPost
(
request
,
response
)
;
}
}
|
輸出結果是:
[AppleScript]
純文本查看 復制代碼
1
2
|
file
.encoding
=
GBK
[
-70
,
-38
,
-62
,
-19
,
-77
,
-52
,
-48
,
-14
,
-44
,
-79
]
|
getBytes()方法的默認編碼確實是跟file.encoding一致的.file.encoding是由誰決定的呢?網上很多流傳說是跟當前文件的編碼格式相同.那我們測試一下.
在idea中我們講文件的編碼格式改成GBK.
<ignore_js_op>

發現事與願違.file.encoding依然是UTF-8的.也就是說file.encoding跟文件的編碼沒有任何關系.相同的代碼.我們用命令行窗口去編譯和運行.發現file.encoding竟然變成了GBK
[AppleScript]
純文本查看 復制代碼
1
2
3
|
C
:
\Users\yanjingpan\Desktop
>
java Demo
file
.encoding
=
GBK
[
-70
,
-38
,
-62
,
-19
,
-77
,
-52
,
-48
,
-14
,
-44
,
-79
]
|
我們講Demo.java文件改成UTF-8編碼格式的用 javac -encoding utf-8 Demo.java進行編譯.然后運行發現file.encoding竟然沒有變:
[AppleScript]
純文本查看 復制代碼
1
2
3
|
C
:
\Users\yanjingpan\Desktop
>
java Demo
file
.encoding
=
GBK
[
-70
,
-38
,
-62
,
-19
,
-77
,
-52
,
-48
,
-14
,
-44
,
-79
]
|
這說明file.encoding跟編譯環境沒有關系.只跟運行環境有關.我們嘗試運行的時候指定file.encoding編碼:
[AppleScript]
純文本查看 復制代碼
1
|
java
-
Dfile.encoding
=
utf
-8
Demo
|
運行結果就是:
[AppleScript]
純文本查看 復制代碼
1
2
|
file
.encoding
=
utf
-8
[
-23
,
-69
,
-111
,
-23
,
-87
,
-84
,
-25
,
-88
,
-117
,
-27
,
-70
,
-113
,
-27
,
-111
,
-104
]
|
運行時將file.encoding指定成gbk
[AppleScript]
純文本查看 復制代碼
1
|
java
-
Dfile.encoding
=
gbk Demo
|
運行結果就是:
[AppleScript]
純文本查看 復制代碼
1
2
3
|
C
:
\Users\yanjingpan\Desktop
>
java Demo
file
.encoding
=
GBK
[
-70
,
-38
,
-62
,
-19
,
-77
,
-52
,
-48
,
-14
,
-44
,
-79
]
|
到此我們就知道了.Tomcat在啟動的時候將file.encoding指定成了gbk.所以我們在Servlet中獲取字節碼數組的時候,默認用的就是gbk.
Tomcat是根據當前操作系統來設置file.encoding的值.我電腦是windows簡體中問的.所以默認就是GBK的.
我們可以在catalina.bat中將file.encoding設置成utf-8.
[AppleScript]
純文本查看 復制代碼
1
|
set
"JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG% -Dfile.encoding=UTF-8"
|
重啟Tomcat.再訪問我們的Servlet.file.encoding就改成UTF-8的了.
<ignore_js_op>
至此,困擾我們的getBytes()默認編碼格式問題就解決了.
更多免費技術資料可關注:annalin1203