大雀软件园

首页 软件下载 安卓市场 苹果市场 电脑游戏 安卓游戏 文章资讯 驱动下载
技术开发 网页设计 图形图象 数据库 网络媒体 网络安全 站长CLUB 操作系统 媒体动画 安卓相关
当前位置: 首页 -> 技术开发 -> JSP专区 -> Servlet、Jsp中的多国语言显示

Servlet、Jsp中的多国语言显示

时间: 2021-07-31 作者:daque

  由于从来不信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流或数组:"华文尝试"----->"\u4e2d\u6587\u6d4b\u8bd5"----->"华文尝试"。如次例程:byte[] bytes = new byte[]{(byte)0xd6, (byte)0xd0, (byte)0xce, (byte)0xc4, (byte)0xb2, (byte)0xe2, (byte)0xca, (byte)0xd4};//gbk源代码的"华文尝试"java.io.bytearrayinputstream bin = new java.io.bytearrayinputstream(bytes);java.io.bufferedreader reader = new java.io.bufferedreader(new java.io. inputstreamreader (bin,"gbk"));string msg = reader.readline();system.out.println(msg)  这段步调放到包括"华文尝试"这四个字的体例(如华文体例)中,不妨精确地打字与印刷出那些字。msg字符串中包括了精确的"华文尝试"的unicode源代码:"\u4e2d\u6587\u6d4b\u8bd5",打字与印刷时变换为操纵体例的默许字符集,能否不妨精确表露依附于操纵体例的字符集,惟有在扶助相映字符集的体例中,咱们的消息本领精确的输入,要不获得的将会是废物。  话入正题,咱们来看看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位的,而utf第88中学一个中国字却是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本领:public static string decode(string s,string encoding) throws exception {stringbuffer sb = new stringbuffer();for(int i=0; i<s.length(); i++) {char c = s.charat(i);switch (c) {case '+':sb.append(' ');break;case '%':try {sb.append((char)integer.parseint(s.substring(i+1,i+3),16));}catch (numberformatexception e) {throw new illegalargumentexception();}i += 2;break;default:sb.append(c);break;}}// undo conversion to external encodingstring result = sb.tostring();byte[] inputbytes = result.getbytes("8859_1");return new string(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提交的实质,请看底下的源代码:package com.hto.servlet;

