Servlet/JSP-04 JSP基础
一. JSP概述
Servlet 是 Java 程序,可以在 Java 程序内部返回一段 HTML 代码(字符串形式)到浏览器,供浏览器解释展示。
JSP 是一种脚本语言,在 HTML 内部通过嵌入 Java 代码处理业务逻辑。JSP 是一种简化 Servlet 编写的技术,其将 Java 代码和 HTML 代码混合在一个文件中编写,对页面中需要动态产生的内容采用 Java 编写,静态内容则采用普通 HTML 页面的方式编写。
1.示例:JSP 的“hello world”
文件放置位置:除 WEB-INF 及其子目录外的任意位置(直接使用URL无法访问应用内部资源)。
访问方式(同 HTML):假设文件位于WebContent/jsp/hello.jsp, 则 .../appName/jsp/hello.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!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>Insert title here</title> </head> <body> <% String s = "Hello world(JSP)"; System.out.println(s); // 后台显示 %> <%=s%> </body> </html>
2.JSP 运行原理
WEB 容器接收到以.jsp为扩展名的 URL 的访问请求时,它将把该请求交给 JSP 引擎处理。每个 JSP 页面在第一次被访问时,JSP 引擎将它翻译成一个Servlet 程序,接着再把这个 Servlet 程序编译成相应的 class 文件,然后再有 WEB 容器像调用普通 Servlet 一样加载和执行这个由 JSP 页面翻译成的 Servlet 程序。
二. 9个页面对象
在JSP页面中,可以在<% %>内部嵌入 Java 代码,且可以使用 JSP 中得9个隐含对象(不需要我们声明就可以使用的对象),* 表示常用。
1. request(*):相当于 HttpServletRequest 的一个对象
2. response:相当于 HttpServletResponse 的一个对象( JSP页面中几乎不会调用)
3. pageContext(*):页面的上下文,是 PageContext 的一个对象,可以从此对象获取其它八个隐含对象,
也可以获取到当前页面的其它信息。(自定义标签中会使用)
4. session(*):代表浏览器和服务器的一次会话,是 HttpSession 的一个对象
5. application(*):代表当前 WEB 应用,是 ServletContext 的一个对象
6. config:是当前 JSP 对应的 Servlet 的 ServletConfig 对象(几乎不使用),若需要访问JSP的初始化参数,需要映射JSP才可以
<servlet> <servlet-name>hellojsp</servlet-name> <jsp-file>/jsp/hello.jsp</jsp-file> <init-param> <param-name>name</param-name> <param-value>tom</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>hellojsp</servlet-name> <url-pattern>/hellojsp</url-pattern> </servlet-mapping>
7. out(*):JspWriter对象,可以通过out.println(String s)把字符串直接打印到浏览器页面上
8. page:指向当前JSP对应的Servlet对象的引用,为Object类型(不会使用)
9. exception:异常信息,在声明了page 指令的isErrorPage="true"属性才可以使用
<%@ page isErrorPage="true" %>
注:属性的作用域范围 pageContext < request < session < application
三. JSP 语法
1. JSP模板元素:JSP 页面中得静态 HTML 内容
2. JSP 表达式:一种将Java变量或表达式结果输出到客户端的简化方式,它将要输出的内容直接封装在 <%= 和 %> 之间
3. 脚本片段:嵌入在JSP页面中得 Java 代码,写在 <% 和 %> 之间。
多个脚本片段的代码可以相互访问。
代码示例:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!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>Insert title here</title> </head> <body> <% String str = "Hello world(JSP)"; %> <%= str %> <% String ageStr = request.getParameter("age"); Integer age = 10; if ( ageStr != null && !"".equals(ageStr)) { age = Integer.valueOf(ageStr); } if (age >= 18) { %> 成人。。。 <% } else { %> 未成人。。。 <% } %> </body> </html>
4. JSP声明:将Java代码封装在<%! 和 %>之间,用于方法的声明(几乎不会使用)
5. JSP注释:格式为<%-- 被注释内容 --%>
与HTML 注释(<!-- 被注释内容 -->)的不同是:JSP可以阻止Java代码的执行。
四. 域对象的属性操作
1. 和属性相关的方法
Object getAttribute(String name) 获取指定的属性
Enumeration getAttributeNames() 获取所有属性名字组成的Enumeration对象
removeAttribute(String name) 移除指定的属性
void setAttribute(String name, Object value) 设置属性
2. 拥有上述方法的对象(域对象)
pageContext, request, session, application
3. 域对象的属性作用范围
Servlet中对应的获取属性方式
pageContext :属性仅限于当前页面有效 无此对于对象
request : 属性仅限于同一个请求有效 request.getAttribute(name)
session : 属性仅限于一次会话有效 request.getSession().getAttribute(name)
(浏览器打开直到关闭称之为一次会话) (request为HttpServletRequest对象)
application :属性在当前应用运行期间有效 getServletContext.getAttribute(name)
五. 转发和重定向
本质区别:请求的转发只发出一次请求,而重定向则发出了两次请求
具体区别:
1. 转发:地址栏是初次发出的请求地址;重定向:地址栏为最后响应的那个地址
2. 转发:最终的 Servlet 中和中转的 Servlet 中 request 对象是同一个
重定向:最终的 Servlet 中和中转得 Servlet 中 request 对象不是同一个
3. 转发:只能转发给当前 WEB 应用的资源
重定向:可以重定向到任何资源
4. 转发:"/" 代表的是当前 WEB 应用的根目录
重定向:"/" 代表的是当前 WEB 站点的根目录
示例:假设访问应用的 a.jsp 页面,URL 为 http://localhost:8080/web1/a.jsp
① 转发时 request.getRequestDispatcher("/b.jsp").forward(request, response),
则访问的是 http://localhost:8080/web1/b.jsp
② 重定向时 response.sendRedirect("/c.jsp"),则访问的是 http://localhost:8080/c.jsp
六. JSP 指令
JSP 指令并不产生任何可见输出,而只是告诉 JSP 引擎如何处理页面中得其余部分。
基本语法格式:<%@ 指令 属性名="属性值" %>
在 JSP2.0 规范中定义了 page, include, taglib 三种指令,每种指令各自有相应的属性
1.设置一个指令的多个属性,可以用多个指令,也可以使用一条指令
<!-- 一条指令 --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!-- 多条指令 --> <%@ page language="java" contentType="text/html; charset=UTF-8" %> <%@ page import="java.util.Date" %>
2. page指令
① page 指令用于定义 JSP 页面的各种属性,无论其出现在 JSP 页面的什么位置,它作用的都是整个 JSP 页面,通常我们放在整个 JSP 页面的起始位置。
② page 命令的常用属性:
language:指明页面中识别的编程语言,只支持 Java
import:当前页面对应的 Servlet 导入的 Java 类
pageEncoding:指定当前 JSP 页面的字符编码,通常与下方的 charset 一致
contentType:指定当前 JSP 页面的响应类型,例如 "text/html; charset=UTF-8", charset指定返回页面的字符编码;
实际编译成 Servlet 后,调用的是response.setContentType("text/html; charset=UTF-8");
session:true/false 当前页面是否允许使用 session
isELIgnored:指定当前 JSP 页面是否忽略 EL 表达式,通常为 false
errorPage:指明当前页面出错时,展示的页面。JSP引擎通过转发的方式请求到错误页面。
<%@ page errorPage="/error.jsp" %> "/"表示的是当前 WEB 应用的根目录
isErrorPage:显示错误信息的页面,必须设置此属性为 true,才可以在页面中使用 exception 隐含对象。一般不建议能够直接访问此页面
③ 如何使客户无法直接访问一个页面?
对应 Tomcat 服务器而言,WEB-INF 下的文件是无法通过浏览器的 URL 访问的,但是可以通过转发的方式访问。
假设 error.jsp 文件位于/WEB-INF/jsp/下,则浏览器无法直接访问,指定错误页面的指令可以写成:
<%@ page errorPage="/WEB-INF/jsp/error.jsp" %>
④ errorPage的配置方法二:在 web.xml 中配置
<error-page> <error-code>404</error-code> <location>/WEB-INF/hello.jsp</location> </error-page> <error-page> <exception-type>java.lang.ArithmeticException</exception-type> <location>/WEB-INF/error.jsp</location> </error-page>
3. include 指令
① 用于通知 JSP 引擎在翻译当前 JSP 页面时将其他文件中的内容合并进当前 JSP 页面转换成的 Servlet源文件中。这种源文件级别的引用方式称作静态引入,当前 JSP 页面和静态引入的页面紧密结合翻译成一个 Servlet。
② 命令格式:<%@ include file="/b.jsp" %>
③ file属性值为相对路径:如果以 "/" 开头表示当前 WEB 应用的根目录, 否则表示相对于当前文件的路径。
④ 主 JSP 页面中定义的变量,在被 include 指令引入的 JSP 页面中可以引用。
七. JSP 标签
1. include 标签 <jsp:include page="b.jsp"></jsp:include>
此标签的作用是动态引入,主 JSP 页面和被引入 JSP 页面被转换成两个 Servlet 文件,二者之间通过一个方法引用最终的页面(可以查看转换后的Servlet文件)
2. forward 标签 <jsp:forward page="/include/b.jsp"></jsp:forward>
① 转发标签,相当于:
<%
request.getRequestDispatcher("/include/b.jsp").forward(request, response);
%>
② <jsp:forward> 与 <% %>区别
<jsp:forward>标签可以通过<jsp:param>向转发的页面传递参数,上述的include标签也可以使用<jsp:param>
<jsp:forward page="b.jsp"> <jsp:param value="name" name="xiaoming"/> <jsp:param value="score" name="96"/> </jsp:forward> <!-- b.jsp中获取参数的方式 --> <%= request.getParameter("name") %>
八. 其他
1. include 指令和 <jsp:include>标签的区别
2. 关于中文乱码问题
① 编辑 JSP 页面时输入中文,请求页面后不出现乱码:
a. JSP 页面的contentType="text/html; charset=UTF-8",pageEncoding="UTF-8",
charset 和 pageEncoding 保持一致且都支持中文,建议为 UTF-8
b. 保证浏览器显示的字符编码和请求的 JSP 页面编码一致
② 获取中文参数:
a. 对于 POST 请求: 获取请求信息之前,调用 request.setCharacterEncoding("UTF-8")即可
b. 对于 GET 请求:(Tomcat中的URI编码方式默认是 ISO-8859-1)
<% String param = request.getParameter("name"); String name = new String(param.getBytes("ISO-8859-1"), "UTF-8"); %>
c. 对于 GET 请求,修改tomcat配置来调整URL编码方式,添加useBodyEncodingForURI属性
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI="true"/>