??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
(多次~译或重新编? h行make clean, make mrproper)
./configure --prefix=/usr/local/apache --enable-mods-shared=all --enable-so --with-mpm=worker --with-included-apr --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr
./configure --prefix=/usr/local/apache2.2 --enable-mods-shared=all \
--enable-so --with-mpm=worker --enable-deflate \
--enable-cache --enable-disk-cache --enable-mem-cache --enable-file-cache \
--enable-proxy --enable-suexec --with-included-apr --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr
make
make install
make mrproper
或者连l执?make && make install && make mrproper
配置
cd /usr/local/apache/conf (下面的LINUX命o都是以conf为当前目?
(1.)httpd.conf
修改如下几项
DocumentRoot /home/test
q在末尾增加如下字段:
#LoadModule jk_module modules/mod_jk.so
Include /usr/local/apache/conf/Includes/*.conf
#转发规则 START
SetOutputFilter DEFLATE
AddOutputFilterByType DEFLATE text/html
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
# Don't compress images
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \
\.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \
\.pdf$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \
\.(css|js)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \
\.(mp3|amr|mid|MP3)$ no-gzip dont-vary
# 保代理不会发送错误的内容
Header append Vary User-Agent env=!dont-vary
#转发规则 END
(2)配置 MOD_JK
复制mod_jk.so到modules/?/span>
1.配置mod_jk.conf
vi Includes/mod_jk.conf
增加如下内容:
LoadModule jk_module modules/mod_jk.so
#mod_jk workers.properties
JkWorkersFile /usr/local/apache2/conf/workers.properties
# Where to put jk logs
JkLogFile /usr/local/apache2/logs/mod_jk.log
# Set the jk log level [debug/error/info]
JkLogLevel info
# Select the log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
# JkOptions indicate to send SSL KEY SIZE,
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
# JkRequestLogFormat set the request format
JkRequestLogFormat "%w %V %T"
# ...servlet .jsp....ajp13.....Tomcat..Tomcat...
JkMount /*.jsp loadbalancer
JkMount /*.do loadbalancer
JkMount /servlet/* loadbalancer
JkMount /jsp-examples/* loadbalancer
2.配置workers.properties(一般只需改动对应HOST)
vi workers.properties
ps=/
# list the workers by name
worker.list=tomcat1, loadbalancer
# ------------------------
# First tomcat server
# ------------------------
worker.tomcat1.port=8009
worker.tomcat1.host=123.108.208.17
worker.tomcat1.type=ajp13
# Specify the size of the open connection cache.
#worker.tomcat1.cachesize
#
# Specifies the load balance factor when used with
# a load balancing worker.
# Note:
# ----> lbfactor must be > 0
# ----> Low lbfactor means less work done by the worker.
worker.tomcat1.lbfactor=100
# ------------------------
# Load Balancer worker
# ------------------------
# The loadbalancer (type lb) worker performs weighted round-robin
# load balancing with sticky sessions.
# Note:
# ----> If a worker dies, the load balancer will check its state
# once in a while. Until then all work is redirected to peer
# worker.
worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=tomcat1
#
# END workers.properties
#
3.配置对应虚拟L
vi Includes/examples.com.conf
NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot /home/test
ServerName www.test.com
ServerAlias www.test.com
ErrorLog logs/www.test.com-error_log
CustomLog logs/www.test.com-access_log common
<Directory "/home/test">
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
4.配置静态页面压~输出模块deflate
q个扩展模块在安装apache的时候已l动态的~译到apache里去了。现在进行配|?br />
# cd /usr/local/apache2.2/conf/Includes
上面d的是apache扩展配置文g的目?br />
# vi mod_deflate.conf
在配|文仉d如下语句
5. 配置mod_cache模块
# cd /usr/local/apache2.2/conf/Includes
# vi mod_cache.conf
在配|文仉d如下语句
#LoadModule disk_cache_module modules/mod_disk_cache.so
CacheRoot /
CacheSize 256
CacheEnable disk /
CacheDirLevels 5
CacheDirLength 3
LoadModule mem_cache_module modules/mod_mem_cache.so
CacheEnable mem /
MCacheSize 4096
MCacheMaxObjectCount 100
MCacheMinObjectSize 1
MCacheMaxObjectSize 2048
试&启动
./bin/apachectl -t 试配置有无语法错误
./bin/apachectl start 启动APACHE服务
./bin/apachectl stop 停止APACHE服务
获取|
文本框,文本区域Q?("#txt").attr("value")Q?br />
多选框checkboxQ?("#checkbox_id").attr("value")Q?br />
单选组radioQ?nbsp; $("input[@type=radio][@checked]").val();
下拉框selectQ?$('#sel').val();
控制表单元素Q?br />
文本框,文本区域Q?("#txt").attr("value",'');//清空内容
$("#txt").attr("value",'11');//填充内容
多选框checkboxQ?$("#chk1").attr("checked",'');//不打?br />
$("#chk2").attr("checked",true);//打勾
if($("#chk1").attr('checked')==undefined) //判断是否已经打勾
单选组radioQ?nbsp; $("input[@type=radio]").attr("checked",'2');//讄value=2的项目ؓ当前选中?br />
下拉框selectQ?nbsp; $("#sel").attr("value",'-sel3');//讄value=-sel3的项目ؓ当前选中?br />
$("<option value='1'>1111</option><option value='2'>2222</option>").appendTo("#sel")//d下拉框的option
$("#sel").empty()Q?/清空下拉?/p>
另外Q你不愿意你的DAO试代码每次都打开关系SessionQ因此,我们一般会采用OpenSessionInView模式?
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
SessionFactory sessionFactory = lookupSessionFactory();
logger.debug("Opening Hibernate Session in OpenSessionInViewFilter");
Session session = getSession(sessionFactory);
TransactionSynchronizationManager.bindResource(sessionFactory,
new SessionHolder(session));
try {
filterChain.doFilter(request, response);
}
finally {
TransactionSynchronizationManager.unbindResource(sessionFactory);
logger.debug("Closing Hibernate Session in OpenSessionInViewFilter");
closeSession(session, sessionFactory);
}
}
Z么绑定以后,可以防止每ơ不会新开一个Session呢?看看HibernateDaoSupport的情况:
public final void setSessionFactory(SessionFactory sessionFactory) {
this.hibernateTemplate = new HibernateTemplate(sessionFactory);
}
protected final HibernateTemplate getHibernateTemplate() {
return hibernateTemplate;
}
我们的DAO用这个templateq行操作Q?
public abstract class BaseHibernateObjectDao
extends HibernateDaoSupport
implements BaseObjectDao {
protected BaseEntityObject getByClassId(final long id) {
BaseEntityObject obj =
(BaseEntityObject) getHibernateTemplate()
.execute(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException {
return session.get(getPersistentClass(),
new Long(id));
}
});
return obj;
}
public void save(BaseEntityObject entity) {
getHibernateTemplate().saveOrUpdate(entity);
}
public void remove(BaseEntityObject entity) {
try {
getHibernateTemplate().delete(entity);
} catch (Exception e) {
throw new FlexEnterpriseDataAccessException(e);
}
}
public void refresh(final BaseEntityObject entity) {
getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException {
session.refresh(entity);
return null;
}
});
}
public void replicate(final Object entity) {
getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException {
session.replicate(entity,
ReplicationMode.OVERWRITE);
return null;
}
});
}
public Object execute(HibernateCallback action) throws DataAccessException {
Session session = (!this.allowCreate ?
SessionFactoryUtils.getSession(getSessionFactory(),
false) :
SessionFactoryUtils.getSession(getSessionFactory(),
getEntityInterceptor(),
getJdbcExceptionTranslator()));
boolean existingTransaction =
TransactionSynchronizationManager.hasResource(getSessionFactory());
if (!existingTransaction && getFlushMode() == FLUSH_NEVER) {
session.setFlushMode(FlushMode.NEVER);
}
try {
Object result = action.doInHibernate(session);
flushIfNecessary(session, existingTransaction);
return result;
}
catch (HibernateException ex) {
throw convertHibernateAccessException(ex);
}
catch (SQLException ex) {
throw convertJdbcAccessException(ex);
}
catch (RuntimeException ex) {
// callback code threw application exception
throw ex;
}
finally {
SessionFactoryUtils.closeSessionIfNecessary(
session, getSessionFactory());
}
}
public static void closeSessionIfNecessary(Session session,
SessionFactory sessionFactory)
throws CleanupFailureDataAccessException {
if (session == null ||
TransactionSynchronizationManager.hasResource(sessionFactory)) {
return;
}
logger.debug("Closing Hibernate session");
try {
session.close();
}
catch (JDBCException ex) {
// SQLException underneath
throw new CleanupFailureDataAccessException(
"Cannot close Hibernate session", ex.getSQLException());
}
catch (HibernateException ex) {
throw new CleanupFailureDataAccessException(
"Cannot close Hibernate session", ex);
}
}
使用同样的方法,q两个Interceptor可以用来解决问题。但是关键的不同之处在于Q它们的力度只能定义在DAO或业务方法上Q而不是在我们的TestҎ上,除非我们把它们应用到TestCase的方法上Q但你不大可能ؓTestCased义一个接口,然后把Interceptor应用到这个接口的某些Ҏ上。直接用HibernateTransactionManager也是一L。因此,如果我们有这L试Q?
Category parentCategory = new Category ();
parentCategory.setName("parent");
dao.save(parentCategory);
Category childCategory = new Category();
childCategory.setName("child");
parentCategory.addChild(childCategory);
dao.save(childCategory);
Category savedParent = dao.getCategory("parent");
Category savedChild = (Category ) savedParent.getChildren().get(0);
assertEquals(savedChild, childCategory);
一U方法是对TestCase应用Interceptor或者TransactionManagerQ但q个恐怕会造成很多ȝ。除非是使用增强方式的AOP.我前期采用这U方?Aspectwerkz)Q在Eclipse里面也跑得含好?
另一U方法是在TestCase的setup和teardown里面实现和Filter完全一L处理Q其他的TestCase都从q个TestCasel承Q这U方法是我目前所使用的?
它有两种配置方式OpenSessionInViewInterceptor?span style="font-size: 10pt; color: #4b4b4b; font-family: Verdana;">OpenSessionInViewFilter(具体参看SpringSide)
Q功能相同,只是一个在web.xml配置Q另一个在application.xml配置而已?/span>Open Session In View?/span>request?/span>sessionl定到当?/span>thread期间一直保?/span>hibernate session?/span>open状态,?/span>session?/span>request的整个期间都可以使用Q如?/span>View层里PO也可?/span>lazy loading数据Q如 ${ company.employees }。当View 层逻辑完成后,才会通过Filter?/span>doFilterҎ?/span>Interceptor?/span>postHandleҎ自动关闭session?/span>
OpenSessionInViewInterceptor配置
<beans> <bean name="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor"> <property name="sessionFactory"> <ref bean="sessionFactory"/> </property> </bean> <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="interceptors"> <list> <ref bean="openSessionInViewInterceptor"/> </list> </property> <property name="mappings"> ... </property> </bean> ... </beans>
OpenSessionInViewFilter配置
<web-app> ... <filter> <filter-name>hibernateFilter</filter-name> <filter-class> org.springframework.orm.hibernate3.support.OpenSessionInViewFilter </filter-class> <!-- singleSession默认为true,若设为false则等于没?span class="me1">OpenSessionInView --> <init-param> <param-name>singleSession</param-name> <param-value>true</param-value> </init-param> </filter> ... <filter-mapping> <filter-name>hibernateFilter</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping> ... </web-app>
很多人在使用OpenSessionInViewq程中提及一个错误:
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition
看看OpenSessionInViewFilter里的几个Ҏ
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,FilterChain filterChain)
throws ServletException, IOException {
SessionFactory sessionFactory = lookupSessionFactory();
logger.debug("Opening Hibernate Session in OpenSessionInViewFilter");
Session session = getSession(sessionFactory);
TransactionSynchronizationManager.bindResource(
sessionFactory, new SessionHolder(session));
try {
filterChain.doFilter(request, response);
}
finally {
TransactionSynchronizationManager.unbindResource(sessionFactory);
logger.debug("Closing Hibernate Session in OpenSessionInViewFilter");
closeSession(session, sessionFactory);
}
}
protected Session getSession(SessionFactory sessionFactory)
throws DataAccessResourceFailureException {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
session.setFlushMode(FlushMode.NEVER);
return session;
}
protected void closeSession(Session session, SessionFactory sessionFactory)
throws CleanupFailureDataAccessException {
SessionFactoryUtils.closeSessionIfNecessary(session, sessionFactory);
}
可以看到OpenSessionInViewFilter在getSession的时?会把获取回来的session的flush mode 设ؓFlushMode.NEVER。然后把该sessionFactoryl定? TransactionSynchronizationManagerQrequest的整个过E都使用同一个sessionQ在hq后再接除该 sessionFactory的绑定,最?span class="me1">closeSessionIfNecessaryҎ? session是否已和transactionl定来决定是否关闭session。在q个q程中,若HibernateTemplate 发现自当前session有不是readOnly的transactionQ就会获取到FlushMode.AUTO SessionQҎ拥有写权限?/p>
public static void closeSessionIfNecessary(Session session, SessionFactory sessionFactory) throws CleanupFailureDataAccessException { if (session == null ||
TransactionSynchronizationManager.hasResource(sessionFactory)) { return; } logger.debug("Closing Hibernate session"); try { session.close(); } catch (JDBCException ex) { // SQLException underneath throw new CleanupFailureDataAccessException("Could not close Hibernate session", ex.getSQLException()); } catch (HibernateException ex) { throw new CleanupFailureDataAccessException("Could not close Hibernate session", ex); } }
也即是,如果有不是readOnly的transaction可以由Flush.NEVER转ؓFlush.AUTO,拥有insert, update,delete操作权限Q如果没有transactionQƈ且没有另外h为地设flush model的话Q则doFilter的整个过E都是Flush.NEVER。所以受transaction保护的方法有写权限,没受保护的则没有?/p>
采用spring的事务声?使方法受transaction控制
<bean id="baseTransaction"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="proxyTargetClass" value="true"/>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
- <bean id="userService" parent="baseTransaction">
<property name="target">
<bean class="com.phopesoft.security.service.impl.UserServiceImpl"/>
</property>
</bean>
? 于上例,则以save,add,update,remove开头的Ҏ拥有可写的事务,如果当前有某个方法,如命名ؓimportExcel()Q则因没 有transaction而没有写权限Q这时若Ҏ内有insert,update,delete操作的话Q则需要手动设|flush model为Flush.AUTO,?/p>
session.setFlushMode(FlushMode.AUTO); session.save(user); session.flush();
管Open Session In View看v来还不错Q其实副作用不少。看回上面OpenSessionInViewFilter的doFilterInternalҎ代码Q这个方? 实际上是被父cȝdoFilter调用的,因此Q我们可以大U了解的OpenSessionInViewFilter调用程: request(h)->open sessionq开始transaction->controller->View(Jsp)->l束transactionq? close session.
一切看h很正,其是在本地开发测试的时候没出现问题Q但试想下如果流E中的某一步被d的话Q那在这期间connection׃直被占用而不? 放。最有可能被d的就是在写Jspq步Q一斚w可能是页面内容大Qresponse.write的时间长Q另一斚w可能是网速慢Q服务器与用户间传输? 间久。当大量q样的情况出现时Q就有连接池q接不Q造成面假死现象?/p>
Open Session In View是个双刃剑,攑֜公网上内容多量大的|站h用?/p>
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1441664
>汉字~码的相兌?br /> 汉字是双字节的,要占用两个BYTE的位|(?6位)Q分别称为高位和低位?br /> 中国规定的汉字编码ؓGB2312Q这是强制性的Q目前几乎所有的能处理中文的应用E序都支持GB2312。GB2312包括了一二汉字?区符P高位?xa1?xfeQ低位也是从0xa1?xfeQ其中,汉字的编码范围ؓ0xb0a1?xf7fe?br /> 另外有一U编码,叫做GBKQ但q是一份规范,不是强制的。GBK提供?0902个汉字,它兼容GB2312Q编码范围ؓ0x8140?xfefe。GBK中的所有字W都可以一一映射到Unicode 2.0?br /> 中国q颁布了另一U标准:GB18030-2000QGBK2KQ。它收录了藏、蒙{少数民族的字型Q从Ҏ上解决了字位不的问题。注意:它不再是定长的。其二字节部份与GBK兼容Q四字节部分是扩充的字符、字形。它的首字节和第三字节从0x81?xfeQ二字节和第四字节从0x30?x39?/p>
2>不同语言直接的{?br /> 异种语言之间的{换是通过Unicode来完成的。假设有两种不同的语aA和BQ{换的步骤为:先把A转化为UnicodeQ再把Unicode转化为B?br /> 举例说明。有GB2312中有一个汉?#8220;?#8221;Q其~码?#8220;C0EE”Q欲转化为ISO8859-1~码。步骤ؓQ先?#8220;?#8221;字{化ؓUnicodeQ得?“674E”Q再?#8220;674E”转化为ISO8859-1字符。当Ӟq个映射不会成功Q因为ISO8859-1中根本就没有?#8220;674E”对应的字W。当映射不成功时Q问题就发生了!当从某语a向Unicode转化Ӟ如果在某语言中没有该字符Q得到的是Unicode的代?#8220;\uffffd”Q?#8220;\ u”表示是Unicode~码Q)。而从Unicode向某语言转化Ӟ如果某语a没有对应的字W,则得到的?#8220;0x3f”Q?#8220;?”Q。这是“?”的由来。例如:把字W流buf =“0x80 0x40 0xb0 0xa1”q行new String(buf, "gb2312")操作Q得到的l果?#8220;\ufffd\u554a”Q再println出来Q得到的l果是“??#8221;Q因?#8220;0x80 0x40”是GBK中的字符Q在GB2312中没有。再如,把字W串String="\u00d6\u00ec\u00e9\u0046\u00bb\ u00f9"q行new String (buf.getBytes("GBK"))操作Q得到的l果?#8220;3fa8aca8a6463fa8b4”Q其中,“\u00d6”?#8220;GBK”中没有对应的字符Q得?#8220;3f”Q?#8220;\u00ec”对应着“a8ac”Q?#8220;\u00e9”对应着“a8a6”Q?#8220;0046”对应着“46”Q因是ASCII字符Q,“\u00bb”没找刎ͼ得到“3f”Q最后,“\u00f9”对应着“a8b4”。把q个字符串println一下,得到的结果是“?ìéF? ù”。看到没Q这里ƈ不全是问P因ؓGBK与Unicode映射的内容中除了汉字外还有字W,本例是最好的明证?/p>
3>Unicode格式
Unicode默认为UTF-16格式?br />
UTF-8是Unicode压羃版本Q对于大多数常用字符?ASCII?~127字符)它只使用单字节,而对其它常用字符(特别是朝鲜和汉语会意文字)Q它使用Q字节。如果写的主要是pQ那么UTF-8可减文件大一半左叟?br />
UTF-8是?位ؓ单元对UCSq行~码Q以字节为编码单元,没有字节序的问题。UTF-16以两个字节ؓ~码单元Q在解释一个UTF-16文本前,首先要弄清楚每个~码单元的字节序。例??的Unicode~码?94EQ??的Unicode~码?E59。如果我们收到UTF-16字节?"594E"Q那么这?#8220;?#8221;q是"?QUnicode规范中推荐的标记字节序的方法是BOM(即Byte Order Mark)。如果接收者收到FEFFQ就表明q个字节是Big-Endian的;如果收到FFFEQ就表明q个字节是Little-Endian的?/p>
3>UTF格式
UTFQ是Unicode Text Format的羃写,意ؓUnicode文本格式。对于UTFQ是q样定义的:
?如果Unicode?6位字W的?位是0Q则用一个字节表C,q个字节的首位是“0”Q剩下的7位与原字W中的后7位相同,?#8220;\u0034” Q?000 0000 0011 0100Q,?#8220;34” (0011 0100)表示Q(与源Unicode字符是相同的Q;
>7位的Unicode: 0 _ _ _ _ _ _ _
?如果Unicode?6位字W的?位是0Q则?个字节表C,首字节是“110”开_后面?位与源字W中除去?个零后的最?位相同;W二个字节以“10”开_后面?位与源字W中的低6位相同。如“\u025d”Q?000 0010 0101 1101Q,转化后ؓ“c99d”Q?100 1001 1001 1101Q;
>11位的Unicode: 1 1 0 _ _ _ _ _ 1 0 _ _ _ _ _ _
?如果不符合上qC个规则,则用三个字节表示。第一个字节以“1110”开_后四位ؓ源字W的高四位;W二个字节以“10”开_后六位ؓ源字W中间的六位Q第三个字节?#8220;10”开_后六位ؓ源字W的低六位;?#8220;\u9da7”Q?001 1101 1010 0111Q,转化?#8220;e9b6a7”Q?110 1001 1011 0110 1010 0111Q;
>16位的Unicode: 1 1 1 0 _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _
>21位的Unicode: 1 1 1 1 0 _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _
可以q么描述JAVAE序中Unicode与UTF的关p,虽然不绝对:字符串在内存中运行时Q表CؓUnicode代码Q而当要保存到文g或其它介质中LQ用的是UTF。这个{化过E是由writeUTF和readUTF来完成的?/p>
4>JavaE序中的~码格式内幕
input(charsetA)-Qprocess(Unicode)-Qoutput(charsetB)
卌入、处理和输出要经q?#8220;从charsetA到unicode再到charsetB”的{化?/p>
SourceFile(jsp,java)-Qclass-Qoutput
输入的是jsp和java源文Ӟ在处理过E中Q以Class文g体,然后输出?/p>
?JSP从源文g到Class的过E?br />
在本节中Q将阐述JSP文g的解释和~译q程Qƈ跟踪其中的中文变化?br />
1、JSP/Servlet引擎提供的JSP转换工具QjspcQ搜索JSP文g中用Q?@ page contentType ="text/html; charset=QJsp-charsetQ?%Q中指定的charset。如果在JSP文g中未指定QJsp-charsetQ,则取JVM中的默认讄file.encodingQ一般情况下Q这个值是ISO8859-1Q?br />
2、jspc用相当于“javac –encoding QJsp-charsetQ?#8221;的命令解释JSP文g中出现的所有字W,包括中文字符和ASCII字符Q然后把q些字符转换成Unicode字符Q再转化?UTF格式Q存为JAVA文g。ASCII码字W{化ؓUnicode字符时只是简单地在前面加“00”Q如“A”Q{化ؓ“\u0041”Q不需要理由,Unicode的码表就是这么编的)。然后,l过到UTF的{换,又变?#8220;41”了!q也是可以使用普通文本编辑器查看由JSP生成的JAVA文g的原因;
3、引擎用相当?#8220;javac –encoding UNICODE”的命令,把JAVA文g~译成CLASS文gQ?br />
先看一下这些过E中中文字符的{换情c有如下源代码:
Q?@ page contentType="text/html; charset=gb2312"%Q?br />
QhtmlQ<bodyQ?br />
Q?
String a="中文";
out.println(a);
%Q?br />
Q?bodyQ</htmlQ?
两个字的GB2312~码?#8220;D6 D0 CE C4”。经查表Q?#8220;中文”两字的Unicode~码?#8220;\u4E2D\u6587”Q用 UTF表示是“E4 B8 AD E6 96 87”。此JSP文g生成的JAVA文g中的“中文”两个字被“E4 B8 AD E6 96 87”替代了,再查看由JAVA文g~译生成的CLASS文gQ发现结果与JAVA文g中的完全一栗?br />
再看JSP中指定的CharSet为ISO-8859-1的情c?br />
Q?@ page contentType="text/html; charset=ISO-8859-1"%Q?br />
QhtmlQ<bodyQ?br />
Q?
String a="中文";
out.println(a);
%Q?br />
Q?bodyQ</htmlQ?
先推一下生成的JAVA文g和CLASS文g的过E:jspc用ISO-8859-1来解?#8220;中文”Qƈ把它映射到Unicode。由于ISO- 8859-1?位的Q其映射规则是在每个字节前?#8220;00”Q所以,映射后的Unicode~码应ؓ“\u00D6\u00D0\u00CE\ u00C4”Q{化成UTF后应该是“C3 96 C3 90 C3 8E C3 84”。最后,打开文g看一下,JAVA文g和CLASS文g中,“中文”果然都表CZؓ“C3 96 C3 90 C3 8E C3 84”?br />
如果上述代码中不指定QJsp-charsetQ,xW一行写?#8220;Q?@ page contentType="text/html" %Q?#8221;QJSPC会用file.encoding的设|来解释JSP文g。在RedHat 6.2上,其处理结果与指定为ISO-8859-1是完全相同的?br />
到现在ؓ止,已经解释了从JSP文g到CLASS文g的{变过E中中文字符的映过E。一句话Q从“JspCharSet到Unicode再到UTF”?/p>
?Servlet从源文g到Class的过E?br /> 本节讨论Servlet的编译过Eƈ跟踪其中的中文变化?br /> ?#8220;javac”~译Servlet源文件。javac可以?#8220;-encoding QCompile-charsetQ?#8221;参数Q意思是“用< Compile-charset Q中指定的编码来解释Serlvet源文?#8221;?br /> 源文件在~译Ӟ用<Compile-charsetQ来解释所有字W,包括中文字符和ASCII字符。然后把字符帔R转变成Unicode字符Q最后,把Unicode转变成UTF?br /> 在Servlet中,q有一个地方设|输出流的CharSet。通常在输出结果前Q调用HttpServletResponse?setContentTypeҎ来达C在JSP中设|<Jsp-charsetQ一L效果Q称之ؓQServlet-charsetQ?br /> 注意Q文中一共提C三个变量Q<Jsp-charsetQ、<Compile-charsetQ和QServlet-charsetQ。其中,JSP文g只与QJsp-charsetQ有养I而<Compile-charsetQ和QServlet-charsetQ只与Servlet有关?/p>
import javax.servlet.*;
import javax.servlet.http.*;
class testServlet extends HttpServlet
{
public void doGet(HttpServletRequest req,HttpServletResponse res)
throws ServletException,java.io.IOException
{
res.setContentType("text/html; charset=GB2312");
java.io.PrintWriter out=res.getWriter();
out.println("QhtmlQ?);
out.println("#中文#");
out.println("Q?htmlQ?);
}
}
开始编译。下表是QCompile-charsetQ不同时QCLASS文g?#8220;中文”两字的十六进制码。在~译q程中,QServlet- charsetQ不起Q何作用。<Servlet-charsetQ只对CLASS文g的输Z生媄响,实际上是QServlet-charsetQ和QCompile-charsetQ一P辑ֈ与JSP文g中的QJsp-charsetQ相同的效果Q因为<Jsp-charsetQ对~译?CLASS文g的输出都会生媄响?#8220;中文”两个字的GB2312~码?#8220;D6 D0 CE C4”
Compile-charset Class文g?nbsp; {效的Unicode?
GB2312 E4 B8 AD E6 96 87(UTF) \u4E2D\u6587 (在Unicode中=“中文”)
ISO-8859-1 C3 96 C3 90 C3 8E C3 84 (UTF) \u00D6 \u00D0 \u00CE \u00C4 (在D6 D0 CE C4前面各加了一?0)
Q默认) 同ISO-8859-1 同ISO-8859-1
普通JavaE序的编译过E与Servlet完全一栗?br /> 接下来看看CLASS又是怎样输出中文的呢Q?br /> 上文说过Q字W串在内存中表现为Unicode~码。至于这UUnicode~码表示了什么,那要看它是从哪种字符集映过来的Q也是说要看它的祖先。看看上面的例子Q如果给一串Unicode~码“00D6 00D0 00CE 00C4”Q如果不作{换,直接用Unicode码表来对照它Ӟ是四个字W(而且是特D字W)Q假如把它与“ISO8859-1”q行映射Q则直接L前面?#8220;00”卛_得到“D6 D0 CE C4”Q这是ASCII码表中的四个字符Q而假如把它当作GB2312来进行映,得到的结果很可能是一大堆qQ因为在GB2312中有可能没有Q也有可能有Q字W与00D6{字W对应(如果对应不上Q将得到0x3fQ也是问号Q如果对应上了,׃00D6{字W太靠前Q估计也是一些特D符P真正的汉字在Unicode中的~码?E00开始)?br /> 可以Q同LUnicode字符Q可以解释成不同的样子。当Ӟq其中有一U是我们期望的结果?br /> 以上例而论Q?#8220;D6 D0 CE C4”应该是我们所惌的,当把“D6 D0 CE C4”输出到IE中时Q用“体中?#8221;方式查看Q就能看到清楚的“中文”两个字了?br /> Servlet中,当Compile-charset=Servlet-charsetӞ昄l果肯定正常?/p>
?最l结论:
在Class输出字符串前Q会Unicode的字W串按照某一U内码重新生成字节流Q然后把字节输入,相当于进行了一?#8220;String.getBytes(???)”操作???代表某一U字W集?br />
如果是ServletQ那么,q种内码是在HttpServletResponse.setContentType()Ҏ中指定的内码Q也是上文定义的<Servlet-charsetQ?br />
如果是JSPQ那么,q种内码是在<%@ page contentType=""%Q中指定的内码,也就是上文定义的QJsp-charsetQ?br />
如果是JavaE序Q那么,q种内码是file.encoding中指定的内码Q默认ؓISO8859-1?/p>
5>l论
在Jsp文g中,要指定contentTypeQ其中,charset的D与客L览器所用的字符集一P对于其中的字W串帔RQ不需做Q何内码{换;对于字符串变量,要求能根据ContentType中指定的字符集还原成客户端能识别的字节流Q简单地_是“字符串变量是ZQJsp- charsetQ字W集?#8221;Q?br />
在Servlet中,必须用HttpServletResponse.setContentType()讄charsetQ且讄成与客户端内码一_对于其中的字W串帔RQ需要在Javac~译时指定encodingQ这个encoding必须与编写源文g的^台的字符集一P一般说来都?GB2312或GBKQ对于字W串变量Q与JSP一P必须“是基于<Servlet-charsetQ字W集?#8221;?nbsp;
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1339656
-------------------------------
国际标准 ISO 10646 定义?通用字符?(Universal Character Set, UCS). UCS 是所有其他字W集标准的一个超? 它保证与其他字符集是双向兼容? 是? 如果你将M文本字符串翻译到 UCS格式, 然后再翻译回原编? 你不会丢׃Q何信?
UCS 包含了用于表达所有已知语a的字W? 不仅包括拉丁?希腊? 斯拉夫语,希伯来语,阿拉伯语,亚美g语和乔治亚语的描q? q包括中? 日文和韩文这L象Ş文字, 以及 q_? 片假? 孟加拉语, 旁遮普语果鲁I奇字符(Gurmukhi), 泰米语, ?埃纳徯(Kannada), Malayalam, 泰国? 老挝? 汉语拼音(Bopomofo), Hangul, Devangari, Gujarati, Oriya, Telugu 以及其他CC清的? 对于q没有加入的语言, ׃正在研究怎样在计机中最好地~码它们, 因而最l它们都被加入. q些语言包括 Tibetian, 高棉? Runic(古代北欧文字), 埃塞俄比亚语, 其他象Ş文字, 以及各种各样的印-Ƨ语pȝ语言, q包括挑选出来的艺术语言比如 Tengwar, Cirth 和克林A?Klingon). UCS q包括大量的囑Ş? 印刷用的, 数学用的和科学用的符? 包括所有由 TeX, Postscript, MS-DOSQMS-Windows, Macintosh, OCR 字体, 以及许多其他字处理和出版pȝ提供的字W?
ISO 10646 定义了一?31 位的字符? 然? 在这巨大的编码空间中, q今为止只分配了?65534 个码?(0x0000 ?0xFFFD). q个 UCS ?16位子集称?基本多语a?(Basic Multilingual Plane, BMP). 被~码?16 ?BMP 以外的字W都属于非常Ҏ的字W?比如象Ş文字), 且只有专家在历史和科学领域里才会用到它们. 按当前的计划, 来也许再也不会有字W被分配C 0x000000 ?0x10FFFF q个覆盖了超q?100 万个潜在的未来字W的 21 位的~码I间以外M. ISO 10646-1 标准W一ơ发表于 1993 q? 定义了字W集?BMP 中内容的架构. 定义 BMP 以外的字W编码的W二部分 ISO 10646-2 正在准备? 但也许要q好几年才能完成. 新的字符仍源源不断地加入?BMP ? 但已l存在的字符是稳定的且不会再改变?
UCS 不仅l每个字W分配一个代? 而且赋予了一个正式的名字. 表示一?UCS ?Unicode 值的十六q制? 通常在前面加?"U+", p U+0041 代表字符"拉丁大写字母A". UCS 字符 U+0000 ?U+007F ?US-ASCII(ISO 646) 是一致的, U+0000 ?U+00FF ?ISO 8859-1(Latin-1) 也是一致的. ?U+E000 ?U+F8FF, 已经 BMP 以外的大范围的编码是为私用保留的.
UCS里有些编码点分配l了 l合字符. 它们cM于打字机上的无间隔重音键. 单个的组合字W不是一个完整的字符. 它是一个类g重音W或其他指示标记, 加在前一个字W后? 因? 重音W可以加在Q何字W后? 那些最重要的被加重的字W? p普通语a的正字法(orthographies of common languages)里用到的那种, ?UCS 里都有自q位置, 以确保同老的字符集的向后兼容? 既有自己的编码位|? 又可以表CZؓ一个普通字W跟随一个组合字W的被加重字W? 被称?预作字符(precomposed characters). UCS 里的预作字符是ؓ了同没有预作字符的旧~码, 比如 ISO 8859, 保持向后兼容性而设? l合字符机制允许在Q何字W后加上重音W或其他指示标记, q在U学W号中特别有? 比如数学方程式和国际x字母, 可能会需要在一个基本字W后l合上一个或多个指示标记.
l合字符跟随着被修饰的字符. 比如, 徯中的元音变音字符 ("拉丁大写字母A 加上分音W?), 既可以表CZؓ UCS ?U+00C4 的预作字W? 也可以表C成一个普?"拉丁大写字母A" 跟着一?l合分音W?:U+0041 U+0308 q样的组? 当需要堆叠多个重音符, 或在一个基本字W的上面和下面都要加上组合标记时, 可以使用多个l合字符. 比如在泰国文? 一个基本字W最多可加上两个l合字符.
不是所有的pȝ都需要支持象l合字符q样?UCS 里所有的先进机制. 因此 ISO 10646 指定了下列三U实现?
历史? 有两个独立的, 创立单一字符集的试. 一个是国际标准化组l?ISO)?ISO 10646 目, 另一个是?一开始大多是国?多语a软g刉商l成的协会组l的 Unicode 目. q运的是, 1991q前? 两个目的参与者都认识? 世界不需要两个不同的单一字符? 它们合ƈ双方的工作成? qؓ创立一个单一~码表而协同工? 两个目仍都存在q独立地公布各自的标? ?Unicode 协会?ISO/IEC JTC1/SC2 都同意保?Unicode ?ISO 10646 标准的码表兼? q紧密地共同调整M未来的扩?
Unicode 协会公布?Unicode 标准 严密地包含了 ISO 10646-1 实现U别3的基本多语言? 在两个标准里所有的字符都在相同的位|ƈ且有相同的名?
Unicode 标准额外定义了许多与字符有关的语义符号学, 一般而言是对于实现高质量的印刷出版系l的更好的参? Unicode 详细说明了绘制某些语a(比如阿拉伯语)表达形式的算? 处理双向文字(比如拉丁与希伯来文合文?的算法和 排序与字W串比较 所需的算? 以及其他许多东西.
另一斚w, ISO 10646 标准, pqؓ人知?ISO 8859 标准一? 只不q是一个简单的字符集表. 它指定了一些与标准有关的术? 定义了一些编码的别名, q包括了规范说明, 指定了怎样使用 UCS q接其他 ISO 标准的实? 比如 ISO 6429 ?ISO 2022. q有一些与 ISO 紧密相关? 比如 ISO 14651 是关?UCS 字符串排序的.
考虑?Unicode 标准有一个易记的名字, 且在M好的书店里的 Addison-Wesley 里有, 只花?ISO 版本的一部? 且包括更多的辅助信息, 因而它成ؓ使用q泛得多的参考也׃ؓ奇了. 然? 一般认? 用于打印 ISO 10646-1 标准的字体在某些斚w的质量要高于用于打印 Unicode 2.0? 专业字体设计者L被徏议说要两个标准都实现, 但一些提供的样例字Ş有显著的区别. ISO 10646-1 标准同样使用四种不同的风格变体来昄表意文字如中? 日文和韩?(CJK), ?Unicode 2.0 的表里只有中文的变体. q导致了普遍的认?Unicode Ҏ本用h说是不可接收的传? 管是错误的.
首先 UCS ?Unicode 只是分配整数l字W的~码? 现在存在好几U将一串字W表CZؓ一串字节的Ҏ. 最显而易见的两种Ҏ是将 Unicode 文本存储?2 ??4 个字节序列的? q两U方法的正式名称分别?UCS-2 ?UCS-4. 除非另外指定, 否则大多数的字节都是q样?Bigendian convention). 一?ASCII ?Latin-1 的文件{换成 UCS-2 只需单地在每?ASCII 字节前插?0x00. 如果要{换成 UCS-4, 则必d每个 ASCII 字节前插入三?0x00.
?Unix 下?UCS-2 (?UCS-4) 会导致非怸重的问题. 用这些编码的字符串会包含一些特D的字符, 比如 '\0' ?'/', 它们?文g名和其他 C 库函数参数里都有特别的含? 另外, 大多C?ASCII 文g?UNIX 下的工具, 如果不进行重大修Ҏ无法d 16 位的字符? Zq些原因, 在文件名, 文本文g, 环境变量{地? UCS-2 不适合作ؓ Unicode 的外部编?
?ISO 10646-1 Annex R ?RFC 2279 里定义的 UTF-8 ~码没有q些问题. 它是?Unix 风格的操作系l下使用 Unicode 的明昄Ҏ.
UTF-8 有一下特?
下列字节串用来表CZ个字W? 用到哪个串取决于该字W在 Unicode 中的序号.
U-00000000 - U-0000007F: | 0xxxxxxx |
U-00000080 - U-000007FF: | 110xxxxx 10xxxxxx |
U-00000800 - U-0000FFFF: | 1110xxxx 10xxxxxx 10xxxxxx |
U-00010000 - U-001FFFFF: | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
U-00200000 - U-03FFFFFF: | 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx |
U-04000000 - U-7FFFFFFF: | 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx |
xxx 的位|由字符~码数的二进制表C的位填? 靠右的 x h少的特D意? 只用最短的那个_表达一个字W编码数的多字节? 注意在多字节串中, W一个字节的开?1"的数目就是整个串中字节的数目.
例如: Unicode 字符 U+00A9 = 1010 1001 (版权W号) ?UTF-8 里的~码?
11000010 10101001 = 0xC2 0xA9
而字W?U+2260 = 0010 0010 0110 0000 (不等? ~码?
11100010 10001001 10100000 = 0xE2 0x89 0xA0
q种~码的官方名字拼写ؓ UTF-8, 其中 UTF 代表 UCS Transformation Format. 请勿在Q何文档中用其他名?(比如 utf8 ?UTF_8) 来表C?UTF-8, 当然除非你指的是一个变量名而不是这U编码本w?
在大U?1993 q之后开发的大多数现代编E语a都有一个特别的数据cd, 叫做 Unicode/ISO 10646-1 字符. ?Ada95 中叫 Wide_Character, ?Java 中叫 char.
ISO C 也详l说明了处理多字节编码和宽字W?(wide characters) 的机? 1994 q?9 ?Amendment 1 to ISO C 发表时又加入了更? q些机制主要是ؓ各类东亚~码而设计的, 它们比处?UCS 所需的要健壮得多. UTF-8 ?ISO C 标准调用多字节字W串的编码的一个例? wchar_t cd可以用来存放 Unicode 字符.
public class BaseCache extends GeneralCacheAdministrator {
// q期旉(单位为秒);
private int refreshPeriod;
public BaseCache(int refreshPeriod){
super();
this.refreshPeriod=refreshPeriod;
}
// d被缓存的对象;
public void put(String key,Object value){
this.putInCache(key,value);
}
// 删除被缓存的对象;
public void remove(String key){
this.flushEntry(key);
}
// 删除所有被~存的对?
public void removeAll(Date date){
this.flushAll(date);
}
public void removeAll(){
this.flushAll();
}
// 获取被缓存的对象;
public Object get(String key) throws Exception{
try{
return this.getFromCache(key,this.refreshPeriod);
} catch (NeedsRefreshException e) {
this.cancelUpdate(key);
throw e;
}
}
}
2.执行Ҏ:
在方法里,indexCache = new BaseCache(3600),hii = new cache.Hits(hits),q个cL自己写的,下面的详l代?然后调用put(String key,Object value)Ҏ,key是关键字.下次取的时候就直接get(key),key我是用的查询参数l成?只要下次当别人用到相同条件搜索时,可以直接从~存L?q里所提到的是org.apache.lucene.search.Hitsq个对像是不能被~存?没有被序例化,我查了下源码,也不能被l承,所以大家自己写个类implements Serializable
public class Hits implements Serializable {
private org.apache.lucene.search.Hits hits;
private Document[] docs=null;
private boolean flag=true;
/**
* sundc 2007-11-20
*/
public Hits(org.apache.lucene.search.Hits hits) {
this.docs=new Document[hits.length()];
int length=0;
//我这里是定义记录有只~存?10多记?如果大于710q是查lucene,大家都知道搜索用戯问都是几?大家可以针对自己目q行规化..
if(hits.length()>=710){
length=710;
}
else{
length=hits.length();
}
for(int i=0;i<length;i++){
try {
this.docs[i]=hits.doc(i);
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public Hits( Document[] doc){
this.docs=doc;
}
public Document doc(int i){
if(!this.flag){
try {
return this.hits.doc(i);
} catch (CorruptIndexException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return this.docs[i];
}
public int length(){
if(this.flag){
return docs.length;
}
return this.hits.length();
}
public Document[] getDocs() {
return this.docs;
}
public void setDocs(Document[] docs) {
this.docs = docs;
}
public org.apache.lucene.search.Hits getHits() {
return this.hits;
}
public void setHits(org.apache.lucene.search.Hits hits) {
this.hits = hits;
}
}
我这里是如果有缓存数?p~存,没有,lucene然后攑֜~存?大家可以调用indexCache.get(key),大家每一ơ访问的时候会相对很慢.如果~存已经建立?那么速度会很?大家在用的时?针对自己目的数据要?q行~存.下面介绍内存~存.
2.内存~存可以相对要快?但是针对服务器的本n内存大小,大家针对自己的项目和服务器的配置选择好的~存方式.,把cache.memory=true,q样可以了.
3.q可以实现页面~存
你可以在web.xml中定义缓存过滤器Q定义特定资源的~存?br />
<filter>
<filter-name>CacheFilter</filter-name>
<filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class>
<init-param>
<param-name>time</param-name>
<param-value>60</param-value>
</init-param>
<init-param>
<param-name>scope</param-name>
<param-value>session</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CacheFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
上面定义缓存所?jsp面Q缓存刷新时间ؓ60U,~存作用域ؓSession,
注意QCacheFilter只捕获Http头ؓ200的页面请求,卛_Ҏ错误h作缓存,
而不对其他请求(?00,404,400Q作~存处理.
我这里介l的不全,只是我在目中用Cq些.如果有什么问?虚心接受....
有相当多的地区电信强制性要求用户安装星IY件才能正怸|,而星I极速Y件的氓行径令h发指?
首先我们对这U行C痛恨~~~
Z么一定要使用星空软g而不能用其它Y件上|呢Q其实其它Y件也能(比如XP自带的)正常上网?
当然q需要进行必要的讄Q该如何讄呢?
我可以给大家提供一个只需要三分钟搞定的方法,不需要借助M破解软gQ只靠WINDOWSOKQ?
大家有没有想qؓ什么只能用星I极速才能上|呢Q而其它Y仉会出?#8220;691”{类的错误提C?
实际上根本问题不是Y仉题,而是账号问题。我们每人的宽带账号其实q真实的̎P真实账号前面
比我们的账号前面多两个字W,一般是“~G”格式Q~?个大写字母)Q也有~7Q~?个阿拉伯数字Q?
比如说电信提供给你的账号是:1234567Q而实际你的真实̎hQ~G1234567或者~71234567Q?
如果用真实̎号在XP自带的Y件中上网可以正常登陆。用星I极速YӞ它则省去部分自动加上拨受?
问题我们弄清楚了Q就需要搞明白I竟省去的是哪两个字W?#8220;~”是固定的Q后面的英文字母和数字是不定的,
有好多网友提供的专业软gq行分析可以解析出是哪两个字W,但是q样太复杂。现在我l大家提供一U?
相当单的Ҏ则可以找出?
Ҏ如下Q?
Q关闭星I极速,xq行中的其它E序Q?
开始——控刉李쀔—性能和维护——管理工具——事件查看器——系l(双击Q——启动星I极速——刷C件查看器
W一个事件即Z用星I极速拨L记录Q双击该事g后可以在描述栏内看到你的真实宽带账号Q即上面所说的格式?
得到真实账号后就可以使用自己心爱的拨可Y件登陆?
声明Q该Ҏ成功率ؓ99%Q另?%Z知控刉板是什么东西的|友?
当然q有W办法,字母和数字加hL不到40个,不怕麻烦也可以一个个来试着拨号QL一个是正确的?
希望上述能大家有所帮助。让我们摆脱氓Q生zd一个宁静的世界?/span>