import javax.servlet.http.httpservletrequest;import java.util.*;/*** insert the type's description here.* creation date: (2001-2-4 15:43:46)* @author: 钱卫春*/public class utf8parameterreader {hashtable pairs = new hashtable();/*** utf8parameterreader constructor comment.*/public utf8parameterreader(httpservletrequest request) throws java.io.ioexception{super();parse(request.getquerystring());parse(request.getreader().readline());}/*** utf8parameterreader constructor comment.*/public utf8parameterreader(httpservletrequest request,string encoding) throws java.io.ioexception{super();parse(request.getquerystring(),encoding);parse(request.getreader().readline(),encoding);}public static string decode(string s) throws exception {stringbuffer sb = new stringbuffer();for(int i=0; i<s.length(); i++) {char c = s.charat(i);switch (c) {case '+':sb.append(' ');break;case '%':try {sb.append((char)integer.parseint(s.substring(i+1,i+3),16));}catch (numberformatexception e) {throw new illegalargumentexception();}i += 2;break;default:sb.append(c);break;}}// undo conversion to external encodingstring result = sb.tostring();byte[] inputbytes = result.getbytes("8859_1");return new string(inputbytes,"utf8");}public static string decode(string s,string encoding) throws exception {stringbuffer sb = new stringbuffer();for(int i=0; i<s.length(); i++) {char c = s.charat(i);switch (c) {case '+':sb.append(' ');break;case '%':try {sb.append((char)integer.parseint(s.substring(i+1,i+3),16));}catch (numberformatexception e) {throw new illegalargumentexception();}i += 2;break;default:sb.append(c);break;}}// undo conversion to external encodingstring result = sb.tostring();byte[] inputbytes = result.getbytes("8859_1");return new string(inputbytes,encoding);}/*** insert the method's description here.* creation date: (2001-2-4 17:30:59)* @return java.lang.string* @param name java.lang.string*/public string getparameter(string name) {if (pairs == null || !pairs.containskey(name)) return null;return (string)(((arraylist) pairs.get(name)).get(0));}/*** insert the method's description here.* creation date: (2001-2-4 17:28:17)* @return java.util.enumeration*/public enumeration getparameternames() {if (pairs == null) return null;return pairs.keys();}/*** insert the method's description here.* creation date: (2001-2-4 17:33:40)* @return java.lang.string[]* @param name java.lang.string*/public string[] getparametervalues(string name) {if (pairs == null || !pairs.containskey(name)) return null;arraylist al = (arraylist) pairs.get(name);string[] values = new string[al.size()];for(int i=0;i<values.length;i++)values = (string) al.get(i);return values;}/*** insert the method's description here.* creation date: (2001-2-4 20:34:37)* @param urlenc java.lang.string*/private void parse(string urlenc) throws java.io.ioexception{if (urlenc == null) return;stringtokenizer tok = new stringtokenizer(urlenc,"&");try{while (tok.hasmoretokens()){string apair = tok.nexttoken();int pos = apair.indexof("=");string name = null;string value = null;if(pos != -1){name = decode(apair.substring(0,pos));value = decode(apair.substring(pos+1));}else{name = apair;value = "";}if(pairs.containskey(name)){arraylist values = (arraylist)pairs.get(name);values.add(value);}else{arraylist values = new arraylist();values.add(value);pairs.put(name,values);}}}catch(exception e){throw new java.io.ioexception(e.getmessage());}}/*** insert the method's description here.* creation date: (2001-2-4 20:34:37)* @param urlenc java.lang.string*/private void parse(string urlenc,string encoding) throws java.io.ioexception{if (urlenc == null) return;stringtokenizer tok = new stringtokenizer(urlenc,"&");try{while (tok.hasmoretokens()){string apair = tok.nexttoken();int pos = apair.indexof("=");string name = null;string value = 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)){arraylist values = (arraylist)pairs.get(name);values.add(value);}else{arraylist values = new arraylist();values.add(value);pairs.put(name,values);}}}catch(exception e){throw new java.io.ioexception(e.getmessage());}}}这个类的功效即是读取并生存form提交的消息,并实行常用的getparameter本领。package com.hto.servlet;

import java.io.*;import javax.servlet.*;import javax.servlet.http.*;/*** insert the type's description here.* creation date: (2001-2-5 8:28:20)* @author: 钱卫春*/public class utfbaseservlet extends httpservlet {public static final string params_attr_name = "params_attr_name";/*** process incoming http get requests * * @param request object that encapsulates the request to the servlet * @param response object that encapsulates the response from the servlet*/public void doget(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {

performtask(request, response);

}/*** process incoming http post requests * * @param request object that encapsulates the request to the servlet * @param response object that encapsulates the response from the servlet*/public void dopost(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {

performtask(request, response);

}/*** insert the method's description here.* creation date: (2001-2-5 8:52:43)* @return int* @param request javax.servlet.http.httpservletrequest* @param name java.lang.string* @param required boolean* @param defvalue int*/public static java.sql.date getdateparameter(httpservletrequest request, string name, boolean required, java.sql.date defvalue) throws servletexception{string value = getparameter(request,name,required,string.valueof(defvalue));return java.sql.date.valueof(value);}/*** insert the method's description here.* creation date: (2001-2-5 8:52:43)* @return int* @param request javax.servlet.http.httpservletrequest* @param name java.lang.string* @param required boolean* @param defvalue int*/public static double getdoubleparameter(httpservletrequest request, string name, boolean required, double defvalue) throws servletexception{string value = getparameter(request,name,required,string.valueof(defvalue));return double.parsedouble(value);}/*** insert the method's description here.* creation date: (2001-2-5 8:52:43)* @return int* @param request javax.servlet.http.httpservletrequest* @param name java.lang.string* @param required boolean* @param defvalue int*/public static float getfloatparameter(httpservletrequest request, string name, boolean required, float defvalue) throws servletexception{string value = getparameter(request,name,required,string.valueof(defvalue));return float.parsefloat(value);}/*** insert the method's description here.* creation date: (2001-2-5 8:52:43)* @return int* @param request javax.servlet.http.httpservletrequest* @param name java.lang.string* @param required boolean* @param defvalue int*/public static int getintparameter(httpservletrequest request, string name, boolean required, int defvalue) throws servletexception{string value = getparameter(request,name,required,string.valueof(defvalue));return integer.parseint(value);}/*** insert the method's description here.* creation date: (2001-2-5 8:43:36)* @return java.lang.string* @param request javax.servlet.http.httpservletrequest* @param name java.lang.string* @param required boolean* @param defvalue java.lang.string*/public static string getparameter(httpservletrequest request, string name, boolean required, string defvalue) throws servletexception{if(request.getattribute(utfbaseservlet.params_attr_name) != null) {utf8parameterreader params = (utf8parameterreader)request.getattribute(utfbaseservlet.params_attr_name);if (params.getparameter(name) != null) return params.getparameter(name);if (required) throw new servletexception("the parameter "+name+" required but not provided!");else return defvalue;}else{if (request.getparameter(name) != null) return request.getparameter(name);if (required) throw new servletexception("the parameter "+name+" required but not provided!");else return defvalue;}}/*** returns the servlet info string.*/public string getservletinfo() {

return super.getservletinfo();

}/*** insert the method's description here.* creation date: (2001-2-5 8:52:43)* @return int* @param request javax.servlet.http.httpservletrequest* @param name java.lang.string* @param required boolean* @param defvalue int*/public static java.sql.timestamp gettimestampparameter(httpservletrequest request, string name, boolean required, java.sql.timestamp defvalue) throws servletexception{string value = getparameter(request,name,required,string.valueof(defvalue));return java.sql.timestamp.valueof(value);}/*** initializes the servlet.*/public void init() {// insert code to initialize the servlet here

}/*** process incoming requests for information* * @param request object that encapsulates the request to the servlet * @param response object that encapsulates the response from the servlet*/public void performtask(httpservletrequest request, httpservletresponse response) {

try

{// insert user code from here.

}catch(throwable theexception){// uncomment the following line when unexpected exceptions// are occuring to aid in debugging the problem.//theexception.printstacktrace();}}/*** insert the method's description here.* creation date: (2001-2-5 8:31:54)* @param request javax.servlet.servletrequest* @param response javax.servlet.servletresponse* @exception javax.servlet.servletexception the exception description.* @exception java.io.ioexception the exception description.*/public void service(servletrequest request, servletresponse response) throws javax.servlet.servletexception, java.io.ioexception {string content = request.getcontenttype();if(content == null || content != null && content.tolowercase().startswith("application/x-www-form-urlencoded"))request.setattribute(params_attr_name,new utf8parameterreader((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中如许树立:  <%@ page contenttype="text/html;charset=utf8"%>  如许就不妨保护输入是utf8流,存户端是否表露,就看存户端的了。

热门阅览

最新排行

Copyright © 2019-2021 大雀软件园(www.daque.cn) All Rights Reserved.