没有找到合适的产品?
联系客服协助选型:023-68661681
提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
原创|其它|编辑:郝浩|2009-12-29 11:36:51.000|阅读 1024 次
概述:当我们通过Java程序员的视角来浏览网页时会发现:一方面用户端浏览器(IE或Firefox)以表单或链接的方式提交HTTP请求同时又处理HTTP服务器发出的响应数据,将其中的数据流(HTML数据或其它种类的数据)以适当的方式展示给使用者浏览。
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
当我们通过Java程序员的视角来浏览网页时会发现:一方面用户端浏览器(IE或Firefox)以表单或链接的方式提交HTTP请求同时又处理HTTP服务器发出的响应数据,将其中的数据流(HTML数据或其它种类的数据)以适当的方式展示给使用者浏览。另一方面在Java WEB应用服务器上,一个HTTP请求可以由一个Servlet类或一个JSP网页来处理,请求数据来自于HttpServletRequest,响应数据发送至HttpServletResponse。通过用户端提交请求、服务器端处理请求、服务器端返回响应数据以及用户端处理响应数据四个步骤组成了一次HTTP请求的全部过程。数据在这四个重要环节中进行传输时,都将以指定的编码方式进行编码或解码。如果处理不当就会出现乱码问题。
用户端的处理
当用户端发出一个HTTP请求时,一个如下格式的数据将发送给服务器端:
<request-line>
<headers>
<CRLF>
[<request-body><CRLF>]
关于HTTP请求的格式,可以在HTTP协议与HTML表单(再谈GET与POST的区别)中了解更多的内容。
在此,request-line与request-body均需要进行相应的编码处理。
request-line的编码处理
request-line中的URL部分必须以application/x-www-form-urlencoded方式编码。编码时使用的字符集是当前网页在浏览器上显示时所使用的字符集。
JDK中专门有两个类处理application/x-www-form-urlencoded类型的数据,它们是URLEncoder及URLDecoder。当网页上的数据需要手动进行URLEncoding处理时,可使用URLEncoder类完成编码工作。需要手动进行URLEncoding处理的位置包括:
链接()中的href标签属性;
以POST方式提交的表单(
)中的action标签属性。
例如,网页上不应该产生这样的链接:
<!-- 不正确的写法 -->
<a href="/hello/checkUser.html?opt=中文>使用者身份验证"</a>
正确的写法是:
<!-- 使用UTF-8字符集进行URLEncoding的结果 -->
<a href="/hello/checkUser.html?opt=%E4%B8%AD%E6%96%87">使用者身份验证</a>
为此,方案之一可以在JSP网页上使用脚本化语言进行URLEncoding处理。如:
view plaincopy to clipboardprint?
<%@page import="java.net.URLEncoder"%>
<a href="/hello/checkUser.html?opt=<%=URLEncoder.encode("中文", "UTF-8")%>">使用者身份验证</a>
request-body的编码处理
request-body只有在POST提交的方式下才会产生。request-body的编码方式由表单的enctype标签属性指定,同request-line一样,编码request-body时使用的字符集也是当前网页在浏览器上显示时所使用的字符集。request-body的编码过程由客户端浏览器自动完成,不需要额外的编程处理。
服务器的处理
相对于用户端,服务器端在接收到HTTP请求时提供了两种处理请求数据的方式:自动处理与不处理。
服务器一般会自动处理application/x-www-form-urlencoded类型的数据(包括request-line及request-body中的数据),就servlet(Servlet类或JSP网页)而言,可以通过request对象的getParameter()或getParameterValues()取得这些数据。对于除此以外的其它MIME类型的数据,HTTP服务器则是将处理的过程直接交到了与HTTP请求相对应的servlet(Servlet类或JSP网页)身上。
例如用户端有以下表单被提交:
view plaincopy to clipboardprint?
<form action="checkUser.html?opt=xxx" method="POST">
<input type="text" name="username" value="yyy"/>
<input type="text" name="username" value="zzz"/>
<inupt type="submit" value="submit"/>
</form>
表单提交时经服务器端自动处理后与checkUser.html相对应的servlet(Servlet类或JSP网页)可以通过下面的方式取得数据:
String opt = request.getParameter("opt");
String[] users = request.getParameterValues("username");
String opt = request.getParameter("opt");
String[] users = request.getParameterValues("username");
默认情况下,服务器对于接收到的application/x-www-form-urlencoded类型数据进行字符集为ISO-8859-1的URLDecoding处理,经过处理之后的字符串内码为ISO-8859-1。对于没有附加任何设置的HTTP服务器而言,我们的servlet在取得数据之后必须进行相应的解码处理,生成内码为UTF-16(unicode)的字符串。
例如对于用户端请求数据中以UTF-8字符集进行URLEncoding的数据,servlet需要进行如下方式的解码:
view plaincopy to clipboardprint?
String opt = request.getParameter("opt");
if (opt!=null && !"".equals(opt)) {
opt = new String(opt.getBytes("ISO-8859-1"), "UTF-8");
}
String opt = request.getParameter("opt");
if (opt!=null && !"".equals(opt)) {
opt = new String(opt.getBytes("ISO-8859-1"), "UTF-8");
}
为了避免这种额外的编码/解码处理,也就是说让服务器了解到用户端在URLEncoding时所使用的字符集,从而直接进行相应字符集的URLDecoding处理,不同的HTTP服务器提供了不同的解决方案。
以Tomcat为例,Tomcat自动解码request-line的处理方式由Tomcat的配置文件server.xml指定。在server.xml中的Connector标签中提供了URIEncoding标签属性,只要为其指定解码用的字符集,Tomcat就会自动解码request-line中经过application/x-www-form-urlencoded编码处理的数据。例如:
<Connector connectionTimeout="40000" port="8080" protocol="HTTP/1.1"
URIEncoding="UTF-8" redirectPort="8443"/>
Tomcat自动解码request-body的处理方式是设置request的characterEncoding值。如:
request.setCharacterEncoding("UTF-8");
但是这一操作必须提前在filter中完成,在servlet中使用此方法已经不起作用了。filter的例子如下:
view plaincopy to clipboardprint?
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class CharacterEncodingFilter implements Filter {
private String encoding;
public CharacterEncodingFilter() {
encoding = null;
}
public void destroy() {
encoding = null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding(encoding);
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
encoding = filterConfig.getInitParameter("encoding");
if (encoding == null || "".equals(encoding)) {
encoding = "UTF-8";
}
}
}
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class CharacterEncodingFilter implements Filter {
private String encoding;
public CharacterEncodingFilter() {
encoding = null;
}
public void destroy() {
encoding = null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding(encoding);
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
encoding = filterConfig.getInitParameter("encoding");
if (encoding == null || "".equals(encoding)) {
encoding = "UTF-8";
}
}
}
我们可以在web.xml使用这个filter。web.xml的相应配置如下:
view plaincopy to clipboardprint?
<filter>
<filter-name>Character Encoding Filter</filter-name>
<filter-class>
CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Character Encoding Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
通过上述两种方式的预处理,在servlet中取出的数据可以不必进行ISO-8859-1解码而直接使用。
字符集的选择
在处理application/x-www-form-urlencoded类型的数据过程中,需要注意的另一个问题是字符集的选择问题。如上所述,不论是request-line还是request-body,其URLEncoding所使用的字符集都是当前网页在浏览器上显示时所使用的字符集。而这个信息又是HTTP服务器端生成HTML网页时,在HTTP响应中提供的。
当HTTP服务器接收到一个HTTP请求时,服务器总是需要向用户端发送一个HTTP响应。HTTP响应数据与HTTP请求数据格式相同,同样由以下几个部分组成:
<response-line>
<headers>
<CRLF>
[<response-body><CRLF>]
下面描述的是请求一个HTML网页数据时服务器的响应信息:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=UTF-8
Content-Length: 265
Date: Thu, 17 Dec 2009 05:20:36 GMT
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>test</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
[End]
其中headers的Content-Type指定了数据流的数据格式以及显示用的字符集。这一指标可以通过以下几种方式指定:
1. HTML网页
在HTML网页的中存在多个 标签,其中可以设置Content-Type。例如:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
2. JSP网页
JSP网页中,除了 标签之外,还需要在JSP网页头部设置如下代码:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
3. Servlet类
如果要在Servlet类中通过response向用户端传送HTML数据,需要在传送前指定Content-Type。代码如下:
response.setContentType("text/html;charset=UTF-8");
通过上述三种方式,可以确保响应数据传送到用户端浏览器时,浏览器使用正确解码方式和字符集显示其内容。
结束语
总之,Content-Type是联系用户端与服务器端的纽带,通过这一指标,双方得以对相关的数据进行正确的编码与解码。只要了解了Content-Type的作用以及使用方法,乱码问题就会迎刃而解。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
文章转载自:网络转载面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@evget.com
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢
慧都科技 版权所有 Copyright 2003-
2025 渝ICP备12000582号-13 渝公网安备
50010702500608号