由于CJW支持中文用户名,三级中文子域名泛解析比如 永远的最爱JAVA.blog.chinajavaworld.com,解析没有问题。但在应用过程上遇到了两个问题:
在应用服务器中 request.getServerName() 得到的中文是乱码。即:??????????java.blog.chinajavaworld.com.
研读Resin源码,找到 com.caucho.server.http.HttpRequest 类,加入两行代码以支持 request.getServerName()的中文问题:
/**
* Parses headers from the read stream.
*
* @param s the input read stream
*/
private void parseHeaders(ReadStream s) throws IOException
{
// This is still slowest part of the web server. I don't see how
// to improve it much more, but there must be a way.
int version = getVersion();
if (version < HTTP_1_0) {
return;
}
if (version < HTTP_1_1)
killKeepalive();
byte []readBuffer = s.getBuffer();
int readOffset = s.getOffset();
int readLength = s.getLength();
char []headerBuffer = _headerBuffer;
int headerOffset = 1;
int headerBufferSize = headerBuffer.length;
headerBuffer[0] = 'z';
int headerSize = 0;
_headerSize = 0;
CharSegment []headerKeys = _headerKeys;
CharSegment []headerValues = _headerValues;
boolean debug = log.isLoggable(Level.FINE);
while (true) {
int ch;
int keyOffset = headerOffset;
// scan the key
while (true) {
if (readLength <= readOffset) {
readOffset = 0;
if ((readLength = s.fillBuffer()) <= 0)
return;
}
ch = readBuffer[readOffset++];
if (ch == '\n') {
s.setOffset(readOffset);
return;
}
else if (ch == ':')
break;
headerBuffer[headerOffset++] = (char) ch;
}
while (headerBuffer[headerOffset - 1] == ' ')
headerOffset--;
int keyLength = headerOffset - keyOffset;
headerKeys[headerSize].init(headerBuffer, keyOffset, keyLength);
do {
if (readLength <= readOffset) {
readOffset = 0;
if ((readLength = s.fillBuffer()) <= 0)
return;
}
ch = readBuffer[readOffset++];
} while (ch == ' ' || ch == '\t');
int valueOffset = headerOffset;
// scan the value
while (true) {
if (readLength <= readOffset) {
readOffset = 0;
if ((readLength = s.fillBuffer()) <= 0)
break;
}
if (ch == '\n') {
int ch1 = readBuffer[readOffset];
if (ch1 == ' ' || ch1 == '\t') {
ch = ' ';
readOffset++;
if (headerBuffer[headerOffset - 1] == '\r')
headerOffset--;
}
else
break;
}
headerBuffer[headerOffset++] = (char) ch;
ch = readBuffer[readOffset++];
}
//加入以下两行代码,设置_host
String readStr = new String(readBuffer);
_host = readStr.split("Host:")[1].split("\n")[0];
while (headerBuffer[headerOffset - 1] <= ' ')
headerOffset--;
int valueLength = headerOffset - valueOffset;
headerValues[headerSize].init(headerBuffer, valueOffset, valueLength);
if (debug) {
log.fine(dbgId() +
headerKeys[headerSize] + ": " + headerValues[headerSize]);
}
if (addHeaderInt(headerBuffer, keyOffset, keyLength,
headerValues[headerSize])) {
headerSize++;
}
_headerSize = headerSize;
}
}
修改并替换后重启Resin
Protocol: HTTP/1.1
Scheme: http
Server Name: 永远的最爱java.blog.chinajavaworld.com:8080
Server Port: 8080
Protocol: HTTP/1.1
Server Info: Resin/3.0.24
Remote Addr: 127.0.0.1
Remote Host: 127.0.0.1
Character Encoding: UTF-8
Content Length: -1
Content Type: null
Auth Type: null
HTTP Method: GET
可以发现request.getServerName()可以显示中文。
2.原以为这下可以解决问题了,第二个问题的发现很不好办:
域名中带有中文的,Cookie读取不到。这意味着中文用户名的用户登录后访问自己的博客或同样带中文域名的博客时,都处于未登录状态。这是Cookie的规范,只能想别的办法。
解决办法还是有,比如可以在登录系统登录成功后,产生一个key,将用户的认证信息通过这个key存进分布式Cache中,同时在定向到成功页面的同时,将这个key做为参数传过去,新页面接收到key后从分布式Cache中取认证信息,这种方法虽然可以解决,但这个key必须在所有相关操作页面传递,影响用户体验。
目前采取了折中的办法,如果用户名是非字母或数字的,就用用户ID做为三级子域名进行访问。
http://anotherbug.blog.chinajavaworld.com/entry/2869/0/