仓酷云

标题: JAVA网页设计Servlet、Jsp中的多国言语显现 [打印本页]

作者: 活着的死人    时间: 2015-1-18 11:39
标题: JAVA网页设计Servlet、Jsp中的多国言语显现
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)与这些框架混在了一起。
作者: 深爱那片海    时间: 2015-1-21 12:29
自从Sun推出Java以来,就力图使之无所不包,所以Java发展到现在,按应用来分主要分为三大块:J2SE,J2ME和J2EE,这也就是Sun ONE(Open Net Environment)体系。J2SE就是Java2的标准版,主要用于桌面应用软件的编程;J2ME主要应用于嵌入是系统开发,如手机和PDA的编程;J2EE是Java2的企业版,主要用于分布式的网络程序的开发,如电子商务网站和ERP系统。
作者: 透明    时间: 2015-1-30 18:18
其实说这种话的人就如当年小日本号称“三个月拿下中国”一样大言不惭。不是Tomjava泼你冷水,你现在只是学到了Java的骨架,却还没有学到Java的精髓。接下来你得研究设计模式了。
作者: 乐观    时间: 2015-2-3 12:33
是一种语言,用以产生「小应用程序(Applet(s))
作者: 小妖女    时间: 2015-2-4 22:25
还好,SUN提供了Javabean可以把你的JSP中的 Java代码封装起来,便于调用也便于重用。
作者: 灵魂腐蚀    时间: 2015-2-6 16:10
Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。
作者: 蒙在股里    时间: 2015-2-7 07:25
那么我书也看了,程序也做了,别人问我的问题我都能解决了,是不是就成为高手了呢?当然没那么简单,这只是万里长征走完了第一步。不信?那你出去接一个项目,你知道怎么下手吗,你知道怎么设计吗,你知道怎么组织人员进行开发吗?你现在脑子里除了一些散乱的代码之外,可能再没有别的东西了吧!
作者: 金色的骷髅    时间: 2015-2-19 08:50
科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。
作者: 简单生活    时间: 2015-2-26 11:39
是一种为 Internet发展的计算机语言
作者: 小女巫    时间: 2015-3-8 14:36
象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发。
作者: 再见西城    时间: 2015-3-15 09:45
你快去找一份Java的编程工作来做吧(如果是在校学生可以去做兼职啊),在实践中提高自己,那才是最快的。不过你得祈祷在公司里碰到一个高手,而且他 还愿意不厌其烦地教你,这样好象有点难哦!还有一个办法就是读开放源码的程序了。我们知道开放源码大都出自高手,他们设计合理,考虑周到,再加上有广大的程序员参与,代码的价值自然是字字珠叽,铿锵有力(对不起,偶最近《金装四大才子》看多了)。
作者: 飘飘悠悠    时间: 2015-3-18 09:56
关于设计模式的资料,还是向大家推荐banq的网站 [url]http://www.jdon.com/[/url],他把GOF的23种模式以通俗易懂的方式诠释出来,纯Java描述,真是经典中的经典。
作者: 谁可相欹    时间: 2015-3-20 11:14
那么我书也看了,程序也做了,别人问我的问题我都能解决了,是不是就成为高手了呢?当然没那么简单,这只是万里长征走完了第一步。不信?那你出去接一个项目,你知道怎么下手吗,你知道怎么设计吗,你知道怎么组织人员进行开发吗?你现在脑子里除了一些散乱的代码之外,可能再没有别的东西了吧!
作者: 飘灵儿    时间: 2015-3-27 00:10
科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。
作者: 不帅    时间: 2015-4-9 13:47
是一种使用者不需花费很多时间学习的语言
作者: 只想知道    时间: 2015-4-16 01:44
Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。
作者: 再现理想    时间: 2015-6-18 22:46
是一种为 Internet发展的计算机语言
作者: 变相怪杰    时间: 2015-6-27 15:07
[url]http://www.jdon.com/[/url]去下载,或到同济技术论坛的服务器[url]ftp://nro.shtdu.edu.cn[/url]去下,安装上有什么问题,可以到论坛上去提问。
作者: 山那边是海    时间: 2015-6-28 03:27
Java自面世后就非常流行,发展迅速,对C++语言形成了有力冲击。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于个人PC、数据中心、游戏控制台
作者: 精灵巫婆    时间: 2015-7-20 02:49
有时间再研究一下MVC结构(把Model-View-Control分离开的设计思想)
作者: 老尸    时间: 2015-7-21 00:44
我大二,Java也只学了一年,觉得还是看thinking in java好,有能力的话看英文原版(中文版翻的不怎么好),还能提高英文文档阅读能力。




欢迎光临 仓酷云 (http://ckuyun.com/) Powered by Discuz! X3.2