2009年04月 存档

Google App Engine Java runtime的file.encoding居然不是UTF-8

2009年04月8日,星期三

runtime的file.encoding居然不是UTF-8
Google App Engine支持Java了,下午在Windows下测试Google App Engine Java Servlet的中文是正常的,但是测试的jsp页面显示却是乱码,
参考:http://618119.com/archives/2009/04/08/145.html

于是晚上写了下面的代码来取出系统属性和环境变量来看:
[code]

out.println("系统属性有:《br/》");

Enumeration e1 = System.getProperties().propertyNames();
String s1 = "";
while (e1.hasMoreElements()) {
String key = (String) e1.nextElement();
String value = System.getProperty(key);
out.println(key + "=" + value + "《br/》");

}
out.println("系统环境变量有:《br/》");
for (Map.Entry《String, String》 et : System.getenv().entrySet()) {
out.println(et.getKey() + "=" + et.getValue() + "《br/》");

}
out.println("你的请求属性有以下内容:《br/》");
Enumeration e2 = req.getAttributeNames();
while (e2.hasMoreElements()) {
String key = (String) e2.nextElement();
Object value = req.getAttribute(key);
out.println(key + "=" + value + "《br/》");

}
out.println("你的请求头信息有以下内容:《br/》");
Enumeration e = req.getHeaderNames();
String s = "";
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String value = req.getHeader(key);
out.println(key + "=" + value + "《br/》");

}

[/code]

程序运行结果如下:
系统属性有:
java.vendor=Sun Microsystems Inc.
java.specification.version=1.6
line.separator=
java.class.version=50.0
java.util.logging.config.file=WEB-INF/logging.properties
java.specification.name=Java Platform API Specification
java.vendor.url=http://java.sun.com/
java.vm.version=1.6.0_13
os.name=Linux
java.version=1.6.0_13
java.vm.specification.version=1.0
user.dir=/base/data/home/apps/lizongbo/2.332646483357654537
java.vm.specification.name=Java Virtual Machine Specification
java.specification.vendor=Sun Microsystems Inc.
java.vm.vendor=Sun Microsystems Inc.
file.separator=/
path.separator=:
java.vm.name=Java HotSpot(TM) Client VM
java.vm.specification.vendor=Sun Microsystems Inc.
file.=ANSI_X3.4-1968
系统环境变量有:

你的请求属性有以下内容:
com.google.apphosting.runtime.jetty.APP_VERSION_REQUEST_ATTR=lizongbo/2.332646786822574367
你的请求头信息有以下内容:
Host=lizongbo.appspot.com
User-Agent=Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.0.8) Gecko/2009032712 Ubuntu/8.10 (intrepid) Firefox/3.0.8,gzip(gfe)
Accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language=zh-cn,zh;q=0.5
Accept-Charset=gb2312,utf-8;q=0.7,*;q=0.7

其中很奇特的是Google App Engine Java runtime的file.encoding=ANSI_X3.4-1968,而不是UTF-8。
从request的属性里看到了jetty字样,,不知google App Engine 的java运行环境是否和jetty有什么关系。
在Ubuntu下Eclipse里重新建立testweb,重新建立test.,这次传上去再访问,中文显示就正常了。 测试地址:http://lizongbo.appspot.com/test.jsp

不明白是何原因。

Tags: , ,

Google App Engine支持Java了!

2009年04月8日,星期三

Google App Engine支持Java了!
开发团队在其官方博客正式宣布Google App Engine支持java,于是开通账户体验了一下。
体验流程如下:1.先创建账户,需要短信激活。再创建一个domain为 http://lizongbo.appspot.com/
2. Google App Engine SDK 1.2.0下载地址:
appengine-java-sdk-1.2.0.zip: http://googleappengine.googlecode.com/files/appengine-java-sdk-1.2.0.zip
中文页面没更新,所以要看英文下载页面:
http://code.google.com/intl/en/appengine/downloads.html
下载之后解压到D:\Java\appengine-java-sdk-1.2.0
3.Eclipse 插件下载:
下载安装步骤参考: http://code.google.com/intl/zh-CN/eclipse/docs/install-eclipse-3.4.html

http://dl.google.com/eclipse/plugin/3.4

我在插件更新里没选Google App Engine Java SDK 1.2.0和Google Web toolkit SDK 1.6.4

4.安装好插件之后,重启Eclipse,新建 Web Application Project,
在向导界面,将 Use Google Web Toolkit的钩取消掉,在Use Google App Engine 的右边,配置SDK目录,选择D:\Java\appengine-java-sdk-1.2.0。
工程名写testweb,包名写com.lizongbo.gapp

5.在创建好工程后,工程默认创建了一个testwebServlet。

6.修改testwebServlet的doGet方法,代码如下:
[code]
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("text/html; charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("《!DOCTYPE HTML PUBLIC \"-"
+ "//W3C//DTD HTML 4.0 Transitional//EN\"》");
out.println("《HTML》《HEAD》《TITLE》" + "lizongbo 的测试app"
+ "《/TITLE》《/HEAD》《BODY》");

out.println("你的请求头信息有以下内容:《br/》");
Enumeration e = req.getHeaderNames();
String s = "";
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String value = req.getHeader(key);
out.println(key + "=" + value + "《br/》");
}
out.println("《/BODY》《/HTML》");
}
[/code]

