jsp(Java Server Pages)
jsp全称Java Server Pages,是一种动态网页开发技术
.html文件是静态页面
.jsp文件是动态页面
jsp页面允许我们在html代码中嵌入java代码,这样就可以在html中使用java代码来完成功能了。
so jsp =html+java
运行
浏览器可以直接运行html页面但是不可以直接运行jsp页面,jsp也是需要在web容器中运行(tomcat等),因为它本质也是一个Servlet
其中最核心的是有JSP的引擎(jasper.jar),它可以将jsp页面翻译成java程序,并编译成class文件,然后在运行。
所以jsp是运行在服务器端的,运行完之后,把动态生成的html页面再使用io流写回给浏览器,浏览器接收并且解析后再呈现出来效果。
关系
因为JSP页面第一次被访问时,会被tomcat服务器编译成一个java类,这个java类默认继承HttpJspBase类,而HttpJspBase类是HttpServlet的子类,所以JSP其实就是一个servlet程序,所以得和servlet一样运行于web容器中;
jsp页面被tomcat服务器编译成的java文件及其class文件,保存在tomcat服务器里面的work目录中,在这里的代码中,我们还可以看见它是如何使用io流把生成的html页面代码一行一行写回给浏览器的。
/*
\* Generated by the Jasper component of Apache Tomcat
\* Version: Apache Tomcat/8.5.58
\* Generated at: 2020-10-07 01:50:21 UTC
\* Note: The last modified time of this file was set to
\* the last modified time of the source file after
\* generation to assist with modification tracking.
*/
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long>
_jspx_dependants;
private static final java.util.Set<java.lang.String> _jspx_imports_packages;
private static final java.util.Set<java.lang.String> _jspx_imports_classes;
static {
_jspx_imports_packages = new java.util.HashSet<>();
_jspx_imports_packages.add("javax.servlet");
_jspx_imports_packages.add("javax.servlet.http");
_jspx_imports_packages.add("javax.servlet.jsp");
_jspx_imports_classes = null;
}
private volatile javax.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public java.util.Set<java.lang.String> getPackageImports() {
return _jspx_imports_packages;
}
public java.util.Set<java.lang.String> getClassImports() {
return _jspx_imports_classes;
}
public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory == null) {
synchronized (this) {
if (_el_expressionfactory == null) {
_el_expressionfactory =
_jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).ge
tExpressionFactory();
}
}
}
return _el_expressionfactory;
}
public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager == null) {
synchronized (this) {
if (_jsp_instancemanager == null) {
_jsp_instancemanager =
org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletCo
nfig());
}
}
}
return _jsp_instancemanager;
}
public void _jspInit() {
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request,
final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final java.lang.String _jspx_method = request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) &&
!"HEAD".equals(_jspx_method) &&
!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许
GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
return;
}
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.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;
out.write("\r\n");
out.write("<!DOCTYPE html>\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write("<meta charset=\"UTF-8\">\r\n");
out.write("<title>index.html</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("\t");
String name = "tom";
out.write("\r\n");
out.write("\t\r\n");
out.write("\t<h1>");
out.print("hello!"+name );
out.write("</h1>\r\n");
out.write("\t\r\n");
out.write("</body>\r\n");
out.write("</html>");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null)
_jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
注意,这里的 _jspService 方法,就相当于servlet中的 service 方法,jsp被访问的时候会自动调用该方法。
代码:
jsp页面中嵌入java代码,一共有三种方式:
-
表达式(expression)
-
脚本(scriptlet)
-
声明(declaration)
表达式
形式:
<%= %>
例如,
<%="hello" %>
<%=1+1 %>
<%=s.getName() %>
将来翻译到java文件中的位置:
_jspService方法中,out.print(…)代码的参数
例如,上面那几个例子会翻译成
out.print("hello");
out.print(1+1);
out.print(s.getName());
所以out.prntln()这个方法的参数可以写什么,那么这个jsp页面中表达式里面就可以写什么
注意,在jsp中的表达式,语句的最后不需要加;号
脚本
形式:
<% %>
例如,
<%
Student s = new Student();
String name = "tom";
String username = s.getName();
List<String> list = new ArrayList<String>();
list.add("hello")
%>
将来翻译到java文件中的位置:
脚本中的代码将来会被直接翻译到_jspService这个方法中
所以,在一个普通的方法中我们可以写什么样的代码,那么在脚本中就可以写什么样的代码.
声明
形式:
<%! %>
例如,
<%!
private String name;
public String go(){
System.out.println("hello world "+name);
return "this is go()";
}
%>
将来翻译到java文件中的位置:
直接将声明中的代码翻译到java文件里面所定义的类中
所以,我们可以在一个类中写什么(属性和方法),就可以在声明中写什么
指令
jsp的指令是给jsp引擎看的,让jsp引擎在翻译jsp页面成java文件的时候,知道需要注意哪些地方的设置。比如页面中的编码、页面中脚本里面所用的编程语言、翻译的java文件中需要引入哪些包下的java类等等
语法
<%@指令名字 属性=“值” … %>
分类:
-
page指令
-
include指令
-
taglib指令
page
page是常用的一个jsp指令,可以用来指定当前jsp的一些基本设置
例如,新建jsp页面后,文件头部会默认有以下page指令的设置
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
其作用分别是
指定当前jsp页面中嵌入的语言是java
指定写回给浏览器页面的时候,contentType的内容
指定当前页面件保存时候所用的编码
例如,在jsp中引入其他的类和接口
<%@ page import="java.util.List,java.util.ArrayList" %>
例如,指定当前jsp页面中是否支持session的使用,默认值就是true
<%@ page session="true" %>
例如,指定当前页面出错之后,会跳转到error.jsp页面
<%@ page errorPage="error.jsp" %>
例如,指定当前页面是专门用来显示错误的页面,在当前页面中可以使用隐藏对象exception来显示错误信息
<%@ page isErrorPage="true" %>
include
include指令,可以将另一个页面的显示内容,引入到当前页面中的指定位置
形式,
<%@include file="" %>
taglib
taglib指令,在jsp中可以引入标签库,然后就可以使用标签库中的标签,来完成相应的功能了
例如,引入JSTL标签库
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
例如,引入spring框架的标签库
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
例如,引入struts2框架的标签
<%@ taglib uri="/struts-tags" prefix="s" %>
注意1,引入标签库,需要先在项目中引入对应的jar包
注意2,uri属性,指的是标签库的设置的URI地址
注意3,prefix属性,指的是给引入的标签库起一个别名,这样使用起来较为方便
动作
jsp中还有内置的标签,称之为jsp的动作元素,它的本质就是把固定的java代码,封装成了标签的形式。
例如,
<jsp:useBean id="s" class="com.briup.bean.Student" scope="page"></jsp:useBean>
相当于代码
<%
Student s = null;
s = (Student)pageContext.getAttribute("s");
if(s==null){
s = new Student();
pageContext.setAttribute("s",s);
}
%>
<jsp:setProperty property="name" value="tom" name="s"/>
相当于代码
<%
Student s = (Student)pageContext.getAttribute("s");
s.setName("tom");
%>
<jsp:getProperty property="name" name="s"/>
相当于代码
<%
Student s = (Student)pageContext.getAttribute("s");
out.write(s.getName());
%>
JSP的动作元素中,常被用的有俩个:
forward
include
例如,页面跳转
<jsp:forward page="target.jsp"></jsp:forward>
例如,跳转的同时还可以传参数
<jsp:forward page="target.jsp">
<jsp:param value="tom" name="name"/>
</jsp:forward>
例如,在当前页面中包含另一个页面
<jsp:include page="foot.jsp"></jsp:include>
例如,在包含页面的同时,还可以传参
<jsp:include page="foot.jsp">
<jsp:param value="lisi" name="name"/>
</jsp:include>
一个页面包含/引入另外一个页面有俩种方式
静态包含, <%@include file="" %>
动态包含, <jsp:include page=""></jsp:include>
静态包含,在jsp翻译成java程序的时候,直接将另一个页面的内容原封不动的写入到代码中。
动态包含,在jsp翻译成java程序的时候,只会把包含的动作翻译成一个方法的调用,将来在访问的时候
才会真正的去获取另一个页面的内容。
注意,动态包含可以传参,静态包含不能穿参
注释
html/xml中的注释方式
-
用户在浏览器中右键查看源代码 【能】 看到这个注释
-
在服务器端,这个jsp页面被翻译成的java文件中 【能】 看到这个注释
注意,jsp动作元素,放在这种注释里面是不起作用(注释不起作用,jsp动作元素正常执行)
例如:下面的注释不起作用`
例如:下面的注释不起作用 例如:下面的注释不起作用 <!-- <jsp:forward page="hello.jsp"></jsp:forward> -->
jsp中的注释方式
<%–
jsp中的注释方式(隐藏注释)
–%>
特点:
- 用户在浏览器中右键查看源代码
【不能】看到这个注释。
- 在服务器端,这个jsp页面被翻译成的java文件中 [不能] 看到这个注释.
java中的注释方式
java中的注释方式,只能在jsp的脚本或者声明中使用。
例如,
<%
//String name = "tom";
/*
int b = 40;
*/
/**
int a = 20;
*/
%>
特点:
-
用户在浏览器中右键查看源代码 【不能】 看到这个注释。
-
在服务器端,这个jsp页面被翻译成的java文件中 【能】 看到这个注释.
JSP内置对象(九种)
类型 名字 作用
PageContext pageContext 页面范围对象
HttpServletRequest request 和servlet中的相同
HttpSession session 和servlet中的相同
ServletContext application 和servlet中的相同
Object page jsp页面本身(this)
HttpServletResponse response 和servlet中的相同
JspWriter out 输出流,可以给客户端写回内容
ServletConfig config 和servlet中的相同
Throwable exception 隐藏对象,表示jsp中的异常
注意,这些对象的类型和名字都是固定的,任意打开一个jsp页面翻译成的java代码,查看
_jspService方法,就可以看到这些内置的对象
注意,JSP中比servlet多了一个更加小的传值范围pageContext,存进去的值,只会在一个页面中有
效,比之前的request范围还要小
默认情况下,
jsp页面中是不能使用exception这个对象的,除非页面中设置了isErrorPage属性:
<%@ page isErrorPage=“true” %>