JSP这三个字母是Java Server Pages的缩写,见名知意java的服务器页面
为什么会出现jsp呢?先看一段servlet的代码:
@WebServlet("/aser")
public class AServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置编码格式
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
writer.write("\n");
writer.write("\n");
writer.write("ser \n");
writer.write("\n");
writer.write("\n");
writer.write("这是Servlet
\n");
writer.write("\n");
writer.write("\n");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
中间那么大一块就在浏览器输出了一个这是Servlet
,是不是很复杂,各种标签需要我们去包裹起来,要是这样开发,程序员的开发成本也太大了,于是就由此衍生了jsp,让jsp帮我们干这些繁琐的事情,来看jsp的代码如何实现上面的:
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="500.jsp" %>
$Title$
这是Servlet
是不是像是HTML一样的简写写法,那么jsp的底层原理到底是什么?为什么就能如此简单的实现servlet中如此复杂的代码,按说这个只能servlet来完成的,带着这个问题,看下面的源码:
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports
这里是jsp被翻译出来的java类,继承了HttpJspBase
类,这个又继承了HttpServlet
类,于是jsp的这个类间接继承了HttpServlet类。于是,我们可以得出一个结论:
JSP其实就是Servlet程序
可以看下面的源码,_jspService方法中也是用到我们手写方式,这就是底层帮我们干了我们觉得很麻烦的事,这也很好的解释了JSP就是Servlet程序了,底层仍然是Servlet。
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, "JSPs only permit GET POST or HEAD");
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,
"500.jsp", true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\n");
out.write("\n");
out.write(" \n");
out.write(" $Title$ \n");
out.write(" \n");
out.write(" \n");
out.write("这是主页
\n");
out.write(" \n");
out.write("\n");
} 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);
}
}
这就可以解释为什么它可以干Servlet的事了。
page 用于声明jsp : jsp=html+page指令
page 里面常见的属性:
taglib 用于导入外部资源标签库,jstl
作用:引入外部标签库,通常用于引入jstl标签
include 静态包含,一个jsp页面可以包含另一个jsp页面
作用:静态包含 – 两个jsp之间使用静态包含,会被tomcat服务器编译成一个servlet,可以实现脚 本互通
a.jsp:
<%@include file="b.jsp"%>
<%
System.out.println(name);
%>
b.jsp:
<%
String name = "wang";
%>
我们访问a.jsp时候,会打印出wang
<%! 代码 %> 声明脚本
这种方式,用的还是比较少的,一般用来定义属性和方法,也可以写静态代码块,内部类什么的
<%
java代码
%>
这种方式用的比较多,这是代码脚本,因为编译之后,全部都在_jspService
方法中
<%=表达式%>表达式脚本
这用用的比较多,可以看下面的例子:
<%
pageContext.setAttribute("key1","pageContext域");
String key1 = (String) pageContext.getAttribute("key1");
out.write(key1);
%>
pageContext:<%=pageContext.getAttribute("key1")%>
上面就可以看出来这种脚本的强大之处了吧,直接可以输出到页面上,非常方便。
九大对象如下:
request | 请求对象 |
---|---|
response | 响应对象 |
pageContext | jsp的上下文对象 |
session | 会话对象 |
application | ServletContext对象 |
config | ServletConfig对象 |
out | jsp输出流对象 |
page | 指向当前jsp的对象 |
exception | 异常对象 |
这个看一下就行了,知道各个对应什么对象就可以。
域对象 | 对应的类 | 作用 |
---|---|---|
pageContext | PageContextImpl类 | 只在当前的jsp界面内起作用 |
request | HttpServletRequest类 | 只在一次请求内起作用 |
session | HttpSession类 | 只在一次会话内有用,关闭浏览器会话结束 |
application | ServletContext类 | 只要web工程没停止,整个范围内都有起作用 |
上面的作用有限顺序从小到大:
pageContext request session application
例子:
a.jsp
<%
/*pageContext ====>>> request ====>>> session ====>>> application*/
//向着四个域中分别保存数据
pageContext.setAttribute("key1","pageContext域");
request.setAttribute("key2","request域");
session.setAttribute("key3","session域");
application.setAttribute("key4","application域");
%>
<%--看这四个域中是否有值--%>
pageContext:<%=pageContext.getAttribute("key1")%>
request:<%=request.getAttribute("key2")%>
session:<%=session.getAttribute("key3")%>
application:<%=application.getAttribute("key4")%>
<%--转发到b.jsp--%>
b.jsp
<%--看这四个域中是否有值--%>
pageContext:<%=pageContext.getAttribute("key1")%>
request:<%=request.getAttribute("key2")%>
session:<%=session.getAttribute("key3")%>
application:<%=application.getAttribute("key4")%>