html + java代码 + JSP动态标签 = jsp
JavaServer page
在静态页面上添加动态信息就可以了,如果是Servlet还需要一行一行的输出。
通常在前台开发人员给出静态页面后,后台开发人员只需在静态页面中添加动态信息即可,而不用再使用Servlet一行一行的去输出了。
当客户请求的是JSP页面时,服务器会查看JSP对应的Servlet是否存在,如果存在,那么直接调用Servlet的service()方法来处理请求。如果不存在,那么服务器会先把JSP编译成.java,再把.java编译成.class,然后调用service()方法。当这个JSP页面,第二处理请求时,就直接调用直身的service()方法了。
JSP是Servlet,JSP与我们编写的Servlet有什么不同呢?通常我们编写的Servlet就不需要输出HTML代码了,而是转发到JSP页面。
即Servlet不再负责显示页面,而由JSP来完成!而Servlet专注与控制层内容!
从单词上分析script是脚本:let在JAVA中表示的小程序,scriptlet表示脚本小程序。
JSP中的Java代码块就是最常见的动态信息。它分为三种:
<%...%> :java代码片段
代码片段会原模原样的出现在真身中,不会有变动。正常的Java代码都可以在代码片段中出现;
<%= …%>:表达式在页面上打印数据
表达式会在“真身”中输出,例如:,对应真身中的out.print(a)。只能出现常量、变量,以及有返回值的方法调用,而且不能出现分号!即在out.println()的合法参数都可以!
对应out.println(a);
”a”%>对应out.println(“a”);
对应out.println(fun());
对应out.println(a;),所以出错;
“hello”)%>对应out.println(System.out.println(“hello”)),所以出错。
<%!...%> :声明
声明对应“真身”中的属性和方法!
语法:<%--… --%>
其中JSP只有一种注释:<%--… --%>,注释中的内容会被JSP编译系统忽略!
Html注释和jsp注释二者的区别!
内置对象是在JSP页面中无需创建就可以直接使用的变量。在JSP中一共有9个这样的对象!它们分别是:
我们发现,在JSP中的内容会出现在“真身”的_jspService()方法中,而且在_jspService()方法上方还有一些其他代码:
public void _jspService(HttpServletRequest
request, HttpServletResponse response)
throws java.io.IOException, ServletException {
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
从这里开始,才是JSP页面的内容
}…
JSP中的内容都出现在try块中,而且在try块的正文!上方是对隐藏对象的初始化!!!
上面代码只是给出普通页面的“真身”,而错误页面的“真身”你会看到exception对象的出现。
域对象的共同特点是都管理域中的属性,他们有着相同的方法:
pageContext 对象是PageContext类型,它不只是域对象,而且还可以操作所有域对象,还可以获取其他隐藏对象。
①本身是域对象:pageContext是JSP中的域对象,而在Servlet中不能使用它!它表示的当前页面中可以使用,是最小的范围!
②操作所有域(四个域):可以使用pageContext对象操作所有域对象,在getAttribute()、setAttribute()、removeAttribute()三个方法中多添加一个参数,int scope来指定范围。在PageContext类中包含四个int类型的常量表示四个范围:
③获取其他隐藏对象:可以使用pageContext获取其他隐藏对象。
JSP指令的格式:指令名 attr1=”” attr2=”” %>,一般都会把JSP指令放到JSP文件的最上方,但这不是必须的。
JSP中有三大指令:page、include、taglib,最为常用,也最为复杂的就是page指令了。
指令在“真身”中不存在,生成“真身”时需要使用指令!
Tomcat编译系统会根据JSP的指令信息来编译JSP,生成Java文件。
在生成的Java文件中,不存在指令信息!
pageEncoding指定的是当前JSP页面的编码!Tomcat编译系统会使用这个编码把JSP编译成Java文件。所以这个编译只需要与真实的页面编译一致即可!
contentType指定的是响应给我客户端时使用的编码,即对应response.setConteType()方法的参数值! Tomcat都会把响应正文转换成UTF-8编译,然后发送给我客户端,并且会在响应头中设置Content-Type头信息为text/html;charset=utf-8,这样浏览器就知道使用服务器发送过来的正文使用了什么编码。
其实pageEncoding和contentType这两个属性的关系很暧昧:
也就是说,当pageEncoding和contentType只出现一个时,那么另一个的值与出现的值相同。如果两个都不出现,那么两个属性的值都是ISO-8859-1。
处理乱码的方案:
但是,我们一般会使用多个page指令来导入多个包:
<%@ page import="java.util.*"%>
<%@ page import="java.net.*"%>
<%@ page import="java.text.*"%>
我们知道,在一个JSP页面出错后,Tomcat会响应给我用户错误信息!如果你不希望Tomcat给用户输出错误信息,那么可以使用page指令的errorPage来指定错误页!例如:
<%@ page errorPage="error.jsp"%>
这时,在当前JSP页面出现错误时,会转发到error.jsp页面。
pageError的路径,由于是服务器端的跳转,所以绝对路径不需要加项目名,直接指定项目名称后面的路径即可
如果希望在error.jsp页面中获得异常对象,那么就需要把error.jsp标记为错误页!这需要设置page指令的isErrorPage属性为true。
<%@ page isErrorPage="true" %>
错误页面
出错了!!!
<%=exception.getMessage() %>
还可以在web.xml文件中配置错误页面,在出现某种错误时跳转到对应的页面处理。
404
/error404.jsp
500
/error500.jsp
当出现404时,会跳转到error404.jsp页面;
当出现500时,会跳转到error500.jsp页面。
还可以配置更多,更细致的异常类型。
page指令的isElIgnored属性表示当前JSP页面是否忽略EL表达式,默认值为false,表示不忽略(即支持)。
EL(Expression Language)表达式语言是一种用于在Java服务器端页面(JSP)中访问和操作数据的简洁、强大的语言。它允许在JSP页面中使用表达式来获取和操作数据,而无需编写复杂的Java代码。
EL表达式的语法类似于JavaScript或XPath表达式,它使用方括号[]来访问对象的属性和集合的元素。例如,${user.name}可以获取名为user的对象的name属性的值。
EL表达式可以用于访问JSP页面中的各种数据,包括请求参数、会话属性、上下文属性、JavaBean属性等。它还支持基本的数学运算、字符串操作和条件判断等。
include指令表示静态包含!
include指令只有一个属性:file,指定要包含的页面,例如:”b.jsp”%>。
静态包含:当hel.jsp页面包含了lo.jsp页面后,在编译hel.jsp页面时,需要把hel.jsp和lo.jsp页面合并成一个文件,然后再编译成Servlet(Java文件)。
在上面代码中,lo.jsp中没有定义username变量,所以lo.jsp不能处理请求,只有hel.jsp才能处理请求!当访问hel.jsp时,hel.jsp会包含lo.jsp,所以两个会合并成一个文件后再编译成Java文件。在合并之后,因为在hel.jsp中定义了username变量,所以lo.jsp中也就不会出现错误了。
在JSP页面中使用第三方的标签库时,需要使用taglib指令来“导包”。例如:
http://java.sun.com/jsp/jstl/core" %>
其中prefix表示标签的前缀,这个名称可以随便起。uri是由第三方标签库定义的,所以你需要知道第三方定义的uri。
在下面我们讲解JSTL标签库时会说明taglib指令的使用方式。
JSP自己的标签,不用导包!
JSP动态标签是JSP自己的标签,不是由第三方提供的,所以使用JSP动态标签时无需使用taglib指令“导包”。
JSP动态标签的格式为:…>
无论是自定义的JSP标签,还是JSP自己的动态标签,还有第三方的标签,最终都会对应一组方法的调用!!!
include标签是动态包含,与include指令不同,include标签与RequestDispatcher.include()方法的功能是相同的。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
a.jsp
a.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
b.jsp
b.jsp
动态包含是会为两个JSP页面都生成“真身”,然后a.jsp的“真身”中会调用b.jsp的“真身”的_jspService()方法而已。
forward标签的作用是请求转发!forward标签的作用与RequestDispatcher#forward()方法相同。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
c.jsp
c.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
d.jsp
d.jsp
注意,显示结果中没有