|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
j2EE和asp比较,其实也没什么比的,原因和我上面说那些比较差不了多少,也是稳定性,安全性,J2EE比asp高,速度上比不过asp,asp也是延续着它的拖拽控件的方法,提高速度。js|servlet|显现
由于一向不信Java竟会有不克不及混排显现多国言语的BUG,这个周末研讨了一下Servlet、Jsp的多国言语显现的成绩,也就是Servlet的多字符集成绩,因为我对字符集的观点还不是很明晰以是写出的工具一定是正确的,我是如许了解Java中的字符集的:在运转时,每一个字符串对象中存储的都是编码为UNICODE内码的(我以为一切的言语中都是有响应编码的,由于在盘算机外部字符串老是用内码来暗示的,只不外一样平常盘算机言语中的字符串编码时平台相干的,而Java则接纳了平台有关的UNICODE)。
Java从一个byte流中读取一个字符串时,将把平台相干的byte变化为平台有关的Unicode字符串。在输入时Java将把Unicode字符串变化为平台相干的byte流,假如某个Unicode字符在某个平台上不存在,将会输入一个?。举个例子:在中文Windows中,Java读出一个"GB2312"编码的文件(能够是任何流)到内存中机关字符串对象,将会把GB2312编码的笔墨变化为Unicode编码的字符串,假如把这个字符串输入又将会把Unicode字符串转化为GB2312的byte流或数组:"中文测试"----->"u4e2du6587u6d4bu8bd5"----->"中文测试"。
以下例程:
byte[]bytes=newbyte[]{(byte)0xd6,(byte)0xd0,(byte)0xce,(byte)0xc4,(byte)0xb2,(byte)0xe2,(byte)0xca,(byte)0xd4};//GBK编码的"中文测试"
java.io.ByteArrayInputStreambin=newjava.io.ByteArrayInputStream(bytes);
java.io.BufferedReaderreader=newjava.io.BufferedReader(newjava.io.InputStreamReader(bin,"GBK"));
Stringmsg=reader.readLine();
System.out.println(msg)
这段程序放到包括"中文测试"这四个字的体系(如中文体系)中,能够准确地打印出这些字。msg字符串中包括了准确的"中文测试"的Unicode编码:"u4e2du6587u6d4bu8bd5",打印时转换为操纵体系的默许字符集,是不是能够准确显现依附于操纵体系的字符集,只要在撑持响应字符集的体系中,我们的信息才干准确的输入,不然失掉的将会是渣滓。
话进正题,我们来看看Servlet/Jsp中的多言语成绩。我们的方针是,任一国度的客户端经由过程Form向Server发送信息,Server把信息存进数据库中,客户端在检索时仍旧可以看到本人发送的准确信息。现实上,我们要包管,终极Server中的SQL语句中保留的时包括客户端发送笔墨的准确Unicode编码;DBC与数据库通信时接纳的编码体例能包括客户端发送的笔墨信息,现实上,最好让JDBC间接利用UNICODE/UTF8与数据库通信!如许就能够确保不会丧失信息;Server向客户端发送的信息时也要接纳不丧失信息的编码体例,也能够是Unicode/Utf8。
假如不指定Form的Enctype属性,Form将把输出的内容按照以后页面的编码字符集urlencode以后再提交,服务器端失掉是urlencoding的字符串。编码后失掉的urlencoding字符串是与页面的编码相干的,如gb2312编码的页面提交"中文测试",失掉的是"%D6%D0%CE%C4%B2%E2%CA%D4",每一个"%"后跟的是16进制的字符串;而在UTF8编码时失掉的倒是"%E4%B8%AD%E6%96%87%E6%B5%8B%E8%AF%95",由于GB2312编码中一个汉字是16位的,而UTF8中一个汉字倒是24位的。中日韩三国的ie4以上扫瞄器均撑持UTF8编码,这类计划一定包容了这三国言语,以是我们假如让Html页面利用UTF8编码那末将最少能够撑持这三国言语。
可是,假如我们html/Jsp页面利用UTF8编码,由于使用程序服务器大概不晓得这类情形,由于假如扫瞄器发送的信息不包括charset信息,最多Server晓得读到Accept-Language哀求招标,我们晓得仅靠这个招标是不克不及获知扫瞄器所接纳编码的,以是使用程序服务器不克不及准确剖析提交的内容,为何?由于Java中的一切字符串都是Unicode16位编码的,HttpServletRequest.request(String)的功效就是把客户端提交的Urlencode编码的信息转为Unicode字符串,有些Server只能以为客户真个编码和Server平台不异,复杂地利用URLDecoder.decode(String)办法间接解码,假如客户端编码刚好和Server不异,那末就能够失掉准确地字符串,不然,假如提交地字符串中包括了外地字符,那末将会招致渣滓信息。
在我提出的这个办理计划里,已指定了接纳Utf8编码,以是,能够制止这个成绩,我们能够本人定制出decode办法:
publicstaticStringdecode(Strings,Stringencoding)throwsException{
StringBuffersb=newStringBuffer();
for(inti=0;i<s.length();i++){
charc=s.charAt(i);
switch(c){
case+:
sb.append();
break;
case%:
try{
sb.append((char)Integer.parseInt(
s.substring(i+1,i+3),16));
}
catch(NumberFormatExceptione){
thrownewIllegalArgumentException();
}
i+=2;
break;
default:
sb.append(c);
break;
}
}
//Undoconversiontoexternalencoding
Stringresult=sb.toString();
byte[]inputBytes=result.getBytes("8859_1");
returnnewString(inputBytes,encoding);
}
这个办法能够指定encoding,假如把它指定为UTF8就满意了我们的必要。好比用它剖析:"%E4%B8%AD%E6%96%87%E6%B5%8B%E8%AF%95"就能够失掉准确的汉字"中文测试"的Unicode字符串。
如今的成绩就是我们必需失掉客户端提交的Urlencode的字符串。关于method为get的form提交的信息,能够用HttpServletRequest.getQueryString()办法读到,而关于post办法的form提交的信息,只能从ServletInputStream中读到,现实上尺度的getParameter办法被第一次挪用后,form提交的信息就被读掏出来了,而ServletInputStream是不克不及反复读出的。以是我们应在第一次利用getParameter办法前读取并剖析form提交的信息。
我是这么做的,创建一个Servlet基类,掩盖service办法,在挪用父类的service办法前读取并剖析form提交的内容,请看上面的源代码:
packagecom.hto.servlet;
importjavax.servlet.http.HttpServletRequest;
importjava.util.*;
/**
*Insertthetypesdescriptionhere.
*Creationdate:(2001-2-415:43:46)
*@author:钱卫春
*/
publicclassUTF8ParameterReader{
Hashtablepairs=newHashtable();
/**
*UTF8ParameterReaderconstructorcomment.
*/
publicUTF8ParameterReader(HttpServletRequestrequest)throwsjava.io.IOException{
super();
parse(request.getQueryString());
parse(request.getReader().readLine());
}
/**
*UTF8ParameterReaderconstructorcomment.
*/
publicUTF8ParameterReader(HttpServletRequestrequest,Stringencoding)throwsjava.io.IOException{
super();
parse(request.getQueryString(),encoding);
parse(request.getReader().readLine(),encoding);
}
publicstaticStringdecode(Strings)throwsException{
StringBuffersb=newStringBuffer();
for(inti=0;i<s.length();i++){
charc=s.charAt(i);
switch(c){
case+:
sb.append();
break;
case%:
try{
sb.append((char)Integer.parseInt(
s.substring(i+1,i+3),16));
}
catch(NumberFormatExceptione){
thrownewIllegalArgumentException();
}
i+=2;
break;
default:
sb.append(c);
break;
}
}
//Undoconversiontoexternalencoding
Stringresult=sb.toString();
byte[]inputBytes=result.getBytes("8859_1");
returnnewString(inputBytes,"UTF8");
}
publicstaticStringdecode(Strings,Stringencoding)throwsException{
StringBuffersb=newStringBuffer();
for(inti=0;i<s.length();i++){
charc=s.charAt(i);
switch(c){
case+:
sb.append();
break;
case%:
try{
sb.append((char)Integer.parseInt(
s.substring(i+1,i+3),16));
}
catch(NumberFormatExceptione){
thrownewIllegalArgumentException();
}
i+=2;
break;
default:
sb.append(c);
break;
}
}
//Undoconversiontoexternalencoding
Stringresult=sb.toString();
byte[]inputBytes=result.getBytes("8859_1");
returnnewString(inputBytes,encoding);
}
/**
*Insertthemethodsdescriptionhere.
*Creationdate:(2001-2-417:30:59)
*@returnjava.lang.String
*@paramnamejava.lang.String
*/
publicStringgetParameter(Stringname){
if(pairs==null||!pairs.containsKey(name))returnnull;
return(String)(((ArrayList)pairs.get(name)).get(0));
}
/**
*Insertthemethodsdescriptionhere.
*Creationdate:(2001-2-417:28:17)
*@returnjava.util.Enumeration
*/
publicEnumerationgetParameterNames(){
if(pairs==null)returnnull;
returnpairs.keys();
}
/**
*Insertthemethodsdescriptionhere.
*Creationdate:(2001-2-417:33:40)
*@returnjava.lang.String[]
*@paramnamejava.lang.String
*/
publicString[]getParameterValues(Stringname){
if(pairs==null||!pairs.containsKey(name))returnnull;
ArrayListal=(ArrayList)pairs.get(name);
String[]values=newString[al.size()];
for(inti=0;i<values.length;i++)
values=(String)al.get(i);
returnvalues;
}
/**
*Insertthemethodsdescriptionhere.
*Creationdate:(2001-2-420:34:37)
*@paramurlencjava.lang.String
*/
privatevoidparse(Stringurlenc)throwsjava.io.IOException{
if(urlenc==null)return;
StringTokenizertok=newStringTokenizer(urlenc,"&");
try{
while(tok.hasMoreTokens()){
StringaPair=tok.nextToken();
intpos=aPair.indexOf("=");
Stringname=null;
Stringvalue=null;
if(pos!=-1){
name=decode(aPair.substring(0,pos));
value=decode(aPair.substring(pos+1));
}else{
name=aPair;
value="";
}
if(pairs.containsKey(name)){
ArrayListvalues=(ArrayList)pairs.get(name);
values.add(value);
}else{
ArrayListvalues=newArrayList();
values.add(value);
pairs.put(name,values);
}
}
}catch(Exceptione){
thrownewjava.io.IOException(e.getMessage());
}
}
/**
*Insertthemethodsdescriptionhere.
*Creationdate:(2001-2-420:34:37)
*@paramurlencjava.lang.String
*/
privatevoidparse(Stringurlenc,Stringencoding)throwsjava.io.IOException{
if(urlenc==null)return;
StringTokenizertok=newStringTokenizer(urlenc,"&");
try{
while(tok.hasMoreTokens()){
StringaPair=tok.nextToken();
intpos=aPair.indexOf("=");
Stringname=null;
Stringvalue=null;
if(pos!=-1){
name=decode(aPair.substring(0,pos),encoding);
value=decode(aPair.substring(pos+1),encoding);
}else{
name=aPair;
value="";
}
if(pairs.containsKey(name)){
ArrayListvalues=(ArrayList)pairs.get(name);
values.add(value);
}else{
ArrayListvalues=newArrayList();
values.add(value);
pairs.put(name,values);
}
}
}catch(Exceptione){
thrownewjava.io.IOException(e.getMessage());
}
}
}
这个类的功效就是读取并保留form提交的信息,并完成经常使用的getParameter办法。
packagecom.hto.servlet;
importjava.io.*;
importjavax.servlet.*;
importjavax.servlet.http.*;
/**
*Insertthetypesdescriptionhere.
*Creationdate:(2001-2-58:28:20)
*@author:钱卫春
*/
publicclassUtfBaseServletextendsHttpServlet{
publicstaticfinalStringPARAMS_ATTR_NAME="PARAMS_ATTR_NAME";
/**
*ProcessincomingHTTPGETrequests
*
*@paramrequestObjectthatencapsulatestherequesttotheservlet
*@paramresponseObjectthatencapsulatestheresponsefromtheservlet
*/
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
performTask(request,response);
}
/**
*ProcessincomingHTTPPOSTrequests
*
*@paramrequestObjectthatencapsulatestherequesttotheservlet
*@paramresponseObjectthatencapsulatestheresponsefromtheservlet
*/
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
performTask(request,response);
}
/**
*Insertthemethodsdescriptionhere.
*Creationdate:(2001-2-58:52:43)
*@returnint
*@paramrequestjavax.servlet.http.HttpServletRequest
*@paramnamejava.lang.String
*@paramrequiredboolean
*@paramdefValueint
*/
publicstaticjava.sql.DategetDateParameter(HttpServletRequestrequest,Stringname,booleanrequired,java.sql.DatedefValue)throwsServletException{
Stringvalue=getParameter(request,name,required,String.valueOf(defValue));
returnjava.sql.Date.valueOf(value);
}
/**
*Insertthemethodsdescriptionhere.
*Creationdate:(2001-2-58:52:43)
*@returnint
*@paramrequestjavax.servlet.http.HttpServletRequest
*@paramnamejava.lang.String
*@paramrequiredboolean
*@paramdefValueint
*/
publicstaticdoublegetDoubleParameter(HttpServletRequestrequest,Stringname,booleanrequired,doubledefValue)throwsServletException{
Stringvalue=getParameter(request,name,required,String.valueOf(defValue));
returnDouble.parseDouble(value);
}
/**
*Insertthemethodsdescriptionhere.
*Creationdate:(2001-2-58:52:43)
*@returnint
*@paramrequestjavax.servlet.http.HttpServletRequest
*@paramnamejava.lang.String
*@paramrequiredboolean
*@paramdefValueint
*/
publicstaticfloatgetFloatParameter(HttpServletRequestrequest,Stringname,booleanrequired,floatdefValue)throwsServletException{
Stringvalue=getParameter(request,name,required,String.valueOf(defValue));
returnFloat.parseFloat(value);
}
/**
*Insertthemethodsdescriptionhere.
*Creationdate:(2001-2-58:52:43)
*@returnint
*@paramrequestjavax.servlet.http.HttpServletRequest
*@paramnamejava.lang.String
*@paramrequiredboolean
*@paramdefValueint
*/
publicstaticintgetIntParameter(HttpServletRequestrequest,Stringname,booleanrequired,intdefValue)throwsServletException{
Stringvalue=getParameter(request,name,required,String.valueOf(defValue));
returnInteger.parseInt(value);
}
/**
*Insertthemethodsdescriptionhere.
*Creationdate:(2001-2-58:43:36)
*@returnjava.lang.String
*@paramrequestjavax.servlet.http.HttpServletRequest
*@paramnamejava.lang.String
*@paramrequiredboolean
*@paramdefValuejava.lang.String
*/
publicstaticStringgetParameter(HttpServletRequestrequest,Stringname,booleanrequired,StringdefValue)throwsServletException{
if(request.getAttribute(UtfBaseServlet.PARAMS_ATTR_NAME)!=null){
UTF8ParameterReaderparams=(UTF8ParameterReader)request.getAttribute(UtfBaseServlet.PARAMS_ATTR_NAME);
if(params.getParameter(name)!=null)returnparams.getParameter(name);
if(required)thrownewServletException("TheParameter"+name+"Requiredbutnotprovided!");
elsereturndefValue;
}else{
if(request.getParameter(name)!=null)returnrequest.getParameter(name);
if(required)thrownewServletException("TheParameter"+name+"Requiredbutnotprovided!");
elsereturndefValue;
}
}
/**
*Returnstheservletinfostring.
*/
publicStringgetServletInfo(){
returnsuper.getServletInfo();
}
/**
*Insertthemethodsdescriptionhere.
*Creationdate:(2001-2-58:52:43)
*@returnint
*@paramrequestjavax.servlet.http.HttpServletRequest
*@paramnamejava.lang.String
*@paramrequiredboolean
*@paramdefValueint
*/
publicstaticjava.sql.TimestampgetTimestampParameter(HttpServletRequestrequest,Stringname,booleanrequired,java.sql.TimestampdefValue)throwsServletException{
Stringvalue=getParameter(request,name,required,String.valueOf(defValue));
returnjava.sql.Timestamp.valueOf(value);
}
/**
*Initializestheservlet.
*/
publicvoidinit(){
//insertcodetoinitializetheservlethere
}
/**
*Processincomingrequestsforinformation
*
*@paramrequestObjectthatencapsulatestherequesttotheservlet
*@paramresponseObjectthatencapsulatestheresponsefromtheservlet
*/
publicvoidperformTask(HttpServletRequestrequest,HttpServletResponseresponse){
try
{
//Insertusercodefromhere.
}
catch(ThrowabletheException)
{
//uncommentthefollowinglinewhenunexpectedexceptions
//areoccuringtoaidindebuggingtheproblem.
//theException.printStackTrace();
}
}
/**
*Insertthemethodsdescriptionhere.
*Creationdate:(2001-2-58:31:54)
*@paramrequestjavax.servlet.ServletRequest
*@paramresponsejavax.servlet.ServletResponse
*@exceptionjavax.servlet.ServletExceptionTheexceptiondescription.
*@exceptionjava.io.IOExceptionTheexceptiondescription.
*/
publicvoidservice(ServletRequestrequest,ServletResponseresponse)throwsjavax.servlet.ServletException,java.io.IOException{
Stringcontent=request.getContentType();
if(content==null||content!=null&&content.toLowerCase().startsWith("application/x-www-form-urlencoded"))
request.setAttribute(PARAMS_ATTR_NAME,newUTF8ParameterReader((HttpServletRequest)request));
super.service(request,response);
}
}
这个就是Servlet基类,它掩盖了父类的service办法,在挪用父类service前,创立了UTF8ParameterReader对象,个中保留了form中提交的信息。然后把这个对象作为一个Attribute保留到Request对象中。然后还是挪用父类的service办法。
关于承继这个类的Servlet,要注重的是,"尺度"getParameter在也不克不及读到post的数据,由于在这之前这个类中已从ServletInputStream中读出了数据了。以是应当利用该类中供应的getParameter办法。
剩下的就是输入成绩了,我们要把输入的信息,转为UTF8的二进制流输入。只需我们设置Content-Type时指定charset为UTF8,然后利用PrintWriter输入,那末这些转换是主动举行的,Servlet中如许设置:
response.setContentType("text/html;charset=UTF8");
Jsp中如许设置:
<%@pagecontentType="text/html;charset=UTF8"%>
如许就能够包管输入是UTF8流,客户端可否显现,就看客户真个了。
因为能用到多少功能就用多少,不能用就不用!总的来说:要简单要性能好,可以不用框架。你说java复杂,就是因为你把java(j2ee)与这些框架混在了一起。 |
|