一、JSP简介
HTML擅长显示页面,但是它并不能调用Java代码动态的生成内容;Servlet擅长调用Java程序,生成动态内容,但是Servlet不擅长显示页面。
jsp(Java Server Pages)结合了HTML和Servlet的优点,本质上是运行在服务端的一个Servlet,Tomcat等Servlet容器会将jsp文件中的内容通过out.write()、out.print()等方法直接输出给浏览器,浏览器获取到的依然是一个html文档,然后再进行渲染等。
jsp的特点:
1️⃣JSP = HTML + Servlet
2️⃣JSP可以让我们以编写HTML的方式去编写Servlet
3️⃣JSP就是一个披着HTML外衣的Servlet,酷似HTML,但本质是一个Servlet
4️⃣JSP是不能脱离服务器(Servlet容器)运行的
jsp的运行原理:jsp --翻译–> java --编译–> class
①将JSP文件翻译为一个.java文件(Servlet容器会将jsp中的内容读取到一个Servlet的输出内容中去),翻译后的文件将会放到服务器的work目录中(jsp页面只有在第一次访问之后才会生成对应的.java文件),在work目录中我们会发现比如index_jsp.java文件,这个类index_jsp 继承了 org.apache.jasper.runtime.HttpJspBase,HttpJspBase又继承HttpServlet,所以该类也间接的实现了Servlet接口
②再将java文件编译为class文件(我们在访问JSP时,实际上就是访问的jsp对应的那个class文件)
二、JSP基本语法
1、模板元素
模板元素指就是JSP中的HTML代码,模板元素的内容会作为out.write()的参数,直接输出到页面中,在HTML中怎么写,在JSP中就怎么写
2、 脚本片段
脚本片段写在 <% %>中,可以在脚本片段中直接编写Java代码,脚本片段会原封不动的复制到java文件的service方法中的对应位置,在service方法中可以写什么,在脚本片段中就可以写什么,在jsp中可以编写多个脚本片段,但是要求多个脚本片段之间的结构完整
<%
System.out.println("Hello JSP!");
Date date = new Date();
%>
3、表达式
JSP的表达式写在<%= %>中,JSP表达式可以将一个对象直接输出到页面中,JSP表达式中的内容最终会作为out.print()方法的参数,输出到页面中,out.print()方法可以接收什么样的参数,表达式中就可以写什么内容,而该方法可以接收Object类型的对象,所以在表达式中可以编写任意的对象
<h1><%=date %>h1>
4、注释
JSP的注释写在 <%-- --%>中,JSP注释中的内容不会被JSP引擎翻译到java文件中,JSP中可以使用三种注释:
1️⃣:HTML注释
2️⃣//:Java的注释
3️⃣<%-- --%>:JSP注释
注释完整的jsp脚本的时候,必须使用jsp的注释<%-- --%> ,若用其他的注释后台还是会执行被注释了的脚本片段
5、声明
JSP中的声明写在<%! %>中,JSP声明中的内容会直接翻译到jsp对应的java文件中,声明的变量等会翻译为该java文件的全局变量,我们在类中可以写什么在声明中就可以写什么,这个一般不用
6、JSP指令
JSP指令的格式:<%@ 指令名 属性名1=”属性值1” 属性名2=”属性值2” %>,举例:
a、page指令:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
page指令的属性:
import:在jsp中导包
errorPage:当页面出现错误以后,要转发到的错误页面
isErrorPage:当前页面是否是一个错误页面,默认为false,如果设置为true,则可以在该页面中使用exception对象
isELIgnored:是否忽略EL表达式,默认值是false,一般不动
session:JSP中是否会自动创建session,默认值是true,一般不动
contentType:设置当前JSP内容的类型
pageEncoding:当前页面使用的编码,jsp引擎会自动根据该编码解析jsp文件
language:JSP页面将会被翻译为的语言,默认值是java,可选值只有一个java
autoFlush:是否自动刷新流中内容,默认是true,一般不动
buffer:流使用的缓存大小,默认是8kb,一般不动
extends:当前JSP对应的java文件需要继承的父类,一般不动
info:设置jsp的信息
b、include指令:静态包含,将一个页面包含进另一个页面
<%@ include file="/include/2.jsp" %>
特点:只会将包含后的文件进行翻译得到一个对应的java文件,而不会翻译被包含的文件,相当于将被包含文件中的内容原封不动的复制到指定文件中,这样可以省去很多重复的html代码
c、taglib指令
7、JSP动作标签
格式:
a、请求转发
<jsp:forward page="">jsp:forward>
forward标签用来做请求的转发,我们还可以通过在forward标签中加入param子标签的形式向目标页面发送请求参数
<jsp:forward page="">
<jsp:param value="admin" name="username"/>
jsp:forward>
注意
:如果没有param子标签,
b、动态包含:会将目标页面包含进当前页面
<jsp:include page="/include2/2.jsp">jsp:include>
动态包含会将两个jsp文件都翻译为java文件,一般使用静态包含而不是用动态包含
三、隐含对象
隐含对象也叫内置对象,这些对象可以在JSP中直接使用,这是因为在JSP对应的java文件的service方法中已经声明了这些对象并且都赋了值。
JSP中一共有9大隐含对象:
隐含对象 | 类型 | 作用 |
---|---|---|
pageContext | PageContext | 代表当前页面的上下文,通过它可以获取到jsp中的其他隐含对象,1个顶9个 |
request | HttpServletRequest | |
session | HttpSession | |
application | ServletContext | |
page | Object | 在jsp对应的java文件中有如下代码:Object page = this;因此page代表当前对象,即对应的Servlet,用的不多 |
out | JspWriter | 和Servlet的PrintWriter类似,都是用来向浏览器输出一个内容 |
response | HttpServletResponse | 和Servlet中response一样,但是在jsp中很少使用 |
config | ServletConfig | 可以用来获取JSP的初始化参数,不常用 |
exception | Throwable | 获取页面中的异常信息 |
四、域对象
在JavaWeb中不同的JSP,不同的Servlet都是一个不同的域,域对象的作用就是在不同的web资源之间传递共享数据的。JavaWeb中一共有四个域对象:
域对象 | 类型 | 作用 |
---|---|---|
pageContext | PageContext | 最小的域对象,可以在当前页面中共享数据,一旦切换页面,则域中的属性就会丢失,该对象主要用来向标签中传递数据 |
request | HttpServletRequest | request对象可以在一次请求中共享数据,一旦发送多次请求,则域中的属性就会丢失。主要用于在转发时共享数据(request域中属性在转发时有效,重定向时无效) |
session | HttpSession | session对象可以在一次会话中共享数据,一旦会话结束则域中的属性丢失。会话:就是一次打开关闭浏览器的过程 |
application | ServletContext | application是最大的域对象,作用范围是整个项目,只要不关闭服务器则application域中的属性一直有效 |
四个域对象在使用时能用小的就不用大的,在JSP中可以使用全部的域对象,但是在Servlet中只能使用三个(Servlet中没有PageContext),域对象都有的几个方法:
void setAttribute(String name , Object value); //根据名字向域中存储一个对象
Object getAttribute(String name); //根据属性名从域中获取一个对象
void removeAttribute(String name); //根据属性名从域中移除一个对象
每一个域对象中实际都维护一个map,这个map就是用来保存对象的
四、JSP和Servlet的分工
JSP本质就是一个Servlet,Servlet可以干的事JSP全都能干,所以有那么一段时间,JSP已经完全替换掉了Servlet,那么会导致我们的项目全都是JSP页面。JSP虽然可以直接编写Java代码,但是当在一个JSP中编写大量的Java代码以后,导致JSP页面非常不好维护。JSP擅长显示一个页面,而不擅长大量的编写Java代码,Servlet擅长编写Java代码,而不擅长显示页面, 所以我们开发中都是通过Servlet去调用Java程序去处理请求,而使用JSP来显示页面。
五、jsp的面试题:
①
<%!
int i = 10;
%>
<%
i++;
%>
<%=i%>
注意第一个jsp脚本中的!,表明i是个全局变量,因此每访问一次该页面i的值都会加1,若去掉那个!,每次访问的值都相同是11
②
<%--这是jsp注释,该注释中的内容,在页面上查看源代码是看不到的,可以用来注释私密的内容--%>
③
<%!
public void fun(){
/*
out.println();
*/
}
%>
上面的这段代码现在看是合法的,但把方法中的注释去掉就不合法了,因为内置对象out只存在于jsp页面中,而由于该部分代码相当于定义在servlet类中,并不在页面中,而类中是没有内置对象out的,所以去掉方法中的注释会出现错误,也就是说在jsp声明中不能使用九大内置对象
注意:在页面中有图片需要展示时,别忘了添加代码:
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
和
<base href="<%=basePath %>">