JSP专题

时间:2023-03-08 17:56:46

JSP起源

·在很多动态网页中,绝大部分内容都是固定不变的,只有局部内容需要动态产生和改变。

·如果使用Servlet程序来输出只有局部内容需要动态改变的网页,其中所有的静态内容也需要程序员代码产生,整个Servlet程序的代码将非常浮肿,编写和维护都将非常困难。

·对大量静态内容的美工设计和相关HTML语句的编写,并不是程序员所要做的工作,程序员对此也不一定在行。网页美工设计和制作人员不懂Java编程,更是无法来完成这样的工作。

·为了弥补Servlet的缺陷,SUN公司在Servlet的基础上推出了JSP(Java Server Pages)技术作为解决方案。

·JSP是简化Servlet编写的一种技术,它将Java代码和HTML语句混合在同一个文件中编写,只对网页中的要动态产生的内容采用Java代码来编写,而对固定不变的静态内容采用普通静态HTML页面的方式编写。

建立对JSP的直观认识

·JSP页面是由HTML语句和嵌套在其中的Java代码组成的一个普通文本文件,JSP页面的文件扩展名必须为.jsp。

·在JSP页面中编写的Java代码需要嵌套在<%和%>中,嵌套在<%和%>之间的Java代码被称之为脚本片段(Scriptlets),没有嵌套在<%和%>之间的内容被称之为JSP的模板元素。

·JSP中的Java代码可以使用out.println语句将其他Java程序代码产生的结果字符串输出给客户端,也可以使用System.out.println语句将他们打印到命令行窗口。

·JSP文件就像普通的HTML文件一样,它们可以防止在WEB应用程序中的除了WEB-INF及其子目录外的其他任何目录中,JSP页面的访问路径与普通HTML页面的访问路径形式也完全一样。

·在JSP页面中也可以使用一种称之为JSP表达式的元素,只需将要输出的变量或表达式直接封装在<%=和%>之中,就可以向客户端输出这个变量或表达式的运算结果。在JSP表达式中嵌套的变量或表达式后面不能有分号。

JSP的运行原理
·WEB容器(Servlet引擎)接受到以.jsp为扩展名的URL的访问请求时,它将把访问请求交给JSP引擎去处理。

·每个JSP页面在第一次被访问时,JSP引擎将它翻译成一个Servlet源程序,接着再把这个Servlet源程序翻译成Servlet的class类文件,然后再由WEB容器(Servlet引擎)像调用普通Servlet程序一样的方式来装载和解释执行这个有JSP页面翻译成的Servlet程序。

·JSP规范也没有明确要求JSP中的脚本程序代码必须采用Java语言,JSP中的脚本程序代码可以采用Java语言之外的其他脚本语言来编写,但是,JSP页面最终必须转换成Java Servlet程序。

·可以在WEB应用程序正式发布之前,将其中的所有JSP页面预先编译成Servlet程序。

JSP隐式对象

public void _jspService(HttpServletRequest request,

HttpServletResponse response)

throws java.io.IOException, ServletException

