JSP(1)—基本知识
起源
在很多动态网页中绝大多数网页都是固定不变的只有局部内容需要动态产生和改变,如果使用Servlet程序来输出只有局部内容需要动态改变的网页,其中所有的的静态内容,也需要程序员用java代码产生,整个Servlet程序代码会非常臃肿,编写和维护都非常困难。
对与大量静态内容的美工设计和相关HTML语句的编写,并不是程序员所要做的事,程序员对此也不一定在行,网页美工设计和制作人员不懂java编程更是无法完成这样的工作,为了弥补Servlet缺陷,SUN在servlet的基础上推出了JSP(java server page)技术作为解决方案。
JSP是简化了Servlet编写的一种技术,它将Servlet和HTML语句混合在一个文件中编写,只对网页中动态产生的内容采用java编写,而相对固定的静态页面采用普通的静态HTML页面的方式编写。在JSP中编写java代码需要嵌套在<% %>中,嵌套在<%%>中的java代码被称为脚本片段,没有嵌套在<%%>中的代码被称为模板元素,JSP文件就像普通的HTML文件一样,他们可以放置WEB应用程序的除WEB-INF目录之外的任何目录中,JSP页面的访问路径和HTML页面的访问路径一样。运行原理
WEB容器(Servlet引擎),接收到以.jsp为扩展名的URL访问请求时,它将该请求转发给JSP引擎去处理,每个JSP页面第一次被访问时JSP引擎将它翻译成Servlet源程序,接着将这个Servlet源程序编译成Servlet的class类文件,然后在由WEB容器(servlet引擎)像调用普通的Servlet程序一样的方式来装载和解释执行这个由JSP页面翻译成Servlet程序,JSP规范没有明指出JSP中的脚本语言必须是java语言,也可以是其他语言,但是JSP页面最后必须转换成java Servlet程序。- 隐含对象(自己没有声明就可使用的变量),共九个
request、response、pageContext、session、application、config、out、page、exception
①request(常用):HttpServletRequest的一个对象
②response:HttpServletResponse的一个对象
③pageContext(常用):页面的上下文,是PageContext的一个对象,可以从该对象中获取其他八个隐含对象,也可以从中获取当前页面的其他信息。(学习自定义标签时用到它)
④session(常用):代表浏览器和服务器一次对话,是HttpSession的一个对象
⑤applicationn(常用):代表当前web应用,是ServletContext的对象。获取servlet初始化对象
⑥config:当前JSP对应的Servlet的ServletConfig对象(在开发过程中很少用),需要访问当前JSP页面配置的初始化参数,
需要通过映射的地址才可以:http://localhost:8080/Demo5/hellojsp?name=test
<!-- 配置一个Servlet -->
<servlet>
<servlet-name>hellojsp</servlet-name>
<jsp-file>/hello.jsp</jsp-file>
<!-- 配置初始化参数 -->
<init-param>
<param-name>test</param-name>
<param-value>testValue</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>hellojsp</servlet-name>
<url-pattern>/hellojsp</url-pattern>
</servlet-mapping>
⑦out(常用):JspWriter对象,调用out.println()可以直接把字符串打印到浏览器上
⑧page:指向JSP对应的Servlet对象的引用,但为Object类型,只能调用Object的方法
⑨exception:只在声明了isErrorPage=”true”时,才可以使用
- 这些对象对属性的作用域范围
pageContext、request、session、application(作用域范围从小到大)
out、response、config、page
exception
- 基本语法
①模板元素:JSP中的静态的HTMl内容,在静态的HTML内容之中可以嵌套JSP的其他元素来产生动态内容和执行业务逻辑,jsp模板元素定义了网页的基本框架和外观。
②表达式:提供了将一个java变量或表达式的计算结果输出到客户端的简化方式,它将要输出的变量或表达式封装在<%=和 %>之中。jsp表达式的变量或表达式的计算结果将被转换成一个字符串,然后被插入进整个jsp页面输出结果的相应位置,jsp变量或表达式的后面不能有分号jsp表达式被翻译成Serrvlet程序中的out.print(…)语句。
例如:
<%
Date date = new Date();
out.println(date);
%>
<%=date%>
③脚本片段:是指嵌套在<% %>之中的java程序代码。多个脚本片段可以互相访问
例如:
<%
String ageStr = request.getParameter("age");
Integer age = Integer.parseInt(ageStr);
if(age >= 18){
%>
成年人...
<%
}else{
%>
未成年人...
<%
}
%>
④声明(在jsp页面中几乎不使用):jsp将java代码封装在<%! %>之中它里面的代码将被插入到Servlet的jspSevlet方法的外面,
所以jsp声明可用于定义jsp页面转换成的Servlet程序的静态代码块、成员变量和方法。jsp隐式对象的作用范围仅限于Servlet的jspServlet方法,所以在jsp声明中不能使用这些隐式对象。
例如:
<%!
void test(){};
%>
⑤EL表达式
⑥注释:(在浏览器上查看源代码时可以看到)、<%– jsp注释 –%>(在浏览器上查看源代码时看不到),或者说jsp注释阻止java代码执行。
⑦特殊字符序列的转义处理
⑧如何查找JSP页面的错误
- 对象的属性
①方法:
getAttribute(String name):获取指定的属性
Enumeration getAttributeNames():获取所有的属性名组成的Enumeration对象
removeAttribute(String name):移除指定的属性
void setAttribute(String name, Object o):设置属性
②对象:
pageContext、request、session、application这个四个对象含有这个四个方法,这四个对象也叫域对象
③范围:
pageContext:属性的作用范围仅限于当前jsp页面
request:属性的作用范围仅限于同一个请求,(在请求转发的情况下可以获取属性值)
session:属性的作用范围仅限于一次会话,(浏览器打开到关闭称为一次会话,在此期间不会失效)(只要不重启浏览器就可获取到)
application:属性的作用范围仅限于当前web应用,是范围最大的属性作用范围,只要在一处设置属性,在其他各处的jsp或
Servlet中都可以获取到。(只要不重启tomcat就可获取到) - JSP指令
①简介
jsp指令是为jsp引擎而设计的,它们并不直接产生任何可见的输出,而是告诉引擎如何处理jsp页面中的其余部分。
②语法格式
<%@ 指令 属性名=”值” %>,注意属性名部分大小写敏感
例如:<%@ page contentType="text/html";charset="gbk2312"%>
③种类
目前jsp2.0中,定义了page、include、taglib这三种指令
④使用方式
如果在一个jsp页面中定义一个指令的多个属性可以使用多条指令语句单独设置每个属性,也可以使用同一条指令语句设置该指令的多个属性
例如:
<%@ page contentType="text/html;<%@ page import="java.util.Date"%>
或者
<%@ page contentType="text/html";charset=gb2312%;import="java.util.Date">
⑤page指令
用于定义jsp页面的各种属性,无论page指令出现在什么地方,它的作用也是整个页面,为了程序的可读性和遵循良好的编程习惯,page指令一般放在jsp页面的起始位置。
JSP2.0中定义的page指令的完整语法
<%@ page[language=”java”]指定用什么语言来编译,但是目前只支持java
[extends=”package.class”]指定jsp网页产生的Servlet是继承哪个类
[import=”“]决定jsp页面使用那些javaAPI
*[session=”true/false”]决定页面是否使用session对象,默认true
*[contentType=”test/html”;charset=”gb2312”]表示指定当前页面的响应类型
[isThreadSafe=”true/false”]是否支持多线程,默认true
[buffer=”none/size in kb”]决定输出流是否有缓冲区,默认有8kb
[autoFlush=”true/false”]决定输出流的缓冲区慢了之后是否需要自动清除,缓冲区满了之后会产生异常,默认true
*[pageEncoding=”ISO-8859-1”]编码方式,通常情况下与contentType中charset的值一致
*[isELLgnored=”true/false”]表示在此jsp页面是否忽略EL表达式,true为忽略,false为支持,默认false
*[errorPage=”url”]如果页面发生异常,网页默认指向一个url
*[isErrorPage=”true/false”]表示页面是否是错误处理页面,默认false
最后这个两个属性一般是配合使用,遇到异常时,errorPage指定跳到有isErrorPage声明的属性的网页中,对于Tomcat服务器而言,WEB-INF下的文件不能直接访问,但可以通过请求转发,而errorPage调到的错误页面就是通过请求转发,所以错误页面可以放在WEB-INF下,而且可以使用隐含的内置对象exception对象获取异常信息。
在web.xml中配置相关页面:
<error-page>
<!-- 指出出错的代码:404,没有指定的资源,500内部错误 -->
<error-code>404</error-code>
<!-- 指定响应页面的路径 -->
<location>/WEB-INF/error.jsp</location>
</error-page>
<error-page>
<!-- 指定异常类型 -->
<exception-type>java.long.ArithmeticException</exception-type>
<!-- 指定响应页面的路径 -->
<location>/WEB-INF/error.jsp</location>
</error-page>
*表示常用的属性
%>
⑥include指令
include指令用于通知jsp引擎在翻译当前jsp页面时将其他文件中的内容合并进当前jsp页面转换成的Servlet源文件中这种源文件级别进行引入的方式称之为静态引入,当前jsp页面与静态引入的页面紧密结合为一个Servlet
语法<%@ include file=”文件名” %>,其中file的属性值用于指定被引入文件的相对路径。
被引入的文件必须遵循jsp语法,其中的内容可以包含HTML、JSP脚本元素、jsp指令、jsp行为元素,等普通jsp页面
所具有的一切内容,在将jsp文件翻译成Servlet 源文件时,jsp引擎将合并被引入的文件与当前jsp页面中的指令元素除了(import和pageEncoding属性之外,page指令的其他属性不能在这两个页面中有不同的设置)
除了指令元素之外,被引入的其他元素都被转换相应的java源代码,然后插入到当前jsp页面翻译成的Servlet源文件中插入位置与include指令在jsp页面中的位置一致。
文件和被引入的文件是在被jsp引擎方翻译成Servlet的过程中进行合并的而不是先合并源文件再对合并的结果进行翻译
file属性的设置值必须使用相对路径,如果以斜杠开头表示相当于当前web应用程序的跟目录(不是站点目录),否则表示相对于当前文件。
在被引入的文件中可以使用引入jsp文件的页面中声明的变量,因为是两个jsp文件合并时产生一个.java文件可能报错但是可以正常显示
jsp标签
jsp提供了一种称之为Action的元素,在jsp页面中使用Action元素可以完成各种通用的jsp页面功能,也可以实现一些复杂的逻辑业务
的专用功能。Action元素采用xml元素的语法出现,即每个Action元素在jsp页面中都以xml标签的形式出现。
①<jsp:include>
:把另外一个资源的输出内容插进当前jsp页面的输出内容之中,这种在jsp页面执行时的引入称之为动态引入
语法:<jsp:include page="relativeURL|<%=exception%>" flush="true/false"/>
其中page属性用于指定被引入资源的相对路径,他也可以通过执行一个表达式来获得,flush属性指定在插入其他资源的输出内容
时,是否先将当前jsp页面的以输出的内容刷新到客户端。
在被引入的文件中不可以使用引入jsp文件的页面中声明的变量,因为是两个jsp文件合并时产生两个.java文件②
<jsp:forward>
:标签用于把请求转发给另外一个资源,其作用跟请求转发一样
语法:<jsp:forward page="relativeURL|<%=exception%>"/>
其中page属性用于指定被引入资源的相对路径,他也可以通过执行一个表达式来获得.
③<jsp:param value="1234" name="username"/>
是以上两个标签的子标签,可以用来传递参数jsp乱码
①显示中文乱码
只要保证charset和pageEncoding的值一致,还需浏览器显示的字符编码也和请求的页面编码一致
<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
②获取中文参数值乱码,默认在传输的过程中使用ISO-8859-1编码方式在post请求之前加上,请求之前调用否则无效
<%
request.setCharacterEncoding("UTF-8");
%>
对于get请求:
方法一:
<%
String val = request.getParameter("username");
//使用getBytes方法的ISO-8859-1的编码方式解码,再使用UTF-8的方式
String username = new String(val.getBytes("iso-8859-1"), "UTF-8");
out.println("username");
%>
方法二:
但是这样太麻烦了也可以这样设置:
//apache tomcat中conf下Servlet.xml中配置
useBodyEncodingForURI="true"tomcat中Servlet.xml文件中
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1"
redirectPort="8443" useBodyEncodingForURI="true"/>
//eclipse中Servlet项目中的servlet.xml文件:
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1"
redirectPort="8443" useBodyEncodingForURI="true"/>
注意:
useBodyEncodingForURI=”true”表示将使用请求体的方式,即request.setCharacterEncoding(“UTF-8”);起作用,因为设置的编码方式为UTF-8,所以在使用方法二的情况下方法一会出现乱码,要想方法一和方法二一起使用需要修改getBytes()的参数值为UTF-8