1、JSP原理
什么是JSP?
Java Server Pages:Java服务器页面,和Servlet一样是动态Web技术!
和HTML的区别?
- HTML是静态页面。
- 在JSP页面中可以嵌入Java代码,为用户提供动态的数据。
JSP 和 Servlet 的关系?
- JSP最终会被转换为一个Java类,JSP的本质就是一个Servlet!
- 我的在访问 index_jsp 时,会自动生成一个Java 类 index_jsp,它继承了 HttpJspBase,HttpJspBase 又继承了 HttpServlet。
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent, org.apache.jasper.runtime.JspSourceImports{ //... }
1、内置对象
final javax.servlet.jsp.PageContext pageContext; //页面上下文对象 javax.servlet.http.HttpSession session = null; //session final javax.servlet.ServletContext application; //applicationContext final javax.servlet.ServletConfig config; //servletConfig javax.servlet.jsp.JspWriter out = null; //out final java.lang.Object page = this; //page HttpServletRequest request //请求 HttpServletResponse response //响应
2、输出页面前增加的代码
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;
3、输出到页面
显示一个hello world和静态页面。
out.write(" \r\n"); out.write(" <HTML>\r\n"); out.write("<body>\r\n"); out.write("<h1>hello world</h1>\r\n"); out.write("</body>\r\n"); out.write("</HTML>\r\n"); out.write("\r\n");
4、JSP页面内直接调用上面的对象
通过 ${}来调用
5、JSP实现过程
index.jsp-> index_jsp.java -> index_jsp.class`-> Servlet程序
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>首页</title> </head> <body> <% String name = "李元芳"; %> hello <%=name%> </body> </html>
运行结果:
2、JSP 基础语法
1、JSP表达式
用来将程序的输出结果输出到客户端
<%--在客户端页面中显示当前时间--%> <%= new java.util.Date()%>
2、JSP脚本片段
输出1到100的和,JSP脚本片段中的变量都是唯一的,因为它最终会变成一个Servlet类,因此不同代码片段中可以互相访问变量。
<% int sum = 0; for (int i = 1; i <= 100; i++) { sum += i; } out.println("<h1>Sum = "+ sum + "</h1>"); %>
3、全局变量的定义
相当于我们Java类下面的全局变量和方法的声明。
<%! private String word = "hello"; public static void sayHi(String name){ System.out.println("hello " + name); } %>
4、JSP指令
1、jsp 设置错误页面
语法:<%@ page %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@page errorPage="error/500.jsp" %> <html> <head> </head> <body> <%-- 制造一个500的错误--%> <% int x = 100/0; %> </body> </html>
因为我们的服务器代码中有错误,所以会报一个500的错误,我们设置如果当前页面报错就跳转到 500.jsp 中。
2、在 web.xml 中指定错误页面
<error-page> <error-code>404</error-code> <location>/error/404.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/error/500.jsp</location> </error-page>
3、公共页面
两种实现方式:
更推荐使用 下面的,因为下面的本质还是三个网页,但上面的本质是将标签合并成一个网页,所以合并后很容易造成变量冲突。
像这种不管哪个页面上面都是这种公共的头部,我们可以设置公共网页嵌入jsp页面当中。
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <%-- 原理:将三个页面合并为一个,提取标签 --%> <%@ include file="common/header.jsp"%> <%-- 效果和上面一样,不过这个的本质还是三个网页 --%> <jsp:include page="common/header.jsp"/> <hr> 这里是网页主体 <hr> <%@ include file="common/footer.jsp"%> </body> </html>
3、JSP9大内置对象(重点!!!)
- PageContext 存东西
- Request 存东西
- Response
- Session 存东西
- Application【ServletContext】存东西
- config【ServletConfig】
- out 【JSPWriter】
- page
测试
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <%--内置对象--%> <% pageContext.setAttribute("name1","鲁班一号"); request.setAttribute("name2","鲁班二号"); session.setAttribute("name3","鲁班三号"); application.setAttribute("name4","鲁班四号"); %> <%--Java脚本片段需要使用Java语法的注释 因为它会原封不动低生成到 .JSP.java--%> <% //通过pageContext取出节点的值 Object name1 = pageContext.findAttribute("name1"); //保存的数据只在一个页面中有效 Object name2 = pageContext.findAttribute("name2"); //保存的数据值在一次请求中有效,请求转发时会携带这个数据 Object name3 = pageContext.findAttribute("name3"); //保存的数据值在一次会话中有效,从打开浏览器到关闭浏览器 Object name4 = pageContext.findAttribute("name4"); 保存的数据值在服务器中有效,从打开服务器到关闭服务器 Object name5 = pageContext.findAttribute("name5");//不存在 %> <h1>取出的Attribute节点的值</h1> <%--使用el表达式输出--%> <h3>${name1}</h3> <h3>${name2}</h3> <h3>${name3}</h3> <h3>${name4}</h3> <%--如果不存在会返回 null 但使用el表达式会自动过滤掉它--%> <%=name5%> </body> </html>
使用el表达式
运行结果:
直接使用 <%=%>显示变量
运行结果:
在另一个新页面中访问新页面的节点Attribute的值
<html> <head> <title>Title</title> </head> <body> <% //通过pageContext取出PageContextDemo01.jsp 中节点的值 Object name1 = pageContext.findAttribute("name1"); //保存的数据只在一个页面中有效 Object name2 = pageContext.findAttribute("name2"); //保存的数据值在一次请求中有效,请求转发时会携带这个数据 Object name3 = pageContext.findAttribute("name3"); //保存的数据值在一次会话中有效,从打开浏览器到关闭浏览器 Object name4 = pageContext.findAttribute("name4"); 保存的数据值在服务器中有效,从打开服务器到关闭服务器 Object name5 = pageContext.findAttribute("name5");//不存在 %> <h1>取出PageContextDemo01.jsp 的Attribute节点的值</h1> <%--使用el表达式输出--%> <h3>${name1}</h3> <h3>${name2}</h3> <h3>${name3}</h3> <h3>${name4}</h3> </body> </html>
运行结果:
pageContext.setAttribute(String s,Object o,int scope)
上面我们是通过不同的内置对象来实现不同的数据的作用域,在JSP中,其实还有一种只需要通过PageContext对象就可以设置多种作用域的方法。
//scope: 作用域 public void setAttribute(String name, Object attribute, int scope) { switch(scope) { case 1: this.mPage.put(name, attribute); break; case 2: this.mRequest.put(name, attribute); break; case 3: this.mSession.put(name, attribute); break; case 4: this.mApp.put(name, attribute); break; default: throw new IllegalArgumentException("Bad scope " + scope); } }
其中第三个参数代表创建 Attribute节点的同时,指定数据的作用域,1 代表当前页面,2 代表请求时生效,3 代表一次会话中有效,4 代表服务器中有效 。
public abstract class PageContext extends JspContext { public static final int PAGE_SCOPE = 1; public static final int REQUEST_SCOPE = 2; public static final int SESSION_SCOPE = 3; public static final int APPLICATION_SCOPE = 4; //... }
在 JSP 中获取数据,并指定作用域等级。
<% pageContext.setAttribute("name3","kk",PageContext.PAGE_SCOPE); %>
总结
作用域等级:pageContext--->request--->session--->application。
pageContext 实现请求转发
<% //转发 pageContext.forward("/index.jsp"); //等同于 request.getRequestDispatcher("/index.jsp").forward(request,response); %>
使用场景
pageContext、request、session和application都可以实现存储数据到Attribute节点,但是适用场景有所不同:
- pageContext 保存的数据只在当前页面生效,所以很少使用。
- request 保存的数据值在一次请求中有效,请求转发时会携带这个数据。适用于用户请求完就没用的数据,比如新闻。
- session 保存的数据值在一次会话中有效,从打开浏览器到关闭浏览器。用户用完一会还有用,比如购物车。
- application 保存的数据值在服务器中有效,从打开服务器到关闭服务器。一个用户用完了,其它用户还可能用,比如网页聊天数据。