戴尔电脑i5多少钱一台

【转】 servlet中怎样接收jsp的form表单的内容 -
- ITeye技术网站
博客分类:
转载自 chunying031最终编辑 chunying031可以查servet的apigetParameterNames(),getParameterMap(),getInputStream(),getAttributeNames(),getParameterValues()等 code:
package com.java91.lesson01;
import java.io.IOE
import java.io.PrintW
import java.util.E
import java.util.M
import javax.servlet.ServletE
import javax.servlet.http.C
import javax.servlet.http.HttpS
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpS
public class RequestTestServlet extends HttpServlet {
&&&
&&& public void doGet(HttpServletRequest request, HttpServletResponse response)
&&&&&&&&&&& throws ServletException, IOException {
&&&&&&&
&&&&&&& //读取表单参数
&&&&&&&
&&&&&&& request.setCharacterEncoding("utf-8");//使用什么编码读客户端发过来的二进制数据,需要与HTML编码保持一致。在TOMCAT中,如果是get方法传过来的数据,可能不起作用。
&&&&&&&
&&&&&&& String sno=request.getParameter("sno");//获取单个、指定参数的值
&&&&&&& System.out.println("-----request.getParameter('sno'):"+sno);
&&&&&&&
&&&&&&& String sname=request.getParameter("sname");//获取单个、指定参数的值
&&&&&&& System.out.println("-----request.getParameter('sname'):"+sname);
&&&&&&&
&&&&&&& String grade[]=request.getParameterValues("grade");//获取单个、指定参数的所有值。(一个参数可能有多个值的情况)
&&&&&&& System.out.println("-----request.getParameterValues('grade'):"+grade[0]+","+grade[1]);&&&&&&&
&&&&&&& Enumeration enume= request.getParameterNames();//返回一个枚举类型(Enumeration)的实例,值为表单的所有参数名
&&&&&&&
&&&&&&& Map map=request.getParameterMap();//返回一个Map实例,键-值成对的形式,键为参数名,值为参数值
&&&&&&& System.out.println("-----request.getParameterMap():"+map);&&&
&&&&&&& //其它信息
&&&&&&&
&&&&&&& String encoding=request.getCharacterEncoding();//&&&&& 返回请求所用的字符编码。
&&&&&&& System.out.println("-----request.getCharacterEncoding(): "+encoding);&&&&&&&&&&&
&&&&&&& String protocol=request.getProtocol();//返回发送请求所使用的名字和版本号,如:HTTP/1.1
&&&&&&& System.out.println("-----request.getProtocol(): "+protocol);&&&
&&&&&&& String ip=request.getRemoteAddr();//返回客户端的IP地址
&&&&&&& System.out.println("-----request.getRemoteAddr(): "+ip);&&&&&&&&&&&
&&&&&&& String scheme =request.getScheme();//返回请求使用的方法的名字,如http,https,ftp等。
&&&&&&& System.out.println("-----request.getScheme(): "+scheme);&&&&&&&&&&&
&&&&&&& String serverName=request.getServerName();//返回服务器的名字
&&&&&&& System.out.println("-----request.getServerName(): "+serverName);&&&&&&&
&&&&&&& int port=request.getServerPort();//返回请求被接收的端口号。
&&&&&&& System.out.println("-----request.getServerPort(): "+port);
&&&&&&&
&&&&&&& String uri=request.getContextPath();//获取标示请求内容的URI的请求部分。
&&&&&&& System.out.println("-----request.getContextPath(): "+uri);
&&&&&&&
&&&&&&& String method=request.getMethod();//返回该请求的HTTP方法名字,如GET/POST
&&&&&&& System.out.println("-----request.getMethod(): "+method);&&&&&&&
&&&&&&& String pathInfo=request.getPathInfo();//返回发出请求的URL客户的相关额外路径信息
&&&&&&& System.out.println("-----request.getPathInfo(): "+pathInfo);&&&&&&&
&&&&&&& String queryString=request.getQueryString();//获取发出请求的URL的路径之后的查询串。
&&&&&&& System.out.println("-----request.getQueryString(): "+queryString);&&&&&&&
&&&&&&& String reURI=request.getRequestURI();//获取在HTTP请求的第一行中的,请求URL中从协议名到查询串的部分。
&&&&&&& System.out.println("-----request.getRequestURI(): "+reURI);&&&&&&&
&&&&&&& StringBuffer reURL=request.getRequestURL();//重构一个发出该请求的URL对象
&&&&&&& System.out.println("-----request.getRequestURL(): "+reURL);&&&&&&&
&&&&&&& String servletPath=request.getServletPath();//获取调用servlet的请求URL部分
&&&&&&& System.out.println("-----request.getServletPath(): "+servletPath);
&&&&&&&
&&&&&&& Enumeration lang=request.getHeaders("Accept-Language");//返回指定报头的所有值
&&&&&&&
&&&&&&& /*什么是cookie
&&&&&&&&
&&&&&&&&    出于安全考虑,动态网站开发语言,无法存储和操作客户端电脑的文件/数据。避免病毒传播&&&&&&&&
&&&&&&&    HTTP提供了一种机制,指定了一个特殊的存储空间,允许服务器向客户端电脑存储少量数据
&&&&&&&
&&&&&&& 到该空间 ,该空间被有效的安全控制,对客户端电脑不会造成影响。&&&&&&&&
&&&&&&&    
&&&&&&&    它可以记录你的用户ID、密码、浏览过的网页、停留的时间等信息。当你再次来到该网站时,
&&&&&&&
&&&&&&& 网站通过读取Cookies,得知你的相关信息,就可以做出相应的动作,如在页面显示欢迎你的标语,
&&&&&&&
&&&&&&& 或者让你不用输入ID、密码就直接登录等等。
&&&&&&&
&&&&&&& */
&&&&&&&
&&&&&&& //打印所有cookies的值:只有本网站留的cookie才会被带回,其它网站不返回
&&&&&&&
&&&&&&& Cookie [] cook = request.getCookies(); //返回cookie类型的数组
&&&&&&& if (cook != null){
&&&&&&&&&&& for(int i =0; i&cook. i++){
&&&&&&&&&&&&&&& Cookie c=cook[i];
&&&&&&&&&&&&&&& System.out.println(c.getName()+":"+c.getValue());
&&&&&&&&&&& }
&&&&&&& }
&&&&&&&
//&&&&&&& 读取cookie值
&&&&&&&
&&&&&&& String cookieName="userID";&&&&&&&& //要读取的cookie名为userID
&&&&&&& String cookieValue="";&&&&&&&&&&&&&&&& //存放读出的cookie值
&&&&&&& Cookie [] cook2 = request.getCookies(); //返回cookie类型的数组
&&&&&&& if (cook != null){
&&&&&&&&&&& for(int i =0; i&cook2. i++){
&&&&&&&&&&&&&&& Cookie c=cook2[i];
&&&&&&&&&&&&&&& if (cookieName.equals(c.getName())){
&&&&&&&&&&&&&&&&&&& cookieValue=c.getValue();
&&&&&&&&&&&&&&&&&&& System.out.println("cookieValue:"+cookieValue);
&&&&&&&&&&&&&&& }
&&&&&&&&&&& }
&&&&&&& }
&&&&&&& //向客户端安装一个cookie
&&&&&&&
&&& /*&&& Cookie cookie = new Cookie("userID" , "1234");&&&&&&&
&&&&&&& cookie.setMaxAge(60*60*24*7); //保留7天时间。如果设为0则删除该&&& cookie。无设置则为当前会话&&&&&&&
&&&&&&& response.addCookie(cookie);
&&&&&&&
&&&&&&& */
&&&&&&&
&&&&&&& // session机制
&&&&&&&
&&&&&&& HttpSession session = request.getSession();//返回当前会话,如果会话不存在,则创建一个新的会话
&&&&&&&
&&&&&&& session.invalidate();
&&&&&&&
&&&&&&& /*&&&&&&&&&&&
&&&&&&& public ServletInputStream getInputStream() throws IOException//用ServletInputStream得到请求的二进制数据
&&&&&&& public BufferReader getReader() throws IOException//用BufferReader读取请求体文本&&&&&&&&&&&
&&&&&&& public RequestDispatcher getRequestDispatcher(String path)//返回指定路径上的资源的RequestDispatcher对象&&&
&&&&&&& public long getDateHeader(String name)//返回指定报头的值,作为长整型的日期值返回(毫秒)
&&&&&&& public String getHeader(String name)
&&&&&&& public Enumeration getHeaderNames()
&&&&&&& public Enumeration getHeaders(String name)//返回指定报头的所有值
&&&&&&& public int getIntHeader(String name)//返回指定报头的值,作为整型返回&&&&&&&
&&&&&&& public String getRequestedSessionId()//返回客户的essionID号
&&&&&&& public HttpSession getSession()//获取和当前请求相关联的session对象。如果没有则创建一个
&&&&&&& public HttpSession getSession(true)//获取和当前请求相关联的session对象,如果没有则创建一个
&&&&&&& public HttpSession getSession(false)//获取和当前请求相关联的session对象,如果没有则返回null
&&&
&&&&&&& */
&&&&&&&
&&&&&&& //response.setContentType("text/charset=utf-8");//指定发送的文件类型为HTML,指定HTML文档编码格式为UTF-8&&&&&&&
&&&&&&& response.setContentType("text/html");//指定发送的文件类型为HTML,指定HTML文档编码格式为UTF-8&&&
&&&&&&& //response.setCharacterEncoding("gbk");
&&&&&&&
&&&&&&& PrintWriter out = response.getWriter();&&&&&&&
&&&&&&& out.println("&HTML&\n"
&&&&&&&&&&&&&&& + "&HEAD&&TITLE&Hello&/TITLE&&/HEAD&\n"
&&&&&&&&&&&&&&& + "&BODY BGCOLOR=\"#FDF5E6\"&\n" + "&H1&Hello java91 你好&/H1&\n"
&&&&&&&&&&&&&&& + "&/BODY&&/HTML&");
&&& }
&&&
&&& public void doPost(HttpServletRequest request, HttpServletResponse response)
&&& throws ServletException, IOException {
&&&&&&&
&&&&&&& doGet(request,response);
&&& }
&&&
stevenjohn
浏览: 898189 次
来自: 深圳
FileInputStream不要关闭啊?
在试用联通的wo邮箱的时候,uid是null的。目前其他邮箱正 ...
理解很有深度,赞一个!
楼主,能解释下 rest 和 http 请求有什么区别吗JSP中表单提交中文乱码解决方法
1.修改Tomcat配置文件文件:tomcat\conf\server.xml修改:&Connector 标签中添加 URIEncoding="UTF-8"所有页面指令:&%@ page language="java" pageEncoding="UTF-8"& %&2.在获取页面添加:request.setCharacterEncoding("UTF-8");数据提供页面和数据接收页面都采用UTF-8编码可以解决POST请求乱码3.使用new String(data.getBytes("ISO-8859-1"),"UTF-8");解决GET请求乱码可以编写一个工具类:public class UITools {&public static String decode(String data){&&try {&&&&&&return new String(data.getBytes("ISO-8859-1"),"UTF-8");&&} catch (UnsupportedEncodingException e) {&&&return "";&&}&}}调用方式:&%=UITools.decode(request.getParameter("data")) %&4.使用过滤器:----过滤器---public class MyFilter implements Filter {&public void destroy() {&&// TODO Auto-generated method stub&}&public void doFilter(ServletRequest request, ServletResponse arg1,&&&FilterChain arg2) throws IOException, ServletException {&&&&&&& for(Object& k :request.getParameterMap().keySet()){&&&&& request.setAttribute(k.toString(), UITools.decode( request.getParameter(k.toString())));&&&&& System.out.println(k.toString());&&&& }&&&& arg2.doFilter(request, arg1);&}&public void init(FilterConfig arg0) throws ServletException {&&// TODO Auto-generated method stub&}}--配置web.xml---&&filter&& &display-name&myfilter&/display-name&& &filter-name&myfilter&/filter-name&& &filter-class&mon.MyFilter&/filter-class&&&/filter&&&filter-mapping&&&& &filter-name&myfilter&/filter-name&&&& &url-pattern&/*&/url-pattern&&/filter-mapping&--使用数据--String name=request.getAttribute("name").toString();通过request.getAttribute获取数据
分享这篇日志的人也喜欢
外面的世界很精彩?
求新主播关注
热门日志推荐
人人最热标签
北京千橡网景科技发展有限公司:
文网文[号··京公网安备号·甲测资字
文化部监督电子邮箱:wlwh@··
文明办网文明上网举报电话: 举报邮箱:&&&&&&&&&&&&
请输入手机号,完成注册
请输入验证码
密码必须由6-20个字符组成
下载人人客户端
品评校花校草,体验校园广场IE6的“以UTF-8发送URL”选项设置对请求页面字符编码有影响吗? - 战隼 - ITeye技术网站
博客分类:
最近又碰到了中文乱码问题,这里我没有把数据库牵扯进来,先说下我的环境,servlet容器使用Tomcat6.0,浏览器FireFox3.0、IE6,涉及字符编码设置的地方我的思路就是编码的地方都统一使用UTF-8,具体配置如下:
1.所有页面的charset设置为UTF-8。
2.Tomcat的URIEncoding默认是ISO-8859-1,而我设置为UTF-8,主要是想解决中文命名的文件以及请求以get方式提交有可能出现的乱码问题。
3.添加过滤器,调用request.setCharacterEncoding("utf-8")方法将request的字符集设定为utf-8,解决请求以post方式提交的乱码问题。
其实这样的设置貌似是不会再出现乱码问题了,不过,问题依旧来了
,如果我在浏览器的地址栏中输入中文参数提交,返回的页面却出现了乱码。真搞不明白到底是哪里出了问题!说起来对中文乱码的问题一直是一支半解,出现乱码了,网上搜罗了一大堆资料,按照网上的配置,问题到是解决了,不过原理却搞的很模糊,一个请求发送到服务器,服务器业务逻辑处理后返回一个页面,这中间涉及的字符集转换,编码,解码过程一概不清楚。这次,折腾了半天,总算是更进一步了解了字符编码问题,这里做个总结。
先看我的总结,有不对的地方欢迎批评。
首先我们看下,一个请求响应的流程
浏览器 IE/FireFox -----------&Servlet容器------------------------&显示页面
使用容器的URIEncoding转码
我把用户发送请求方式不同引起的中文问题划分了四种类型:
1、表单的get提交
2、表单的post提交
3、页面链接传递中文参数
4、地址栏中参数直接输入中文提交
1.首先我们看表单get方式提交
浏览器根据页面的charset编码方式对页面进行编码,然后提交至服务器,首先进入对应的字符编码过滤器(如果有的话),不过Tomcat6.0对于get提交方式采用的是server.xml文件中的URIEncoding编码方式,而并不会采用过滤器中设置的编码,那么根据我的环境设置,jsp页面都使用UTF-8的编码,Servlet容器的URIEncoding也设置为UTF-8,则servlet不用进行转码即可正确解码,获得正常的中文字符串。那么,响应页面的中文因为页面的统一编码(UTF-8)自然也会正常显示。当然,如果我们Tomcat的URIEncoding设置为其他非UTF-8的编码方式时,页面的内容进入Tomcat解析时,因为Tomcat和页面的编码不统一,就需要转码。例如,如果我们采用Tomcat默认的ISO-8859-1,那么当我们使用request.getParameter("yourVariable
")获取表单参数值时其实Servlet就进行了转码,它会以容器编码方式进行解码,这个过程如下:
UTF-8(编码)--&ISO-58859-1(解码)
这个过程也相当于我们使用如下的语句
new String(变量值.getBytes("UTF-8"),"ISO-8859-1");
根据API的解释,先将变量值以UTF-8字符集编码转换为字节序列,再以ISO-8859-1字符集解码字节数组,构造出新的字符串对象。
等价于以下方式:
String code = "编码";
code = URLEncoder.encode(code,"UTF-8");
code = URLDecoder.decode(code,"ISO-8858-1");
例如表单的username属性以字符串"编辑"提交,那么进入容器后,FormBean中的这个变量会乱码,request.getParameter(username)一样的效果,s1就是request返回的结果,下面是内存快照。
不过即使这样,我们依然可以使用不恰当的方法显示正常的中文,即逆向转码,例如上面的乱码,我们可以通过ISO8859-1--&UTF-8这种方式还原我们提交时的中文。以下是GBK,UTF-8,ISO-8859-1三者之间互相转换的内存快照:
我们可以看到,偶数汉字可以在UTF-8,GBK两者中互相转换,而奇数个汉字则不能。综上看来,貌似Tomcat的URIEncoding设置为UTF-8是最好的解决办法,不过这样的设置依然无法解决上面我所说的第三、第四种情况。大家继续向下看。(这里有一点我不确定,就是页面提交至Servlet容器时,是以页面的charset方式编码后直接进入容器,还是以charset转码为ISO-8859-1方式进入,大家有什么见解?)2.表单的post提交
对于这种方式的请求,request.setCharacterEncoding("一般来自于web.xml中过滤器设置的参数")方法进行编码设置将会产生作用,struts的表单提交方式默认为post方式,那么按照上面我的环境设置,页面,容器,都采用UTF-8编码方式,就不会产生中文乱码问题。3.页面链接中传递中文参数
我虚拟一个这样的场景,请求页面中有如下代码
String username = "编辑";
&a href="hello.do?username=&%=username%&"&页面中链接传递中文&/a&
对于这种方式,我们需要先将参数使用统一的编码方式编码,将编码后的字符放入链接,这里我对参数以UTF-8方式编码,如下
String username = java.net.URLEncoder.encode("编辑","UTF-8");
那么这样我们也不会产生中文乱码问题
4.地址栏中参数直接输入中文提交
例如浏览器地址栏中输入"http://localhost:8080/helloapp.do?username=编辑"提交,对于这种方式,浏览器不会采用页面的charset方式对URL中的中文进行编码后提交至服务器(IE,FireFox都一样),而是采用系统的GBK转码为ISO-8859-1之后提交至Servlet容器,那么,如果对于前三种方式我们所做的设置,在这里就有问题了,因为进入容器时中文进行了GBK至ISO-8859-1的转码,而之前我们的Servlet容器URIEncoding设置为UTF-8,当我们使用request.getParameter("username")时,相当于又进行了这样的流程GBK--&ISO-8859-1--&UTF-8,按照以上我们使用的测试中文,“编辑”,使用request.getParameter("username")则会得到这样的结果??,下图是进行转码的内存快照:
我们可以看到
“编辑”经过从GBK--&ISO-8859-1--&UTF-8的过程后得到的就是??这样的结果,这里我们还会想到那进行2次逆向转码看看,不过可惜的是,结果为“锟洁辑”。对于这种情况,我们的解决办法就是,Tomcat的URIEncoding采用默认的ISO-8859-1字符集,那么我们可以在程序中通过ISO-8859-1--&GBK这样不恰当的逆向转码方式得到正常的中文“编辑”,但这样的结果是,我们get请求方式的中文处理解决办法就需要改变。如,在我的环境下就需要进行ISO-8859-1--&UTF-8的转码,挺不爽。
综上,对于乱码问题,前三种方式是一般用户的请求方式,第四种属于非正常途径的请求方式,对于这种方式产生的问题我认为无法很好的解决,也不需要解决。我看到javaeye对于这样的情况就没有处理,不知道大家在自己的项目中是如何处理的?我的实验是,IE6的设置会影响应用路径的编码方式,例如地址栏中请求一个中文JSP页面,如:http://localhost:8080/helloapp/编辑.jsp,IE默认是勾选"以UTF-8发送URL"项的,那么按照我上面总结的处理方式,这个请求可以正常显示页面,如图:
如果取消IE的这个选项,那么浏览器会以GBK编码应用路径的中文,得到的结果如图:
按照我上面的设置,这里如果将Tomcat的URIEncoding设置为GBK,则也可以正常显示页面。对于FireFox3.0,则是以UTF-8编码。
最后,回到我的题目,向大家讨教下,IE6的“以UTF-8发送URL”选项设置对请求页面字符编码有影响吗?欢迎讨论!
我的测试代码共享给大家:),使用的是struts1.2,struts的jar包,大家可以去apache下载。
这里推荐个链接,有兴趣的可以深入了解更多字符集、编码的问题。
/blog/97803
下载次数: 83
论坛回复 /
(1 / 9576)
battlehawk
浏览: 14877 次
来自: 西安
欢迎大家指点批评,讨论!过滤器设置编码,中文到达Action类中还是乱码 - ITeye问答
各位好,我试着用Filter来做统一编码,doFilter方法如下:
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,ServletException {
System.out.println("---------------------------doFilter");
req.setCharacterEncoding("UTF-8");
if (ignore || req.getCharacterEncoding()==null) {
String encoding = selectEncoding(req);
if (encoding != null) req.setCharacterEncoding(encoding);
else req.setCharacterEncoding(this.encoding);
chain.doFilter(req,res);
}
在web.xml里面的配置如下:
&filter&
&filter-name&encoding&/filter-name&
&filter-class&org.simon.filter.SetCharacterEncodingFilter&/filter-class&
&init-param&
&param-name&encoding&/param-name&
&param-value&utf-8&/param-value&
&/init-param&
&/filter&
&filter-mapping&
&filter-name&encoding&/filter-name&
&url-pattern&/*&/url-pattern&
&/filter-mapping&
JSP页面上的主要代码如下:
&%@ page language="java" import="java.util.*" pageEncoding="GB2312"%&
&form action="/helloworld/helloworldAction.action" method="post"&
&input type="hidden" name="submitFlag" value="login" /&
账号:&input type="text" name="account" /&&br /&
密码:&input type="password" name="password" /&&br /&
&input type="submit" value="提交" /&
&/form&
但是提交后,在Struts 2的Action类中接收到的中文还是乱码,但是把JSP中第一行中的pageEncoding="GB2312" 改成 pageEncoding="UTF-8",就没问题了。
我就是觉得很奇怪,过滤器不是在访问这个页面的时候就已经把编码设置成了UTF-8了吗?为什么还是会出现这种问题,中间做了什么呢?麻烦大家帮忙解决一下,谢谢了~~
采纳的答案
试试点到这个jsp文件然后点反键 找到最后一个Properties 在这设置一下他的编码 看行不行
应该是设置了编码格式,方便应用内部再次获取时按照此编码格式获取,但整个文本的内容却没有重新编码。所以页面上是GB2312,但在Filter中设置其为UTF-8,此时内容的编码仍旧是GB2312,所以到后台你按照Filter中设置的UTF-8获取内容出现了乱码。如果此处将内容按照UTF-8再编码一次,后台照此获取就没问题了。
因此需要各处统一。
在过滤器中设置的编码方式只针对于post请求方式有效,如果你的请求时get方式,依然会出现乱码的问题。
最好所以的页面和后台代码都统一编码 utf-8
&%@ page language="java" import="java.util.*" pageEncoding="utf-8"%&
由于服务器使用的编码方式不同和浏览器对不同的字符显示结果不同而导致的
1.问题的起源
  每个国家(或区域)都规定了计算机信息交换用的字符编码集,如美国的ASCII,中国的GB2312-80,日本的JIS等,作为该国家/区域内信息处理的基础,有着统一编码的重要作用。字符编码集按长度分为SBCS(单字节字符集),DBCS(双字节字符集)两大类。早期的软件(尤其是操作系统),为了解决本地字符信息的计算机处理,出现了各种本地化版本(L10N),为了区分,引进了LANG,Codepage等概念。但是由于各个本地字符集代码范围重叠,相互间信息交换困难;软件各个本地化版本独立维护成本较高。因此有必要将本地化工作中的共性抽取出来,作一致处理,将特别的本地化处理内容降低到最少。这也就是所谓的国际化(I18N)。各种语言信息被进一步规范为Locale信息。处理的底层字符集变成了几乎包含了所有字形的 Unicode。
  现在大部分具有国际化特征的软件核心字符处理都是以Unicode为基础的,在软件运行时根据当时的Locale/Lang/Codepage设置确定相应的本地字符编码设置,并依此处理本地字符。在处理过程中需要实现Unicode和本地字符集的相互转换,甚或以Unicode为中间的两个不同本地字符集的相互转换。这种方式在网络环境下被进一步延伸,任何网络两端的字符信息也需要根据字符集的设置转换成可接受的内容。
  Java 语言内部是用 Unicode 表示字符的,遵守 Unicode V2.0。Java 程序无论是从/往文件系统以字符流读/写文件,还是往 URL 连接写 HTML 信息,或从 URL 连接读取参数值,都会有字符编码的转换。这样做虽然增加了编程的复杂度,容易引起混淆,但却是符合国际化的思想的。
  从理论上来说,这些根据字符集设置而进行的字符转换不应该产生太多问题。而事实是由于应用程序的实际运行环境不同,Unicode和各个本地字符集的补充、完善,以及系统或应用程序实现的不规范,转码时出现的问题时时困扰着程序员和用户。
2.GB2312-80,GBK,GB 汉字字符集
  其实解决 JAVA 程序中的汉字编码问题的方法往往很简单,但理解其背后的原因,定位问题,还需
要了解现有的汉字编码和编码转换。
  GB2312-80是在国内计算机汉字信息技术发展初始阶段制定的,其中包含了大部分常用的一、二级汉字,和9区的符号。该字符集是几乎所有的中文系统和国际化的软件都支持的中文字符集,这也是最基本的中文字符集。其编码范围是高位0xa1-0xfe,低位也是 0xa1-0xfe;汉字从 0xb0a1 开始,结束于 0xf7fe;
  GBK是GB2312-80的扩展,是向上兼容的。它包含了20902个汉字,其编码范围是0x8140-0xfefe,剔除高位0x80的字位。其所有字符都可以一对一映射到Unicode2.0,也就是说JAVA实际上提供了GBK字符集的支持。这是现阶段Windows和其它一些中文操作系统的缺省字符集,但并不是所有的国际化软件都支持该字符集,感觉是他们并不完全知道GBK是怎么回事。值得注意的是它不是国家标准,而只是规范。随着GB国标的发布,它将在不久的将来完成它的历史使命。
  GB(GBK2K)在GBK的基础上进一步扩展了汉字,增加了藏、蒙等少数民族的字形。GBK2K从根本上解决了字位不够,字形不足的问题。它有几个特点:
  ●它并没有确定所有的字形,只是规定了编码范围,留待以后扩充。
  ●编码是变长的,其二字节部分与 GBK 兼容;四字节部分是扩充的字形、字位,其编码范围是首字节 0x81-0xfe、二字节0x30-0x39、三字节 0x81-0xfe、四字节0x30-0x39。
  ●它的推广是分阶段的,首先要求实现的是能够完全映射到 Unicode 3.0 标准的所有字形。
  ●它是国家标准,是强制性的。
  现在还没有任何一个操作系统或软件实现了 GBK2K 的支持,这是现阶段和将来汉化的工作内容。
3.JSP/Servlet 汉字编码问题及在 WAS 中的解决办法
  3.1 常见的 encoding 问题的现象
  网上常出现的 JSP/Servlet encoding 问题一般都表现在 browser 或应用程序端,如:
  ●浏览器中看到的 Jsp/Servlet 页面中的汉字怎么都成了 ’?’ ?
  ●浏览器中看到的 Servlet 页面中的汉字怎么都成了乱码?
  ●JAVA 应用程序界面中的汉字怎么都成了方块?
  ●Jsp/Servlet 页面无法显示 GBK 汉字。
  ●Jsp/Servlet 不能接收 form 提交的汉字。
  ●JSP/Servlet 数据库读写无法获得正确的内容。
  隐藏在这些问题后面的是各种错误的字符转换和处理(除第3个外,是因为Javafont设置错误引起的)。解决类似的字符encoding问题,需要了解 Jsp/Servlet 的运行过程,检查可能出现问题的各个点。
  3.2 JSP/Servlet web 编程时的 encoding 问题
  运行于Java 应用服务器的 JSP/Servlet 为 Browser 提供 HTML 内容,
  其中有字符编码转换的地方有:
  a.JSP 编译。Java 应用服务器将根据 JVM 的 file.encoding 值读取 JSP 源文件,并转换为内部字符编码进行 JSP 编译,生成 JAVA 源文件,根据file.encoding值写回文件系统。如果当前系统语言支持GBK,那么这时候不会出现encoding问题。如果是英文的系统,如LANG 是 en_US的Linux,AIX或Solaris,则要将JVM的file.encoding值置成GBK。系统语言如果是GB2312,则根据需要,确定要不要设置file.encoding,将 file.encoding 设为 GBK 可以解决潜在的 GBK 字符乱码问题
  b.Java需要被编译为.class才能在JVM中执行,这个过程存在与a.同样的file.encoding问题。从这里开始servlet和jsp的运行就类似了,只不过 Servlet 的编译不是自动进行的。
  c.Servlet需要将HTML页面内容转换为browser可接受的encoding内容发送出去。依赖于各JAVAAppServer的实现方式,有的将查询 Browser的accept-charset和accept-language参数或以其它猜的方式确定encoding值,有的则不管。因此constant-encoding也许是最好的解决方法。对于中文网页,可在JSP或Servlet中设置contentType="text/charset=GB2312";如果页面中有GBK字符,则设置为contentType="text/ charset=GBK",由于IE 和 Netscape对GBK的支持程度不一样,作这种设置时需要测试一下。
  因为16位JAVAchar在网络传送时高8位会被丢弃,也为了确保Servlet页面中的汉字(包括内嵌的和servlet运行过程中得到的)是期望的内码,可以用PrintWriterout=res.getWriter()取代ServletOutputStreamout=res.getOutputStream(),PrinterWriter将根据contentType中指定的charset作转换(ContentType需在此之前指定!);也可以用OutputStreamWriter封装ServletOutputStream类并用write(String)输出汉字字符串。 对于 JSP,JAVA Application Server 应当能够确保在这个阶段将嵌入的汉字正确传送出去。
  d.这是URL字符encoding问题。如果通过get/post方式从browser返回的值中包含汉字信息,servlet将无法得到正确的值。SUN的 J2SDK 中,HttpUtils.parseName 在解析参数时根本没有考虑 browser 的语言设置,而是将得到的值按 byte 方式解析。这是网上讨论得最多的 encoding问题。因为这是设计缺陷,只能以bin方式重新解析得到的字符串;或者以hackHttpUtils类的方式解决。参考文章2、3均有介绍,不过最好将其中的中文 encoding GB2312、 CP1381 都改为 GBK,否则遇到 GBK 汉字时,还是会有问题。
  ServletAPI2.3提供一个新的函数HttpServeletRequest.setCharacterEncoding用于在调用request.getParameter(“param_name”) 前指定应用程序希望的 encoding,这将有助于彻底解决这个问题。
  WebSphere Application Server 对标准的 Servlet API 2.x 作了扩展,提供较好的多语言支持。上述c,d情况,WAS 都要查询 Browser 的语言设置,在缺省状况下zh、zh-cn 等均被映射为 JAVA encoding CP1381(注意:CP1381 只是等同于 GB2312 的一个 codepage,没有 GBK 支持)。这样做我想是因为无法确认 Browser 运行的操作系统是支持GB2312, 还是 GBK,所以取其小。但是实际的应用
系统还是要求页面中出现 GBK 汉字,最著名的是朱总理名字中的“?”(rong2 ,0xe946,\u9555),所以有时还是需要将 Encoding/Charset 指定为 GBK。当然 WAS 中变更缺省的 encoding 没有上面说的那么麻烦,针对 a,b,参考文章 5 ),在 Application Server 的命令行参数中指定-Dfile.encoding=GBK即可;针对d,在ApplicationServer的命令行参数中指定-Ddefault.client.encoding=GBK。如果指定了-Ddefault.client.encoding=GBK,那么c情况下可以不再指定charset。
  3.3 数据库读写时的 encoding 问题
  JSP/Servlet 编程中经常出现 encoding 问题的另一个地方是读写数据库中的数据。流行的关系数据库系统都支持数据库 encoding,也就是说在创建数据库时可以指定它自己的字符集设置,数据库的数据以指定的编码形式存储。当应用程序访问数据时,在入口和出口处都会有 encoding 转换。对于中文数据,应当保证数据的完整性。GB2312,GBK,UTF-8 等都是可选的数据库 encoding;如果选择 ISO-bitSBCS),那么应用程序在写数据之前须将16Bit的一个汉字或Unicode拆分成两个8-bit的字符,读数据之后则需将两个字节合并起来,同时还有判别其中的 SBCS 字符。没有充分利用数据库 encoding 的作用,反而增加了编程的复杂度,ISO8859-1不是推荐的数据
库 encoding。JSP/Servlet编程时,可以先用数据库管理系统提供的功能检查其中的中文数据是否正确。
  然后应当注意的是读出来的数据的 encoding,JAVA 程序中一般得到的是 Unicode。写数据时则相反。
  3.4 定位问题时常用的技巧
  定位中文encoding问题通常采用最笨的也是最有效的办法——在你认为有嫌疑的程序处理后打印字符串的内码。通过打印字符串的内码,你可以发现什么时候中文字符被转换成Unicode,什么时候Unicode被转回中文内码,什么时候一个中文字成了两个Unicode字符,什么时候中文字符串被转成了一串问号,什么时候中文字符串的高位被截掉了……
  取用合适的样本字符串也有助于区分问题的类型。如:”aa啊aa?aa”等中英相间、GB、GBK特征字符均有的字符串。一般来说,英文字符无论怎么转换或处理,都不会失真(如果遇到了,可以尝试着增加连续的英文字母长度)
你的所有地方都统一编码,因为是同一个项目,最好是遵循同一个编码,否则就容易出现传递参数时出现乱码。
&%@ page language="java" import="java.util.*" pageEncoding="GB2312"%&
这句话设置了你的页面是GB2312的编码,所以就使得你UTF-8的编码在这里就得到乱码了。
首先项目是utf-8的编码,页面是utf-8的编码,action以及fiter都是
已解决问题
未解决问题

我要回帖

 

随机推荐