7.在工程上点右键,选择 Run As ,选择 Web Application。web就启动了。

8.访问http://localhost:8080/testweb,查看效果,可以验证程序是ok的了

9.在工程上点右键,选择google ,再选Deploy to App Engine.
再发布界面选择工程为testweb,Email为lizongbo@gmail.com。输入密码。
点 App Engine project settings,Application ID填lizongbo.Version先用默认的1.
确认之后,再带拿Deploy就发布成功了。

10.访问 http://lizongbo.appspot.com/,再访问http://lizongbo.appspot.com/testweb,就可以看到实际效果了。
这个时候,也可以访问http://1.latest.lizongbo.appspot.com/testweb来查看效果

11.稍微修改一下代码,再发布一次,Version填2,这个时候,就可以通过http://lizongbo.appspot.com/testweb或者http://2.latest.lizongbo.appspot.com/testweb来查看效果
http://1.latest.lizongbo.appspot.com/testweb 依然是发布前上个版本的效果。

12.在war目录新建test.,然后发布,发布完之后马上就可以访问成功。

13.Google确实牛!

15.进一步测试发现,Eclipse里工程使用UTF-8编码,Servlet没有乱码问题,而jsp在本地测试ok,部署在Google App Engine上却是乱码。

参考: http://googleappengine.blogspot.com/2009/04/seriously-this-time-new-language-on-app.html

Tags: ,

jsp拦截JspWriter实现类似php的ob_get_contents

2009年04月6日,星期一

jsp拦截JspWriter实现类似php的ob_get_contents
php可以通过ob_start和ob_get_contents可以拦截并得到echo等方式输出的内容,并可以方便的进行二次处理。java的jsp也是可以非常方便就实现这样的功能,那就是实现一个自定义的JspWriter.
oscache的功能强大的jsp缓存标签就是这样干的。
前段时间作了个简单的rss输出,由于避免访问量过大影响到数据库和接口调用。
于是需要对生成的rss文本进行缓存。原有的jsp代码都已经写好,大概动就太麻烦了,于是用TextJspWriter继承javax.servlet..,然后在jsp作小改造就搞定了。
php的用法参考: http://cn2.php.net/ob_get_contents
TextJspWriter.java的代码为:
[code]

package com.lizongbo.util;

import .io.IOException;
import java.io.StringWriter;

import javax.servlet.jsp.JspWriter;

public class TextJspWriter extends JspWriter {
public String getString() {
return sb.toString();
}

private StringBuilder sb = null;

public TextJspWriter() {
this(8192, true);
}

public TextJspWriter(int bufferSize, boolean autoFlush) {
super(bufferSize, autoFlush);
sb=new StringBuilder(bufferSize);
}

@Override
public void clear() throws IOException {
sb = new StringBuilder();

}

@Override
public void clearBuffer() throws IOException {
sb = new StringBuilder();

}

@Override
public void close() throws IOException {

}

@Override
public void flush() throws IOException {

}

@Override
public int getRemaining() {
return 0;
}

@Override
public void newLine() throws IOException {
sb.append("\n");

}

@Override
public void print(boolean arg0) throws IOException {
sb.append(arg0);

}

@Override
public void print(char arg0) throws IOException {
sb.append(arg0);

}

@Override
public void print(int arg0) throws IOException {
sb.append(arg0);

}

@Override
public void print(long arg0) throws IOException {
sb.append(arg0);

}

@Override
public void print(float arg0) throws IOException {
sb.append(arg0);

}

@Override
public void print(double arg0) throws IOException {
sb.append(arg0);

}

@Override
public void print(char[] arg0) throws IOException {
sb.append(arg0);

}

@Override
public void print(String arg0) throws IOException {
sb.append(arg0);

}

@Override
public void print(Object arg0) throws IOException {
sb.append(arg0);

}

@Override
public void println() throws IOException {
sb.append("\n");

}

@Override
public void println(boolean arg0) throws IOException {
sb.append(arg0);
println();

}

@Override
public void println(char arg0) throws IOException {
sb.append(arg0);
println();

}

@Override
public void println(int arg0) throws IOException {
sb.append(arg0);
println();

}

@Override
public void println(long arg0) throws IOException {
sb.append(arg0);
println();

}

@Override
public void println(float arg0) throws IOException {
sb.append(arg0);
println();

}

@Override
public void println(double arg0) throws IOException {
sb.append(arg0);
println();

}

@Override
public void println(char[] arg0) throws IOException {
sb.append(arg0);
println();

}

@Override
public void println(String arg0) throws IOException {
sb.append(arg0);
println();

}

@Override
public void println(Object arg0) throws IOException {
sb.append(arg0);
println();

}

@Override
public void write(char[] cbuf, int off, int len) throws IOException {
sb.append(cbuf, off, len);
}

}

[/code]

jsp代码:

[code]
《%//读取缓存
String textStr==rssTextCache.get(cacheKey);
if(textStr==null){
JspWriter oldout=out;
out= new com.lizongbo.util.TextJspWriter();
%》
《% //正常输出rss内容%》

《%
textStr=((com.lizongbo.util.TextJspWriter)out).getString();
out=oldout;//放入缓存中
rssTextCache.put(cacheKey,textStr);
}
%》
《%=textStr%》

[/code]

Tags: , , , ,