1. jsp的在服务器中的内部结构
2. jsp的三种语法
a) jsp头部的page指令
b) jsp中的三种脚本
i. 声明脚本(类中(非_jspService()方法中))
ii. 表达式脚本(_jspService方法)
iii. 代码脚本(_jspService方法中)
c) jsp中的三种注释
i. html注释
ii. java注释
iii. jsp注释
3. jsp九大内置对象
4. jsp四大域对象
5. jsp中的out输出和response.getWriter输出的区别
6. jsp的常用标签
a) jsp静态包含
b) jsp标签-动态包含
c) jsp标签-转发
7. 静态包含和动态包含的区别
jsp的全称是java server pages.java的服务器页面。动态页面。
jsp主要是为了解决Servlet程序输出html页面,代码过于繁锁事情。
如下是用servlet输入的html页面
public class PrintHtml extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html; charset=UTF-8"); //获取字符输出流 PrintWriter writer = response.getWriter(); writer.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n"); writer.write("<html>\r\n"); writer.write(" <head>\r\n"); writer.write(" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n"); writer.write(" <title>Insert title here</title>\r\n"); writer.write(" </head>\r\n"); writer.write(" <body>\r\n"); writer.write(" this is the hello html!\r\n"); writer.write(" </body>\r\n"); writer.write("</html>"); } }
从上面的代码可以看出其繁琐性,如果HTML页面过于复杂,则servlet就会显得臃肿
jsp技术存的主要目标,就是为了解决Servlet程序输出html过于繁锁。不方便项目的开发和后期维护。
jsp页面和hmlt页面一样。都存放在WebContent目录下。
jsp页面的和html页面的访问一样。
比如:
在WebContent目录下有:
a.html 访问的地址是:http://ip:port/工程名/a.html
c.jsp 访问的地址是:http://ip:port/工程名/c.jsp
jsp的本质是一个Servlet程序
当我们第一次访问jsp页面的时候。Tomcat服务器会把jsp页面翻译成为Servlet程序
第一次访问jsp页面的时候(即,每次更改jsp页面该目录下的_jsp.java文件不会自动刷新,需要在浏览器刷新之后,其里面的内容才会发生刷新)。我们会发现,在tomcat服务器的work目录下,会有这些的文件。
我们打开a_jsp.java源文件,我们发现。里面是:
然后根据源码中的继承关系,我们找到了HttpJspBase的实现类(源码),在源码中,不难发现。HttpJspBase其实继承了HttpServlet类,
那么 也就是,我们访问jsp的时候Tomcat服务器帮我们翻译出来的a_jsp类其实也是间接继承了httpServlet类。
那么 说明翻译出来的类,本身也是一个Servlet程序。
那么 我们翻译出来的Servlet程序的源码中,我们发现如下的代码:
又一次证明 jsp页面,是为了解决Servlet程序输出html页面过繁锁这样的事情。
a. jsp 翻译之后 是 a_jsp.java
b. jsp 翻译之后 是 b_jsp.java
2. jsp的三种语法
a) jsp头部的page指令
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
i. language属性 表示jsp翻译之后是指定的java语言内容
ii. contentType属性 设置了jsp页面输出给客户端的数据的类型。
i. pageEncoding属性 设置当前jsp页面的字符集
ii. import属性它可以导入你需要包或类
iii. autoFlush属性自动刷新 out 输出流(缓冲区)。默认值是true(不能改为false)
iv. buffer属性它是out输出流的缓冲区,设置了缓冲区的大小。默认是8kb
当autoFlush设置为false,out缓冲区满了之后不让执行flush操作,客户端就会发生如下错误,buffer缓冲区溢出。
i. errorPage属性设置当jsp运行时。出错,就会自动跳转去的页面。(为了不给用户一个差的体验)
ii. isErrorPage属性设置当前jsp页面是否是一个错误页面。它会启用Exception异常对象。默认是false
iii. session 属性设置访问jsp页面的时候,是否创建Session会话对象。默认是true。
iv. extends 属性给留服务器厂商(一般不会改动)
b) jsp中的三种脚本
i. 声明脚本(类中(非_jspService()方法中))
作用:声明为类中(非_jspService()方法中)的代码
格式脚本的格式是:
<%! %>
1. 我们可以定义全局变量。
2. 定义static静态代码块
3. 定义方法
4. 定义内部类
<body> <!-- 1.我们可以定义全局变量。 --> <%! private int i = 12; private static Map<String,Object> map; %> <!-- 2.定义static静态代码块 --> <%! static { map = new HashMap<String,Object>(); map.put("key1", "value1"); map.put("key2", "value2"); } %> <!-- 3.定义方法 --> <%! public int abc(){ return 0; } %> <!-- 4.定义内部类 --> <%! public static class A { private int kkk; } %> this is the hello html!<br/> </body>
务器自动帮我们生成代码在tomca目录下的work工作区间中的对应servlet与jsp页面中的代码:
ii. 表达式脚本(_jspService方法)
作用: 在jsp页面中输出数据
表达式脚本格式是:
<%=表达式 %>
表达式脚本可以在jsp页面中输出数据。
表达式脚本被翻译之后在_jspService方法中
表达式脚本翻译之后都是out.printl输出
在_jspService方法中的对象都可以直接使用。
在表达式脚本中,表达式不能以分号结尾
1. 输出整型
2. 输出浮点型
3. 输出字符串
4. 输出对象
<!-- 1.输出整型 --> <%=124 %><br/> <!-- 2.输出浮点型 --> <%=12.12 %><br/> <!-- 3.输出字符串 --> <%="dfsawrqwafsa" %><br/> <!-- 4.输出对象 --> <%=map %><br/> <%=12==12?"12等于12":"12不等于12" %><br/>
iii. 代码脚本(_jspService方法中)
作用:
代码脚本它可以在_jspService方法中定义你需要的代码内容。
代码脚本最终会被翻译到_jspService方法中
换句话说。也就是我们能在_jspService方法中写的代码,都可以在代码脚本中编写。
格式:
<% %>
1. 代码脚本----if 语句
2. 代码脚本----for 循环语句
3. 翻译后java文件中_jspService方法内的代码都可以写
<% int i = 12 ; // if 语句 if (i == 12) { System.out.println("i等于12"); } else { System.out.println("i不等于12"); } // for 循环语句 for (int j = 0; j < 10; j++) { System.out.println(j); } String username = request.getParameter("username"); System.out.println(username); // 获取工程名 System.out.println( application.getContextPath() ); %>
c) jsp中的三种注释
i. html注释
html注释都会被翻译到_jspService方法中,然后以out.write输出到客户端。
ii. java注释
java注释在翻译之后 ,会被翻译到java源代码中//xxxx
iii. jsp注释
jsp注释在翻译的时候会被完全忽略掉。
3. jsp九大内置对象
4. jsp四大域对象
application |
ServletContext |
整个web工程(只要服务器或工程不停。数据都在) |
session |
HttpSession |
览器打开到浏览器关闭 一个会话(打开浏览器请求服务器。中间,只要浏览器不关,会话都在。) |
request |
HttpServletRequest |
请求对象(每次请求,由Tomcat服务器创建) |
pageContext |
PageContext |
在一个jsp页面中,是jsp上下文对象 |
域对象,就是可以像map一样存取数据的对象
四个域在使用的时候,按从小到大的顺序。
pageContext --->>> request ---->>>> session ---->>>application
测试:
先运行Context1.jsp查看四种结果
Context1.jsp代码:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <% pageContext.setAttribute("key", "pageContext"); request.setAttribute("key", "request"); session.setAttribute("key", "session"); application.setAttribute("key", "application"); %> <h1>Context1.jsp页面</h1> pageContext : <%=pageContext.getAttribute("key") %><br/> request : <%=request.getAttribute("key") %><br/> session : <%=session.getAttribute("key") %><br/> application : <%=application.getAttribute("key") %><br/> <% // 转发中的斜杠 表示到http://ip:port/工程名/ 映射到代码的WebContent目录 // request.getRequestDispatcher("/context2.jsp").forward(request, response); // 重定向的斜杠 表示到http://ip:port/ // response.sendRedirect("/Hello/context2.jsp"); %> </body> </html>
Context2.jsp代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h1>Context2.jsp页面</h1> pageContext : <%=pageContext.getAttribute("key") %><br/> request : <%=request.getAttribute("key") %><br/> session : <%=session.getAttribute("key") %><br/> application : <%=application.getAttribute("key") %><br/> </body> </html>
5. jsp中的out输出和response.getWriter输出的区别
在jsp页面中不管是先out输出,还是respose.getWriter()
客户端显示的输出结果都是先输出response.getWriter()再out输出
原因如下解析
在jsp页面中统一使用out进行输出,不用response。因为在 jsp翻译的源码中都是用out进行输出的javax.servlet.jsp.JspWriter out = null;
out.write 可以输出字符串
out.print 可以输出任意数据。
在jsp页面当中,我们可以使用out.print输出
6. jsp的常用标签
a) jsp静态包含
<%--
静态包含的斜杠表示到http://ip:port/工程名/ 也就是映射到WebContent目录
--%>
<%@ include file="/include/footer.jsp" %>
静态包含是把被包含的jsp页面的内容,原封不动的拷贝到静态包含的代码位置,进行输出。
静态包含,只会翻译大的jsp页面。被包含的jsp页面,不会被翻译
b) jsp标签-动态包含
<%--
动态包含的斜杠表示到http://ip:port/工程名/ 也就是映射到WebContent目录
--%>
<jsp:include page="/include/footer.jsp"></jsp:include>
动态包含是把全部的jsp页面,都翻译成为servlet程序。然后再通过代码(传递request对象,response对象,out对象给被包含的jsp页面使用)
注:request.getRequestDispatcher("/context2.jsp").forward(request, response)也是传递request对象和response对象,参数共享
源码_jspService()方法中:JspRuntimeLibrary.include(request, response, "/include/footer.jsp", out, false);
调用被包含的jsp页面的内容。
动态包含,还可以传递参数。
c) jsp标签-转发
<%-- 请求转发,功能跟request.getRequestDispatcher("/context2.jsp").forward(request, response); 一样 --%>
<jsp:forward page="/context2.jsp"></jsp:forward>
7. 静态包含和动态包含的区别
静态包含 |
动态包含 |
|
是否生成java文件 |
不会(只翻译自己) |
会(全部) |
service方法中的区别 |
是把被包含的jsp页面的内容原封不动的拷贝到被包含的位置输出 |
JspRuntimeLibrary.include |
是否可以传递参数 |
不能 |
可以 |
编译次数 |
1次 |
多次 |
适用范围 |
静态包含适用于包含那些jsp页面中,只有输出html页面数据的jsp |
动态包含适用于那些被包含的jsp页面中包含了大量的java代码,或者运行进来执行时候耗时比较长的jsp页面。 |
jsp页面在整个javaEE的框架中的定位,它的定位只是用来输出html页面数据。所以一般情况下。我们也就只使用静态包含。静态包含性能会比动态包含经微快。
例题:用jsp输出一个表格,里面有20个学生信息。
表格样式 <style type="text/css"> table{ width: 500px; border: 1px solid red; border-collapse: collapse; } th , td{ border: 1px solid red; } </style>
Student对象
public class Student { private int id; private String name; private String phone; private String sex; private int age; public Student(int id, String name, String phone, String sex, int age) { super(); this.id = id; this.name = name; this.phone = phone; this.sex = sex; this.age = age; }
SearchStudent程序中的代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 省略获取搜索关键字 // 省略到数据库中去查询 // 生for循环生成 数据库查询的结果 List<Student> stus = new ArrayList<Student>(); for (int i = 0; i < 10; i++) { stus.add(new Student(i,"name-" + i,"phone-" + i,(i%2==1?"男":"女"), 18+i)); } // 需要保存到request域对象中 request.setAttribute("stus", stus); // 转发到jsp页面 request.getRequestDispatcher("/showStudent.jsp").forward(request, response); }
jsp页面中的代码:
<%@page import="java.util.ArrayList"%> <%@page import="java.util.List"%> <%@page import="com.atguigu.pojo.Student"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <style type="text/css"> table{ width: 500px; border: 1px solid red; border-collapse: collapse; } th , td{ border: 1px solid red; } </style> </head> <body> <% List<Student> stus = (List<Student>) request.getAttribute("stus"); %> <table> <tr> <th>编号</th> <th>姓名</th> <th>电话</th> <th>性别</th> <th>年龄</th> <th>操作</th> </tr> <% for (int i = 0; i < stus.size(); i++) { %> <% Student s = stus.get(i); %> <tr> <td><%=s.getId() %></td> <td><%=s.getName() %></td> <td><%=s.getPhone() %></td> <td><%=s.getSex() %></td> <td><%=s.getAge() %></td> <td>删除,修改</td> </tr> <% } %> </table> </body> </html>