{

JspFactory _jspxFactory = null;

PageContext pageContext = null;

HttpSession session = null;

ServletContext application = null;

ServletConfig config = null;

JspWriter out = null;

Object page = this;

...

...

Throwable exception =

org.apache.jasper.runtime.JspRuntimeLibrary.getThrowable(request);

if (exception != null) {

response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

}

注册与配置JSP页面的访问路径

<servlet>

<servlet-name>SimpleJspServlet</servlet-name>

<jsp-file>/jsp/simple.jsp</jsp-file>

<load-on-startup>1</load-on-startup >

</servlet>

……

<servlet-mapping>

<servlet-name>SimpleJspServlet</servlet-name>

<url-pattern>/xxx/yyy.html</url-pattern>

</servlet-mapping>

JSP与Servlet的应用比较

·JSP是一种

以产生网页显示内容为中心的 WEB开发技术,它可以直接使用模板元素来产生网页文档的内容。

·JSP网页的源文件要比Servlet源文件简单,并且JSP页面的开发过程要比Servlet的开发过程简单得多。

·JSP引擎可以对JSP页面的修改进行检测,并自动重新翻译和编译修改过的JSP文件。

·JSP技术是建立在Servlet技术基础之上的,所有的JSP页面最终都要被转换成Servlet来运行。

·在大型WEB应用程序的开发中,Servlet与JSP经常要混合使用,各司其职,Servlet通常用作控制组件,并处理一些复杂的后台业务,JSP则作为显示组件。

·一次响应过程可以划分成几个功能模块来协同完成,首先由Servlet完成流程控制和业务处理,并将结果数据存储在Request或session域中,然后将请求转发(forward)到JSP页面,再由JSP页面从Request或session域中取出结果数据并完成响应内容的输出。通过这种方式实现业务逻辑与显示内容的分离,从而将应用程序开发者和网页作者的工作分离。

JSP基本语法

JSP模板元素

·JSP页面中的静态HTML内容称之为JSP模板元素,在静态的HTML内容之中可以嵌套JSP的其他各种元素来产生动态内容和执行业务逻辑。

·JSP模板元素定义了网页的基本骨架,即定义了页面的结构和外观。

JSP表达式

·JSP表达式(expression)提供了将一个java变量或表达式的计算结果输出到客户端的简化方式,它将要输出的变量或表达式直接封装在<%=和%>之中。

举例:Current time: <%= new java.util.Date() %>

·JSP表达式中的变量或表达式的计算结果将被转换成一个字符串,然后被插入进整个JSP页面输出结果的相应位置。

·JSP表达式中的变量或表达式后面不能有分号(;),JSP表达式被翻译成Servlet程序中的一条out.print(...)语句。

JSP脚本片断

·JSP脚本片断(scriptlet)是指嵌套在<%和%>之中的一条或多条Java程序代码。

·在JSP脚本片断中,可以定义变量、执行基本的程序运算、调用其他Java类、访问数据库、访问文件系统等普通Java程序所能实现的功能。

·在JSP片断中可以直接使用JSP提供的隐式对象来完成WEB应用程序特有的功能。

·JSP脚本片断中的Java代码将被原封不动地搬移进由JSP页面所翻译成的Servlet的jspService方法中,所以,JSP脚本片断之中只能是符合Java语法要求的程序代码,除此之外的任何文本、HTML标记、其他JSP都必须在脚本片断之外编写。

·JSP脚本片断中的Java代码必须严格遵循Java语法,例如,每条命令执行语句后面必须用分号(;)结束。

·在一个JSP页面中可以有多个脚本片断(每个脚本片断代码嵌套在各自独立的一对<%和%>之间),在两个或多个脚本之间可以嵌入文本、HTML标记和其他JSP元素。

举例:

<%

int x = 3;

%>

<p>这是一个HTML段落</p>

<%

out.println(x);

%>

·多个脚本片断中的代码可以相互访问,犹如将所有的代码放在一对<%%>之中的情况。

举例:上面的JSP内容与下面的JSP内容具有同样的运行效果

<p>这是一个HTML段落</p>

<%

int x = 3;

out.println(x);

%>

·单个脚本片断中的Java语句可以是不完整的,但是,多个脚本片断组合后的结果必须是完整的Java语句,例如,涉及条件和循环处理时,多个脚本片断及其他元素组合的结果必须能形成完整的条件和循环控制语句。

·由于脚本片断中的Java代码将被原封不动地搬移进由JSP页面所翻译成的Servlet的JSPService方法中,脚本片断之外的任何文本、HTML标记以及其他JSP元素也都会被转换成响应的Java程序代码插入进JSPService方法中,且脚本片断和其他JSP元素的出入位置与JSP页面中的原始位置相对应。

·在脚本片断中可以使用条件、循环、选择等流程控制语句来创建其周围的其他元素的执行逻辑,因此,在编写JSP页面时应考虑各个元素之间的先后顺序和相互关系,特别是将循环、条件判断等语句分布在若干个脚本片断中编写时对其邻近的其他JSP元素产生的影响。

JSP专题

JSP声明

·JSP声明将Java代码封装在<%!和%>之中,它里面的代码将被插入进Servlet的JSPService方法的外面,所以,JSP声明可用于定义JSP页面转换成的Servlet程序的静态代码块、成员变量和方法。

·多个静态代码块、变量和函数可以定义在一个JSP声明中,也可以分别单独定义在多个JSP声明中。

·JSP隐式对象的作用范围仅限于Servlet的JSPService方法中,所以在JSP声明中不能使用这些隐式对象。

·JSP脚本片断中的Java代码必须严格遵循Java语法,例如,每条命令执行语句后面必须用分号(;)结束。

·在一个JSP页面中可以有多个脚本片断(每个脚本片断代码嵌套在各自独立的一对<%和%>之间),在两个或多个脚本片断之间可以嵌入文本、HTML标记和其他JSP元素。

JSP声明--实例

<%!

static { System.out.println("loading Servlet!"); }

private int globalVar = 0;

public void jspInit()

{

System.out.println("initializing jsp!");

}

%>

<%!

public void jspDestroy()

{

System.out.println("destroying jsp!");

}

%>

<%

int localVar = 0;

%>

globalVar:<%= ++globalVar %><br>

localVar:<%= ++localVar %>

JSP注释

·JSP注释的格式

<%-- 注释信息 --%>

·JSP引擎在将JSP页面翻译成Servlet程序时,忽略JSP页面中被注释的内容。

如何查找JSP页面中的错误

·JSP页面中的JSP语法格式有问题,导致其不能被翻译成Servlet源文件,JSP引擎将提示这类错误发生在JSP页面中的位置(行和列)以及相关信息。

·JSP页面中的JSP语法格式没有问题,但被翻译成的Servlet源文件中出现了Java语法问题,导致JSP页面翻译成的Servlet源文件不能通过编译,JSP引擎也将提示这类错误发生在JSP页面中的位置(行和列)以及相关信息。

·JSP页面翻译成的Servlet程序在运行时出现异常,这与普通java程序的运行时错误完全一样,java虚拟机将提示错误发生在Servlet源文件中的位置(行和列)以及相关信息。

out隐式对象

·在JSP页面中应使用out隐式对象来向客户端发送文本形式的实体内容。

·out对象时通过调用pageContext对象的getOut方法返回的,起作用和用法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似。

·JSP页面中的out隐式对象的类型为JSPWriter,JSPWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,甚至关闭它的缓存。

·JSP页面中的out隐式对象相当于插入到ServletResponse.getWriter方法返回的PrintWriter对象前面的缓存包装类对象。

·只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓存区内容真正写到Servlet引擎提供的缓存区中:

1.设置page指令的buffer属性关闭了out对象的缓存功能
2.写入到out对象中的内容充满了out对象的缓冲区
3.整个JSP页面结束
out隐式对象的工作原理图
JSP专题
pageContext对象简介
·pageContext对象封装了当前JSP页面的运行信息,它提供了返回JSP页面的其他隐式对象的方法。
·pageContext类中定义了一个setAttribute方法来讲对象存储进pageContext对象内部的一个HashMap对象中,同时也定义了一个getAttribute方法来检索存储在该HashMap对象中的对象。
·PageContext类除了可以存储和检索自身中的属性对象外,还定义了可以存储和检索其他域范围内的属性对象的方法。
获得其他隐式对象
•getException方法返回exception隐式对象
•getPage方法返回page隐式对象
•getRequest方法返回request隐式对象
•getResponse方法返回response隐式对象
•getServletConfig方法返回config隐式对象
•getServletContext方法返回application隐式对象
•getSession方法返回session隐式对象
•getOut方法返回out隐式对象 
引入和跳转到其他资源
·PageContext类中定义了一个forward方法和两个include方法来分别简化和替代RequestDispatcher.forward方法和RequestDispatcher.include方法的调用:

public void forward(java.lang.String relativeUrlPath)

throws javax.servlet.ServletException,java.io.IOException

public void include(java.lang.String relativeUrlPath)

throws javax.servlet.ServletException,java.io.IOException

public void include(java.lang.String relativeUrlPath,boolean flush)

throws javax.servlet.ServletException,java.io.IOException

· 传递给这些方法的资源路径都只能是相对路径,如果路径以“/”开头,表示相当于当前WEB应用程序的根目录,否则,表示相对于当前JSP所映射到的访问路径。

访问各个域范围中的属性

·在application、session、request、PageContext对象中都可以调用setAttribute方法和getAttribute方法来设置和检索各个域范围内的属性。

·存储在application对象中的属性可以被同一个WEB应用程序中的所有Servlet和JSP页面访问。

·存储在session对象中的属性可以被属于同一个会话的所有Servlet和JSP页面访问。

·存储在request对象中的属性可以被属于同一个请求的所有Servlet和JSP页面访问,例如使用PageContext.forward和PageContext.include方法连接起来的多个Servlet和JSP页面。

·存储在PageContext对象中的属性仅可以被当前JSP页面的当前响应过程中调用的各个组件访问,例如,正在响应当前请求的JSP页面和它调用的各个自定义标签类。

·PageContext类中还提供了对各个域范围的属性进行统一管理的方法,以简化对各个域范围内的属性的访问。

•setAttribute方法
public void setAttribute(java.lang.String name,java.lang.Object value)
public void setAttribute(java.lang.String name,  java.lang.Object value,int scope)
•常量
PageContext.APPLICATION_SCOPE
PageContext.SESSION_SCOPE
PageContext.REQUEST_SCOPE
PageContext.PAGE_SCOPE
•getAttribute方法
public java.lang.Object getAttribute(java.lang.String name)
public java.lang.Object getAttribute(java.lang.String name,int scope)
•removeAttribute方法
public void removeAttribute(java.lang.String name)
public void removeAttribute(java.lang.String name,int scope)
•getAttributeNamesInScope方法
•findAttribute方法    (*)

请求重定向与请求转发

RequestDispatcher接口

·RequestDispatcher实例对象时由Servlet引擎创建的,它用于包装一个要被其他资源调用的资源(例如,Servlet、HTML文件、JSP文件等),并可以通过其中的方法将客户端的请求转发给所包装的资源。

·RequestDispatcher接口中定义了两个方法:forward方法和include方法。

·forward和include方法接受的两个参数必须是传递给当前Servlet的service方法的那两个ServletRequest和ServletResponse对象,或者是对它们惊醒了包装的ServletRequestWrapper或ServletResponseWrapper对象。

·获取RequestDispatcher对象的方法:

ServletContext.getRequestDispatcher (参数只能是以“/”开头的路径)
ServletContext.getNamedDispatcher
ServletRequest.getRequestDispatcher (参数可以是不以“/”开头的路径)
用sendRedirect方法实现请求重定向
  

  sendRedirect 方法不仅可以重定向到当前应用程序中的其他资源,它还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。

如果传递给sendRedirect 方法的相对URL以“/”开头,则是相对于整个WEB站点的根目录,而不是相对于当前WEB应用程序的根目录。

请求重定向与请求转发的比较

•RequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的组件;而HttpServletResponse.sendRedirect 方法还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。
•如果传递给HttpServletResponse.sendRedirect 方法的相对URL以“/”开头,它是相对于整个WEB站点的根目录;如果创建RequestDispatcher对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。
•调用HttpServletResponse.sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;调用RequestDispatcher.forward 方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。
•HttpServletResponse.sendRedirect方法对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求;RequestDispatcher.forward方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。
•RequestDispatcher.forward方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;而HttpServletResponse.sendRedirect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。

JSP指令简介

·JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分。

·JSP指令的基本语法格式:

<%@ 指令属性名="值" %>

举例:<%@ page contentType="text/html;charset=gb2312"%>

注意:属性名部分是大小写敏感的

•在目前的JSP 2.0中,定义了page、include和taglib这三种指令,每种指令中又都定义了一些各自的属性。
•如果要在一个JSP页面中设置同一条指令的多个属性,可以使用多条指令语句单独设置每个属性,也可以使用同一条指令语句设置该指令的多个属性。

第一种方式:

<%@ page contentType="text/html;charset=gb2312"%>

<%@ page import="java.util.Date"%>

第二种方式:

<%@ page contentType="text/html;charset=gb2312" import="java.util.Date"%>

Page指令

•page指令用于定义JSP页面的各种属性,无论page指令出现在JSP页面中的什么地方,它作用的都是整个JSP页面,为了保持程序的可读性和遵循良好的编程习惯,page指令最好是放在整个JSP页面的起始位置。
JSP专题
include指令
•include指令用于通知JSP引擎在翻译当前JSP页面时将其他文件中的内容合并进当前JSP页面转换成的Servlet源文件中,这种在源文件级别进行引入的方式称之为静态引入,当前JSP页面与静态引入的页面紧密结合为一个Servlet。
•语法:

<%@ include file="relativeURL"%>

其中的file属性用于指定被引入文件的相对路径。

•细节:
被引入的文件必须遵循JSP语法,其中的内容可以包含静态HTML、JSP脚本元素、JSP指令和JSP行为元素等普通JSP页面所具有的一切内容。
被引入的文件可以使用任意的扩展名,即使其扩展名是html,JSP引擎也会按照处理jsp页面的方式处理它里面的内容,为了见明知意,JSP规范建议使用.jspf(JSP fragments)作为静态引入文件的扩展名。
在将JSP文件翻译成Servlet源文件时,JSP引擎将合并被引入的文件与当前JSP页面中的指令元素(设置pageEncoding属性的page指令除外),所以,除了import和pageEncoding属性之外,page指令的其他属性不能在这两个页面中有不同的设置值。 
除了指令元素之外,被引入的文件中的其他元素都被转换成相应的Java源代码,然后插入进当前JSP页面所翻译成的Servlet源文件中,插入位置与include指令在当前JSP页面中的位置保持一致。
引入文件与被引入文件是在被JSP引擎翻译成Servlet的过程中进行合并,而不是先合并源文件后再对合并的结果进行翻译。当前JSP页面的源文件与被引入文件的源文件可以采用不同的字符集编码,即使在一个页面中使用page指令的pageEncoding或contentType属性指定了其源文件的字符集编码,在另外一个页面中还需要用page指令的pageEncoding或contentType属性指定其源文件所使用的字符集。
Tomcat 5.x在访问JSP页面时,可以检测它所引入的其他文件是否发生了修改,如果发生了修改,则重新编译当前JSP页面
file属性的设置值必须使用相对路径,如果以“/”开头,表示相对于当前WEB应用程序的根目录(注意不是站点根目录),否则,表示相对于当前文件。
•假设myweb应用程序的根目录下有一个a.jsp文件,其一般的访问路径形式为:

http://localhost:8080/myweb/a.jsp

在a.jsp页面中使用了如下语句引入b.jspf文件:

<%@ include file=“b.jspf”%>

请问:这时候JSP引擎调用的b.jspf文件的完整URL路径为什么?

如果将a.jsp页面映射为如下地址:

http://localhost:8080/myweb/dir1/a.html

请问:这时候JSP引擎调用的b.jspf文件的完整URL路径为:

http://localhost:8080/myweb/b.jspf

http://localhost:8080/myweb/dir1/b.jspf

 JSP标签--概念
·JSP还提供了一种称之为Action的元素,在JSP页面中使用Action元素可以完成各种通用的JSP页面功能,也可以实现一些处理浮渣业务逻辑的专用功能。
·Action元素采用XML元素的语法格式,即每个Action元素在JSP页面中都以XML标签的形式出现。
·JSP规范中定义了一些标准的Action元素,这些元素的标签名都以jsp作为前缀,并且全部采用小写,例如,<jsp:include>、<jsp:forward>等等。
<jsp:include>标签
•<jsp:include>标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入。
•语法:

<jsp:include page="relativeURL | <%=expression%>" flush="true|false" />

page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得。

flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端。 
<jsp:include>标签与include指令的比较
•<jsp:include>标签是在当前JSP页面的执行期间插入被引入资源的输出内容,当前JSP页面与被动态引入的资源是两个彼此独立的执行实体,被动态引入的资源必须是一个能独立被WEB容器调用和执行的资源。include指令只能引入遵循JSP格式的文件,被引入文件与当前JSP文件共同合被翻译成一个Servlet的源文件。
•使用<jsp:include>标签和include指令都可以把一个页面的内容分成多个组件来生成,开发者不必再把页眉和页脚部分的相同HTML代码复制到每个JSP文件中,从而可以更轻松地完成维护工作,但是都应注意最终的输出结果内容应遵循HTML语法结构,例如,如果当前页面产生了<html>、</html>、<body>、</body>等标记,那么在被引入文件中就不能再输出<html>、</html>、<body>、</body>等标记。
•<jsp:include>标签对JSP引擎翻译JSP页面的过程不起作用,它是在JSP页面的执行期间才被调用,因此不会影响两个页面的编译。由于include指令是在JSP引擎翻译JSP页面的过程中被解释处理的,所以它对JSP引擎翻译JSP页面的过程起作用,如果多个JSP页面中都要用到一些相同的声明,那么就可以把这些声明语句放在一个单独的文件中编写,然后在每个JSP页面中使用include指令将那个文件包含进来。
 •<jsp:include>标签使用page属性指定被引入资源的相对路径,而include指令使用file属性指定被引入资源的相对路径。
•假设myweb应用程序的根目录下有一个a.jsp文件,其一般的访问路径形式为:

http://localhost:8080/myweb/a.jsp

在a.jsp页面中使用了如下语句引入b.jsp文件:

<jsp:include page=“b.jsp" />

请问:这时候JSP引擎调用的b.jsp文件的完整URL路径为什么?

如果将a.jsp页面映射为如下地址:

http://localhost:8080/myweb/dir1/a.html

请问:这时候JSP引擎调用的b.jsp文件的完整URL路径为:

http://localhost:8080/myweb/b.jspf

http://localhost:8080/myweb/dir1/b.jspf

<jsp:forward>标签

•<jsp:forward>标签用于把请求转发给另外一个资源。
•语法:

<jsp:forward page="relativeURL | <%=expression%>" />

page属性用于指定请求转发到的资源的相对路径,它也可以通过执行一个表达式来获得。

RequestDispatcher.forward方法、PageContext.forward方法、<jsp:forward>标

签的区别

调用RequestDispatcher.forward方法的JSP脚本代码的前后不能有JSP模版内容。

调用PageContext.forward方法的JSP脚本代码的后面不能有JSP模版内容。

<Jsp:forward>标签的前后都能有JSP模版内容。

<jsp:param>标签
•当使用<jsp:include>和<jsp:forward>标签引入或将请求转发给的资源是一个能动态执行的程序时,例如Servlet和JSP页面,那么,还可以使用<jsp:param>标签向这个程序传递参数信息。
•语法1:

<jsp:include page="relativeURL | <%=expression%>">

<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />

</jsp:include>

•语法2:

<jsp:forward page="relativeURL | <%=expression%>">

<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />

</jsp:include>

•<jsp:param>标签的name属性用于指定参数名,value属性用于指定参数值。在<jsp:include>和<jsp:forward>标签中可以使用多个<jsp:param>标签来传递多个参数。
 
JSP中文乱码
•JSP程序存在有与Servlet程序完全相同的中文乱码问题
输出响应正文时出现的中文乱码问题
读取浏览器传递的参数信息时出现的中文乱码问题
•JSP引擎将JSP页面翻译成Servlet源文件时也可能导致中文乱码问题
JSP引擎将JSP源文件翻译成的Servlet源文件默认采用UTF-8编码,而JSP开发人员可以采用各种字符集编码来编写JSP源文件,因此,JSP引擎将JSP源文件翻译成Servlet源文件时,需要进行字符编码转换。
如果JSP文件中没有说明它采用的字符集编码,JSP引擎将把它当作默认的ISO8859-1字符集编码处理。
•如何解决JSP引擎翻译JSP页面时的中文乱码问题
通过page指令的contentType属性说明JSP源文件的字符集编码
page指令的pageEncoding属性说明JSP源文件的字符集编码
在部署描述符中说明一组JSP源文件的字符集编码

<jsp-config>

<jsp-property-group>

<url-pattern>/jsp/*</url-pattern>

<page-encoding>GB2312</page-encoding>

</jsp-property-group>

</jsp-config>

可能原因:

•Servlet程序从请求消息中获取请求参数和从数据库、文件、键盘等外设中读取一个字符串时都要将底层的字节流转换成字符串,但转换过程中指定的字符集编码与外设所输入内容的字符集编码不一致。如果某个第三方API将底层设备中的字节流数据总是按ISO8859-1转换成字符串返回,那么,对于底层设备中的GB2312编码的中文字符来说,返回的将不是其正确的Unicode码,这时候可以通过如下语句来解决:

strNew = new String(strOld.getBytes("ISO8859-1"),"GB2312");

•Servlet程序将字符串输出到浏览器、屏幕、文件和数据库时都要将字符串转换成底层的字节流,但转换过程中指定的字符集编码与外设所能显示的字符集编码不一致。
•JSP引擎将JSP源文件翻译成Servlet源文件时,其选择的字符集编码与JSP源文件实际使用的字符集编码不一致。
•JSP引擎编译由JSP源文件翻译成的Servlet 源文件时,其选择的字符集编码与Servlet 源文件的字符集编码不一致。

诊断方法:

•使用System.out.println语句在命令行窗口中打印出现乱码的字符串
•跟踪某个中文字符在JSP页面运行过程中的每个阶段的编码值