%p 输出优先U,即DEBUGQINFOQWARNQERRORQFATAL
%r 输出自应用启动到输出该log信息耗费的毫U数
%c 输出所属的cȝQ通常是所在类的全?
%t 输出产生该日志事件的U程?
%n 输出一个回车换行符QWindowsq_?#8220;\r\n”QUnixq_?#8220;\n”
%d 输出日志旉点的日期或时_默认格式为ISO8601Q也可以在其后指定格式,比如Q?d{yyy MMM dd HH:mm:ss,SSS}Q输出类|
%l 输出日志事g的发生位|,包括cȝ名、发生的U程Q以及在代码中的行数。D例:Testlog4.main(TestLog4.java:10)
一、常用输出格?/p>
%c 列出logger名字I间的全Uͼ如加上{<层数>}表示Z最内层v的指定层数的名字I间
%X 按MDCQMapped Diagnostic Context,U程映射表)输出日志。通常用于多个客户端连接同一台服务器Q方便服务器区分是那个客L讉K留下来的日志?br />
%p 日志信息U别
%d %d{<日期格式>}:日志信息产生旉,使用ISO8601定义的日期格?br />
%C 日志信息所在地Q全限类名)
%m 产生的日志具体信?br />
%n 输出日志信息换行
%F 昄调用logger的源文g?br />
%l 输出日志事g的发生位|,包括cȝ名、发生的U程Q以及在代码中的行数
%L 昄调用logger的代码行
%M 昄调用logger的方法名
%r 昄从程序启动时到记录该条日志时已经l过的毫U数
%t 输出产生该日志事件的U程?br />
%% 昄一?br />
二、log4j.properties
#控制包中日志输出U别
log4j.logger.org.apache.struts = debug
# 应用于控制台
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %-4r [%t] %-5p %c %x - %m%n
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]
n%c[CATEGORY]%n%m[MESSAGE]%n%n
#应用于文?br />
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=file.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %-4r [%t] %-5p %c %x - %m%n
# Use this layout for LogFactor 5 analysis
# 应用于文件回?br />
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.ROLLING_FILE.MaxFileSize=100KB
log4j.appender.ROLLING_FILE.MaxBackupIndex=10
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %-4r [%t] %-5p %c %x - %m%n
#应用于socket
log4j.appender.SOCKET=org.apache.log4j.net.SocketAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=5001
log4j.appender.SOCKET.LocationInfo=true
# Set up for Log Facter 5
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n
# Log Factor 5 Appender
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
# 发送日志给邮g
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=FATAL
log4j.appender.MAIL.BufferSize=10
log4j.appender.MAIL.From=web@www.wuset.com
log4j.appender.MAIL.SMTPHost=www.wusetu.com
log4j.appender.MAIL.Subject=Log4J Message
log4j.appender.MAIL.To=web@www.wusetu.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %-4r [%t] %-5p %c %x - %m%n
# 用于数据?br />
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=root
log4j.appender.DATABASE.password=
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %-4r [%t] %-5p %c %x - %m%n')
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %-4r [%t] %-5p %c %x - %m%n
#每日回滚日志文g
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=SampleMessages.log4j
log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout
#自定义Appender
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = corlin@cybercorlin.net
log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern =[framework] %d - %-4r [%t] %-5p %c %x - %m%n
This article describes in detail how the Java compiler and the JVM use the class search path to locate classes when they are referenced by other Java code. It does this with reference to a very simple example, which uses two classes in the same package. We will see how various operations to compile these two classes succeed and fail, depending on the class path setting.
To make things absolutely clear, we will use only simple command-line tools to carry out the compile operations. Interactive development tools have their own ways of manipulating the class path, which vary from product to product.
There is no fundamental difference between the way that the Java compiler searches for classes, and the way that the JVM does it at run time. However, the compiler has the ability to compile classes from source code, where the JVM does not. In the examples below we will use the compiler, but similar issues apply at run time.
com.web_tomorrow.CPTest1
and com.web_tomorrow.CPTest2
, which are listed below. package com.web_tomorrow; public class CPTest1 { public static void main(String[] args) { System.out.println ("Run CPTest1.main()"); } } package com.web_tomorrow; public class CPTest2 { public static void main(String[] args) { System.out.println ("Run CPTest2.main()"); CPTest1 cpt1 = new CPTest1(); } }One of the most fundamental rules of Java code organization is that `package name = directory name'. We will begin by setting up a directory structure that matches the package assignment of these two classes. The classes are in a package
com.web_tomorrow
, so we must create the directory com/web_tomorrow
to contain the source code. [root] com web_tomorrow CPTest1.java CPTest2.javaIn this document I will use the notation `[root]' to mean `whatever directory contains the structure described above', that is, the root of the directory layout. This will vary, of course, according to how you install the files.
CPTest1.java
on its own using the command-line javac
program. To disable the class search path completely (so any existing setting does not interfere with the example), we can run javac
with the option `-classpath ""
'.
As a first attempt, let's change directory to the location of CPTest1.java
, and try to compile it by specifying its name on the javac
command line.
cd [root]/com/web_tomorrow javac -classpath "" CPTest1.javaThis operation succeeds, because the compiler is able to find
CPTest1.java
(it is in the working directory), and because CPTest1
does not reference any other classes. The output file, CPTest1.class
ends up in the same directory as CPTest1.java
because, again, you haven't given the compiler information to do anything else. So far so good. Now let's try the same thing with CPTest2
. Still in the `web_tomorrow' directory, execute this command: javac -classpath "" CPTest2.javaThis operation should fail, even though the directory is the same as the previous step, and
CPTest1
and CPTest2
are in the same package. The error message will be something like this: PTest2.java:7: cannot resolve symbol symbol : class CPTest1 location: class com.web_tomorrow.CPTest2 CPTest1 cpt1 = new CPTest1(); ^The difference between this case and the previous, successful, one is that
CPTest2
contains a reference to CPTest1
: CPTest1 cpt1 = new CPTest1();What is going on here? When the compiler encounters the reference to
CP1Test
here, it assumes that this is a class in the same package as CP2Test
that is is currently compiling. This is a correct assumption. So the compiler needs to find com.web_tomorrow.CP1Test
. But it has nowhere to look, as we have explicitly set the class search path to "" (i.e., nothing).
You might think this problem can be resolved by telling the compiler to look in the current directory. The standard symbol for `current directory' is a single period (.) in both Unix and Windows systems. So try something like this:
javac -classpath "." CPTest2.javaThis fails in exactly the same way as the previous example. The problem now is that although
CPTest1.java
is in the current directory, the class that it implements is not just CPTest1
, but com.web_tomorrow.CPTest1
. The compiler will look for a directory com/web_tomorrow
below the current directory. So, overall, it is looking for a Java source or class file in the directory [home]/com/web_tomorrow/com/web_tomorrow
which, of course, does not exist.To make this compile operation work, we need to make the class search path reference not the directory containing CPTest1
, but a directory root from which CPTest1
can be located by the compiler following the standard Java `package name = directory name' rule. This should work, although it's rather ugly:
javac -classpath "../.." CPTest2.javaBefore seeing how we can make this less ugly, consider this example (still in the same directory):
javac -classpath "" CPTest1.java CPTest2.javaThis also works, even though the class path is empty. This is because the Java compiler will look for references between any source code explicitly listed on the command line. If there are many classes, all in the same directory, we can simplify this to:
javac -classpath "" *.javaThe `*.java' expands to a list of all the .java files in the current directory. This explains why compiling many files in one operation often succeeds where attempts to compile a single file fails.
A more convenient way to compile CPTest2
on its own is like this:
cd [root] javac -classpath "." com/web_tomorrow/CPTest2.javaIn this example we specify the full path to
CPTest2.java
, but include `.' in the -classpath
option. Again, we aren't telling the compiler to look for files in the current directory, we are telling it to begin a class search from the current directory. Because the class we are looking for is com.web_tomorrow.CPTest1
, the compiler will search in ./com/web_tomorrow
(that is, the directory com/web_tomorrow
below the current directory). This is exactly where CPTest1.java
is located.
In fact, even though I only specified CPTest2
on the command line, this practice does in fact lead to the compilation of CPTest1
as well. The compiler finds the .java
file in the right place, but it can't tell whether this Java source really implements the right class, so it has to compile it. But note that if we do this:
cd [root] javac -classpath "." com/web_tomorrow/CPTest1.javait does not cause a compilation of
CPTest2.java
, because the compiler does not need to know anything about CPTest2
to compile CPTest1
.
.class
files alongside the .java
files from which they were generated. This is a simple scheme, and very widely used. However, many developers like to keep the source tree free of generated files, and must therefore tell the Java compiler to maintain separate directories for .class
files. Let's see what impact this has on the class search path.
To begin we will need to delete any .class
files lurking around after the previous examples. We will also contain a new directory classes
to contain the generated .class
files. The procedure at the command line would be something like this:
cd [root] rm com/web_tomorrow/*.class mkdir classesDon't forget to swap the `/' characters for '\' if you are using a Windows system. The directory structure now looks like this.
[root] com web_tomorrow CPTest1.java CPTest2.java classesLet's compile
CPTest1.java
, specifying classes
as the destination directory (using the -d
option): cd [root] javac -d classes -classpath "" com/web_tomorrow/CPTest1.javaThis should succeed, but you should notice that the
.class
files have not been placed into the classes
directory at all. Instead, we have a new directory structure like this: [root] com web_tomorrow CPTest1.java CPTest2.java classes com web_tomorrow CPTest1.classWhat has happened is that the compiler has created a directory structure to match the package structure. It has done this to be helpful, as we shall see. When we come to compile
CPTest2.java
we have two choices. First, we can compile it as described above, allowing the compiler to compile CPTest1
as part of the process. Alternatively, we can compile it and use the -classpath
option to refer to the compiler to the .class
file generated in the previous step. This method is superior, as we don't have to repeat the compilation of CPTest1
. cd [root] javac -d classes -classpath classes com/web_tomorrow/CPTest2.javaBy doing this, we end up with this directory structure.
[root] com web_tomorrow CPTest1.java CPTest2.java classes com web_tomorrow CPTest1.class CPTest2.classOf course we could have compiled both
.java
files in the same command, and got the same result.
myclasses.jar
in directory /myclasses
. To have the Java compiler look for classes in this jar, we need to specify: javac -classpath /myclasses/myclasses.jar ...and not merely the directory
myclasses
.
javac
to search in only one directory at a time. In practice, your class search path will contain numerous directories and JAR archives. The -classpath
option to javac
and java
allows multiple entries to be specified, but notice that the syntax is slightly different for Unix and Windows systems.
On Unix, we would do this:
javac -classpath dir1:dir2:dir3 ...whereas on Windows we have:
javac -classpath dir1;dir2;dir3 ...The reason for the difference is that Windows uses the colon (:) character as part of a filename, so it can't be used as a filename separator. Naturally the directory separator character is different as well: forward slash (/) for Unix and backslash (\) for Windows.
javac
command line, we can make use of a `system' class path. This is the class path that will be used by both the Java compiler and the JVM in the absence of specific instructions to the contrary. In both Unix and Windows systems, this is done by setting an environment variable. For example, in Linux with the bash
shell: CLASSPATH=/myclasses/myclasses.jar;export CLASSPATHand in Windows:
set CLASSPATH=c:\myclasses\myclasses.jarThis procedure is fine for short-term changes to the system CLASSPATH, but if you want these changes to be persistent you will need to arrange this yourself. Details vary from system to system. On a Linux system, for example, I would put the commands in the file
.bashrc
in my home directory. On Windows 2000/NT there is a `Control Panel' page for this.
Setting the system CLASSPATH is a useful procedure if you have JARs full of classes that you use all the time. For example, if I am developing Enterprise JavaBean (EJB) applications using Sun's J2EE `Reference Implementation', all the EJB-related classes are in a JAR called `j2ee.jar
' that comes with the distribution. I want this JAR on the class search path all the time. In addition, most people want to ensure that the current directory is on the search path, whatever the current directory happens to be. So in my .bashrc
file I have this line:
CLASSPATH=/usr/j2ee/j2ee.jar:.;export CLASSPATHwhere the `.' indicates `current directory'.
It is easy to overlook that the -classpath
option on the command line replaces the default, system class path; it does not add to it. So what should I do if I want to set the class path to include the default system classpath plus some other entries? I could simply use the -classpath
option and list the default entries in addition to my extras. However, a better way is to reference the CLASSPATH environment variable. The syntax for this is different -- of course -- on Windows and Unix systems. On Unix:
javac -classpath $CLASSPATH:dir1:dir2 ...where
$CLASSPATH
expands to the current setting of the CLASSPATH environment variable. On Windows: javac -classpath %CLASSPATH%;dir1:dir2 ...Finally, please note that if directories in your class search path have spaces in their names, you may have to use double-quotes on the command line to prevent the CLASSPATH being split up. For example:
javac -classpath "%CLASSPATH%";dir1:dir2 ...
//
//the article ended! the following is got from Sun Microsystem Document.Setting the class path
Synopsis
The class path is the path that the Java runtime environment searches for classes and other resource files. The class search path (more commonly known by the shorter name, "class path") can be set using either the-classpath
option when calling a JDK tool (the preferred method) or by setting theCLASSPATH
environment variable. The-classpath
option is preferred because you can set it individually for each application without affecting other applications and without other applications modifying its value.
C:>
sdkTool-classpath
classpath1;
classpath2...-or-
C:> set CLASSPATH=
classpath1;
classpath2...where:
- sdkTool
- A command-line tool, such as
java
,javac
,javadoc
, orapt
. For a listing, see JDK Tools.- classpath1
;
classpath2- Class paths to the .jar, .zip or .class files. Each classpath should end with a filename or directory depending on what you are setting the class path to:
- For a .jar or .zip file that contains .class files, the class path ends with the name of the .zip or .jar file.
- For .class files in an unnamed package, the class path ends with the directory that contains the .class files.
- For .class files in a named package, the class path ends with the directory that contains the "root" package (the first package in the full package name).
Multiple path entries are separated by semi-colons. With the
set
command, it's important to omit spaces from around the equals sign (=).The default class path is the current directory. Setting the
CLASSPATH
variable or using the-classpath
command-line option overrides that default, so if you want to include the current directory in the search path, you must include "." in the new settings.Classpath entries that are neither directories nor archives (.zip or .jar files) nor * are ignored.
Description
The class path tells JDK tools and applications where to find third-party and user-defined classes -- that is, classes that are not Java extensions or part of the Java platform. The class path needs to find any classes you've compiled with the javac compiler -- its default is the current directory to conveniently enable those classes to be found.
The JDK, the JVM and other JDK tools find classes by searching the Java platform (bootstrap) classes, any extension classes, and the class path, in that order. (For details on the search strategy, see How Classes Are Found.) Class libraries for most applications will want to take advantage of the extensions mechanism. You only need to set the class path when you want to load a class that's (a) not in the current directory or in any of its subdirectories, and (b) not in a location specified by the extensions mechanism.
If you are upgrading from an older version of the JDK, your startup settings may include
CLASSPATH
settings that are no longer needed. You should remove any settings that are not application-specific, such asclasses.zip
. Some third-party applications that use the Java Virtual Machine may modify yourCLASSPATH
environment variable to include the libaries they use. Such settings can remain.You can change the class path by using the JDK tools' -classpath option when you invoke the JVM or other JDK tools or by using the
CLASSPATH
environment variable. Using the-classpath
option is preferred over settingCLASSPATH
environment variable because you can set it individually for each application without affecting other applications and without other applications modifying its value.Classes can be stored either in directories (folders) or in archive files. The Java platform classes are stored in
rt.jar
. For more details on archives and information on how the class path works, see Understanding the class path and package names near the end of this document.
- Important Note: Some older versions of the JDK sofware included a
<
jdk-dir>/classes
entry in the default class path. That directory exists for use by the JDK software, and should not be used for application classes. Application classes should be placed in a directory outside of the JDK directory hierarcy. That way, installing a new JDK does not force you to reinstall application classes. For compatibility with older versions, applications that use the<
jdk-dir>/classes
directory as a class library will run in the current version, but there is no guarantee that they will run in future versions.Using the JDK tools' -classpath option
The JDK tools java, jdb, javac, and javah have a
-classpath
option which replaces the path or paths specified by theCLASSPATH
environment variable while the tool runs. This is the recommended option for changing class path settings, because each application can have the class path it needs without interfering with any other application.The runtime tool java has a
-cp
option, as well. This option is an abbreviation for-classpath
.For very special cases, both java and javac have options that let you change the path they use to find their own class libraries. The vast majority of users will never to need to use those options, however.
Using the CLASSPATH environment variable
In general, you will want to use the
-classpath
command-line option, as explained in the previous section. This section shows you how to set theCLASSPATH
environment variable if you want to do that, or clear settings left over from a previous installation.Setting CLASSPATH
The
CLASSPATH
environment variable is modified with the set command. The format is:set CLASSPATH=
path1;
path2 ...The paths should begin with the letter specifying the drive, for example,
C:\
. That way, the classes will still be found if you happen to switch to a different drive. (If the path entries start with backslash (\
) and you are on driveD:
, for example, then the classes will be expected onD:
, rather thanC:
.)Clearing CLASSPATH
If your
CLASSPATH
environment variable has been set to a value that is not correct, or if your startup file or script is setting an incorrect path, you can unsetCLASSPATH
by using:C:> set CLASSPATH=
This command unsets
CLASSPATH
for the current command prompt window only. You should also delete or modify your startup settings to ensure that you have the rightCLASSPATH
settings in future sessions.Changing Startup Settings
If theCLASSPATH
variable is set at system startup, the place to look for it depends on your operating system:
Operating System Method Windows 95 and 98 Examine autoexec.bat for the set command. Other (Windows NT, Windows 2000, ...) The CLASSPATH environment variable can be set using the System utility in the Control Panel. Understanding class path wildcards
Class path entries can contain the basename wildcard character *, which is considered equivalent to specifying a list of all the files in the directory with the extension
.jar
or.JAR
. For example, the class path entryfoo/*
specifies all JAR files in the directory namedfoo
. A classpath entry consisting simply of * expands to a list of all the jar files in the current directory.A class path entry that contains * will not match class files. To match both classes and JAR files in a single directory
foo
, use eitherfoo;foo/*
orfoo/*;foo
. The order chosen determines whether the classes and resources infoo
are loaded before JAR files infoo
, or vice versa.Subdirectories are not searched recursively. For example,
foo/*
looks for JAR files only infoo
, not infoo/bar
,foo/baz
, etc.The order in which the JAR files in a directory are enumerated in the expanded class path is not specified and may vary from platform to platform and even from moment to moment on the same machine. A well-constructed application should not depend upon any particular order. If a specific order is required then the JAR files can be enumerated explicitly in the class path.
Expansion of wildcards is done early, prior to the invocation of a program's
main
method, rather than late, during the class-loading process itself. Each element of the input class path containing a wildcard is replaced by the (possibly empty) sequence of elements generated by enumerating the JAR files in the named directory. For example, if the directoryfoo
containsa.jar
,b.jar
, andc.jar
, then the class pathfoo/*
is expanded intofoo/a.jar;foo/b.jar;foo/c.jar
, and that string would be the value of the system propertyjava.class.path
.The
CLASSPATH
environment variable is not treated any differently from the-classpath
(or-cp
) command-line option. That is, wildcards are honored in all these cases. However, class path wildcards are not honored in theClass-Path
jar-manifest header.Understanding the class path and package names
Java classes are organized into packages which are mapped to directories in the file system. But, unlike the file system, whenever you specify a package name, you specify the whole package name -- never part of it. For example, the package name for
java.awt.Button
is always specified asjava.awt
.For example, suppose you want the Java runtime to find a class named
Cool.class
in the packageutility.myapp
. If the path to that directory isC:\java\MyClasses\utility\myapp
, you would set the class path so that it containsC:\java\MyClasses
.To run that app, you could use the following JVM command:
C:> java -classpath C:\java\MyClasses utility.myapp.Cool
When the app runs, the JVM uses the class path settings to find any other classes defined in the
utility.myapp
package that are used by theCool
class.Note that the entire package name is specified in the command. It is not possible, for example, to set the class path so it contains
C:\java\MyClasses\utility
and use the commandjava myapp.Cool
. The class would not be found.(You may be wondering what defines the package name for a class. The answer is that the package name is part of the class and cannot be modified, except by recompiling the class.)
Note: An interesting consequence of the package specification mechanism is that files which are part of the same package may actually exist in different directories. The package name will be the same for each class, but the path to each file may start from a different directory in the class path.
Folders and archive files
When classes are stored in a directory (folder), like
c:\java\MyClasses\utility\myapp
, then the class path entry points to the directory that contains the first element of the package name. (in this case,C:\java\MyClasses
, since the package name isutility.myapp
.)But when classes are stored in an archive file (a .zip or .jar file) the class path entry is the path to and including the .zip or .jar file. For example, to use a class library that is in a .jar file, the command would look something like this:
C:> java -classpath C:\java\MyClasses\myclasses.jar utility.myapp.Cool
Multiple specifications
To find class files in the directory
C:\java\MyClasses
as well as classes inC:\java\OtherClasses
, you would set the class path to:C:> java -classpath C:\java\MyClasses;C:\java\OtherClasses ...
Note that the two paths are separated by a semicolon.
Specification order
The order in which you specify multiple class path entries is important. The Java interpreter will look for classes in the directories in the order they appear in the class path variable. In the example above, the Java interpreter will first look for a needed class in the directory
C:\java\MyClasses
. Only if it doesn't find a class with the proper name in that directory will the interpreter look in theC:\java\OtherClasses
directory.
Copyright © 2004-2006 Sun Microsystems, Inc. All Rights Reserved. | ![]() Java Software |
Java中文问题一直困扰着很多初学者,如果了解了Javapȝ的中文问题原理,我们可以对中文问题能够采取Ҏ的解决之道?/p>
最古老的解决Ҏ是用String的字节码转换Q这U方案问题是不方便,我们需要破坏对象封装性,q行字节码{换?/p>
q有一U方式是对J2EE容器q行~码讄Q如果J2EE应用pȝq该容器,则会发生qQ而且指定容器配置不符合J2EE应用和容器分ȝ原则?/p>
在Java内部q算中,涉及到的所有字W串都会被{化ؓUTF-8~码来进行运。那么,在被Java转化之前Q字W串是什么样的字W集Q?JavaLҎ操作pȝ的默认编码字W集来决定字W串的初始编码,而且Javapȝ的输入和输出的都是采取操作系l的默认~码?/p>
因此Q如果能l一Javapȝ的输入、输出和操作pȝ3者的~码字符集合Q将能够使Javapȝ正确处理和显C汉字。这是处理Javapȝ汉字的一个原则,但是在实际项目中Q能够正抓住和控制住Javapȝ的输入和输出部分是比较难的。J2EE中,׃涉及到外部浏览器和数据库{,所以中文问题ؕ码显得非常突出?/p>
J2EE应用E序是运行在J2EE容器中。在q个pȝ中,输入途径有很多种Q一U是通过面表单打包成请求(requestQ发往服务器的Q第二种是通过数据库读入;q有W?U输入比较复杂,JSP在第一ơ运行时L被编译成ServletQJSP中常常包含中文字W,那么~译使用javacӞJava根据默认的操作pȝ~码作ؓ初始~码。除非特别指定,如在Jbuilder/eclipse中可以指定默认的字符集?/p>
输出途径也有几种Q第一U是JSP面的输出。由于JSP面已经被编译成ServletQ那么在输出Ӟ也将Ҏ操作pȝ的默认编码来选择输出~码Q除非指定输出编码方式;q有输出途径是数据库Q将字符串输出到数据库?/p>
由此看来Q一个J2EEpȝ的输入输出是非常复杂Q而且是动态变化的Q而Java是跨q_q行的,在实际编译和q行中,都可能涉及到不同的操作系l,如果ȝJava自由Ҏ操作pȝ来决定输入输出的~码字符集,q将不可控制地出Cؕ码?/p>
正是׃Java的跨q_Ҏ,使得字符集问题必ȝ具体pȝ来统一解决Q所以在一个Java应用pȝ中,解决中文q的根本办法是明确指定整个应用pȝl一字符集?/strong>
指定l一字符集时Q到底是指定ISO8859_1 、GBKq是UTF-8呢?
Q?Q如l一指定为ISO8859_1Q因为目前大多数软g都是西方人编制的Q他们默认的字符集就是ISO8859_1Q包括操作系lLinux和数据库MySQL{。这P如果指定Jivel一~码为ISO8859_1Q那么就有下?个环节必L握:
开发和~译代码时指定字W集为ISO8859_1?/p>
q行操作pȝ的默认编码必LISO8859_1Q如Linux?/p>
在JSP头部声明Q?lt;%@ page contentType="text/html;charset=ISO8859_1" %>?/p>
Q?Q如果统一指定为GBK中文字符集,上述3个环节同样需要做刎ͼ不同的是只能q行在默认编码ؓGBK的操作系l,如中文Windows?/p>
l一~码为ISO8859_1和GBK虽然带来~制代码的方便,但是各自只能在相应的操作pȝ上运行。但是也破坏了Java跨^台运行的优越性,只在一定范围内行得通。例如,Z使得GBK~码在linux上运行,讄Linux~码为GBK?/p>
那么有没有一U除了应用系l以外不需要进行Q何附加设|的中文~码Ҏ解决Ҏ呢?
Java/J2EEpȝ的统一~码定义为UTF-8。UTF-8~码是一U兼Ҏ有语a的编码方式,惟一比较ȝ的就是要扑ֈ应用pȝ的所有出入口Q然后用UTF-8厠Z结扎”它?/p>
一个J2EE应用pȝ需要做下列几步工作Q?/p>