最近一个项目因为要使用到servlet3.0的一些新特性(最主要的是对异步的支持,以及部分对websocket的支持),考察了目前最新的两个容器:Tomcat7和Jetty8,当前只有Jetty支持的比较好,Tomcat7暂时支持不够充分,所以把项目迁移到Jetty8中来了,所使用的版本是Jetty8.14(features:Standardized async;status:Development;),但是随之而来的是原项目中的所有中文字符在页面上显示的时候全部变成了乱码,惨不忍睹啊,所以不得不去找资料修复。
google了半天,没找到解决方案,后来经过很多实验(什么改xml的encoding的都做了,都不行)。本来我的项目中所有的页面和JS代码全部是使用UTF-8进行编码,spring中也指定了编码过滤器为UTF-8,UTF-8是万国码,应该是什么语言都支持显示,在tomcat里中文都是正常的,但是使用jetty在firefox中观察页面的时候,浏览器会自动把字符编码设置的为“简体中文(GB2312)”,我手动把浏览器的字符编码设置为“Unicode(UTF-8)”后页面上的中文就能正常显示了,我估计问题就在这个浏览器的编码被错误导向了,于是去修改Jetty关于编码的配置文件,经过一番尝试终于成功了,最关键的一步是修改:
jetty_home/lib/jetty-webapp-8.1.4.v20120524.jar中webdefault.xml,把zh所指向的编码更改为UTF-8,保存更新就行了。在jetty/etc/下面也有个webdefualt.xml文档,不过修改这个文档不起作用。
<locale-encoding-mapping> <locale>zh</locale> <encoding>UTF-8</encoding> <locale-encoding-mapping>
此时redeploy项目,重启jetty之后,就会发现浏览器的编码自动设置为了"Unicode(UTF-8)",中文显示正常了;
===========================================
另附说明,如果要使用servlet3.0的新特性,需要以下步骤:
1.JDK1.6以上,设置编译器级别为1.6或者6.0;
2.web.xml中要更新名字空间和版本到3.0;
3.导入servlet3.0的新jar包(如果你的容器自带3.0的jar包的话,可以省略本步);
4.如果想要特定的servlet支持异步,可以在xml中使用true标签作为该类的初始化参数,当然你也可以在类中使用注解实现,不过我没有研究过,呵呵。
===========================================
Jetty使用过程中常见错误:
一、空指针异常:
java.lang.NullPointerException at sun.net.www.protocol.jar.JarURLConnection.getUseCaches(JarURLConnection.java:309)
可以通过在etc/jetty.xml中添加
<Set class="org.eclipse.jetty.util.resource.Resource" name="defaultUseCaches">false</Set>
出处:http://stackoverflow.com/questions/7715985/jsf2-on-jetty-gives-randomly-zip-file-closed-but-works-when-running-from-maven
===========================================
二、"zip file closed"的错误:
将jetty_home/lib/jetty-webapp-8.1.4.v20120524.jar中webdefault.xml中gzip的value由true(默认)改为false,就不会再出现该错误了。
<init-param> <param-name>gzip</param-name> <param-value>false</param-value> </init-param>
按上述办法处理,只是治标不治本;原本启用Gzip是为了实现http传输压缩,提供网站的访问效率,如果需要实现改功能的话,建议还是设置gzip为true;在true的情况下,需要在web.xml中配置gzip的过滤器:
<filter> <filter-name>jettyGzipFilter</filter-name> <filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class> <init-param> <param-name>mimeTypes</param-name> <param-value>text/javascript,application/x-javascript,text/html,text/css,image/gif,image/png,image/jpg</param-value> </init-param> </filter> <filter-mapping> <filter-name>jettyGzipFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
jettyGzipFilter的已经包含在jetty-servlets-8.1.4.v20120716.jar中,如果进行了上述配置,还是有zip file closed的话,查看jetty的版本,如果在8及其以下的版本中,在etc/jetty.xml的文档最下面,添加上:
<Set class="org.eclipse.jetty.util.resource.Resource" name="defaultUseCaches">false</Set>
这个东西本来是jetty7.6版本中出现的一个BUG,在官方的BUG report中有提到,加上上面的配置后就不会再出现错误了。
进行了该设置后,大家可以在http://tool.chinaz.com/Gzips/ 上检测自己的网站是否启用了Gzip压缩传输。
===========================================
三、有些同学不会启动Jetty,囧啊:
windows下面使用cmd的cd命令,进入到jetty的安装目录下面,直接打java -jar start.jar就可以启动了。。Linux下面就更简单。操作一样的。。
===========================================
四、在Myeclipse下Jetty不能自动部署web工程的问题:
这是因为Jetty默认是考虑使用缓存文件以提供访问效率和稳定性来考虑的,如果是开发测试的话,可以修改掉Jetty的该项配置(webdefault.xml):默认为true,修改为false,就可以自动部署了。
<init-param> <param-name>useFileMappedBuffer</param-name> <param-value>false</param-value> </init-param>
===========================================
还有最近看了新版本的Tomcat,其也已经加入了对异步和websocket的支持,如果您对tomcat使用比较熟悉的话,其实可以考虑使用最新版本的tomcat也可以的