1 jsp
1 什么是jsp,他有什么作用?
jsp全称是java server pages,是java的服务器页面,jsp的主要作用是代替Servlet程序回传html页面,因为Servlet程序回传html页面数据是一个非常繁琐的事情,开发成本和维护成本都非常的高。servlet的方式实现回传界面:十分的繁琐。
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
writer.write("hello,world");
writer.write("<!DOCTYPE html>\r\n");
writer.write("<html lang=\"en\">\r\n");
writer.write("<head>\r\n");
writer.write("<meta charset=\"UTF-8\">\r\n");
writer.write("<title>hello</title>\r\n");
writer.write("</head>\r\n");
writer.write("<body>\r\n");
writer.write("你好,jsp。\r\n");
writer.write("</body>\r\n");
writer.write("</html>\r\n");
writer.write("\r\n");
}
2 jsp如何访问
jsp页面和html页面一样,都是存放在web目录下,访问地址也跟HTML页面一致。
web目录下
- a.html页面: http://localhost:8080/工程目录/a.html
- b.jsp页面: http://localhost:8080/工程目录/b.jsp
3 jsp页面的本质是什么?
jsp本质上是一个Servlet程序。tomcat启动的时候会得到以下信息。
通过访问CATALINA_BASE文件夹,访问jsp翻译后的java文件,会发现实际上是继承了HttpJspBase,表明jsp翻译出的java类,间接的继承了HttpServlet类。如下所示
实际上进入HttpServlet也会发现,注释写道:该类为所有jsp页面的超类。
4 jsp的三种语法
1 jsp头部的page指令
jsp头部的page指令可以修改jsp页面中的一些重要的属性或者行为。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
- language:表示jsp翻译之后是什么类型的语言,目前只支持java。
- contentType:表示jsp返回的数据类型是什么,也是源码中response中ContentType的属性值。
- 指定响应文件的格式。
- 指定浏览器的解码的编码集。
- 响应输出流的编码集。
- pageEncoding:表示当前jsp页面文件本身的编码类型。
- import:用于导包,和java中保持一致。
- autoFLush:是给out输出流使用的。当out缓冲区满了之后,是否自动刷新缓冲区,默认是true。不建议修改。
- buffer:是给out输出流使用的,输出流缓冲流的大小值,默认为8kb。缓冲区满了之后不刷新会报错:缓冲区溢出。不建议修改。
- errorPage:当前jsp页面运行时出错,自动跳转到的页面地址。相当于设置一个友好的页面。/开头,映射到的路径为web下。
- errorPage和isErrorPage配合使用。
- isErrorPage:表明当前是错误页面,默认是false,如果是true则可以获取异常信息,编译后的源文件就是存在一个异常类的对象。和errorPage配合使用。
- session:设置访问当前jsp页面会创建HttpSession对象,默认为true。
- extends:设置jsp翻译出来的java类默认继承谁。默认为HttpJspBase,一般不推荐修改。
2 jsp常见脚本
1)声明脚本==>很少使用
-
格式:<%!声明java代码 %>
-
作用:可以给jsp翻译出来的java类定义属性和方法甚至是静态代码块,内部类等。
<%--1.声明类的属性--%>
<%!
private Integer id;
private String name;
private static Map<String,Object> map;
%>
<%--2.声明static静态代码块--%>
<%!
static {
map=new HashMap<>();
map.put("key1","value1");
map.put("key2","value2");
map.put("key3","value3");
map.put("key4","value4");
}
%>
<%--3.定义方法--%>
<%!
public Object get(String key){
return map.get(key);
}
%>
<%--声明内部类--%>
<%!
public static class A{
private Integer id=2;
private String name="张三";
}
%>
2)表达式脚本==>常用
-
格式:<%=表达式%>
-
作用:在jsp页面上输出数据。
特点:
-
所有的表达式脚本都会被翻译到_jspService中。
-
所有的表达式脚本都会被out.print()输出到页面上。
-
表达式脚本翻译的内容都在_jspService()方法中,所以_jspService中存在的对象都可以使用。
-
表达式脚本中的代码不能以";"结尾。
<%--
表达式脚本
1.输出整形
2.输出浮点型
3.输出字符串
4.输出对象
--%>
<%=12%><br />
<%=12.5%><br />
<%="字符串"%><br/>
<%=map%><br />
<%=request.getParameter("username")%>>
你好,这里是jsp页面<br/>
<br/>
3)代码脚本
-
格式:<% java语句 %>
-
作用:可以在jsp页面中编写自己需要的功能,基本上写的是java语句。
特点:
-
①所有的代码脚本都会被翻译到_jspService中。
-
②代码脚本翻译的内容都在_jspService()方法中,所以_jspService中的对象都可以使用。
-
③代码脚本还可以由多个代码脚本块组合完成一个java语句。
-
④还可以和表达式脚本(EL表达式)配合使用。
<%
int i=13;
if (i==12){
%>
<%="龙哥帅气!!!"%>
<%
}else {
%>
<%= "龙哥骗人!!!"%>
<%
}
%>
<%
for (int j = 0; j < 5; j++) {
//此时输出是输出到控制台中去
System.out.println("龙哥真帅!!!"+(j+1));
}
%>
4)JSP中的三种注释
- :被翻译到java源代码中,在_jspService中以out.writer输出到客户端。
- <%-- 这是jsp注释 --%>:可3以注释掉一切jsp中的代码。
- //或者/* */:java注释,写在代码脚本中,会被翻译到java的源代码中
5 jsp中的九大内置对象
内置对象:jsp翻译为Servlet源码之后,提供的九个对象,称之为九大内置对象。
- request:请求对象
- response:响应对象
- pageContext:page上下文对象
- 域对象:
- 全域搜索:
- 代理其他域:
- 获取其他八大内置对象:
- session:会话对象
- application:ServletContext对象
- config:ServletConfig对象
- out:jspWriter对象
- page:指的是当前jsp对象,是Object类的对象,值是当前这个jsp对象。
- exception:异常对象,只有isErrorPage=true时才存在
6 jsp的四大域对象
域对象 | 作用域 |
---|---|
pageContext:PageContextImpl | 当前jsp页面内有效 |
request:HttpServletRequest | 一次请求内有效 |
session:HttpServlet | 一个会话的范围(浏览器的开启关闭) |
application:ServletContext | 整个web工程生命周期内都有效 |
使用:虽然都可以存储数据,但是使用的时候存在优先顺序,推荐由小范围到大范围。当不需要使用的时候就会进行内存的释放,越小的域对象,越早可能被释放。
7 out和respense.getWriter输出的区别?
-
response中表示响应,我们经常用于设置返回给客户端的内容(输出)
-
out也是给用户作输出使用的。
<%
out.write("out输出1<br />");
out.flush();
out.write("out输出2<br />");
response.getWriter().write("response输出1<br />");
response.getWriter().write("response输出2<br />");
%>
输出显示:
out输出1
response输出1
response输出2
out输出2
1)由于jsp翻译之后,底层源代码都使用writer来进行输出,所以一般情况下,我们都使用out进行输出,避免输出顺序被打乱。
2)对于out来说,输出存在两个方法:
-
print:输出所有数据都没有问题,输出其他类型的时候底层会转化为字符串,然后调用writer()。
-
writer:输出字符串没有问题。底层存在一个char型数组,无论传入的参数是什么类型都会转化为char型并让char数组指向它,如果存入的是整形之类的数据就会出错。
8 jsp中常见的标签
1 jsp静态包含(常用)
- 格式:<%@include file="/include/footer.jsp"%>
特点:
- 静态包含不会翻译被包含的jsp页面。
- 静态包含会被翻译到主体页面的.class文件中,在包含的位置执行输出。
- 可以共享四大域对象
2 jsp动态包含(少用)
格式:
<jsp:include page="/include/footer.jsp">
<jsp:param name="name" value="zhangsan"/>
</jsp:include>
特点:
- 会将被包含的页面也翻译为java代码。
- 底层使用如下代码去调用被包含的jsp页面执行输出。
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, “/include/footer.jsp”, out, false);
- 动态包含可以添加参数,会共享主页面的域对象,除了pageContext。
总结:静态包含和动态包含的区别:a.jsp包含b.jsp
-
使用的标签不同:
- 静态包含:<%@include file="/include/footer.jsp"%>
- 动态包含:<jsp:include page="/include/footer.jsp">。
-
是否生成servlet
- 静态包含:b页面不会生成单独的servlet。
- 动态包含:会生成两个servlet。
-
合并的时期不同
- 静态包含:两个jsp的代码合并为整体,被tomcat解析为一个servlet,一个servlet只对应一个servlet。
- 动态包含:两个jsp对应两个servlet,两个servlet两个servlet工程组成一个页面。
-
包含的名字是否可以是变量
- 静态包含:名字不能是变量,在jsp时期就需要被确定。
- 动态包含:名字可以是变量。
-
是否可以共享域对象
- 静态包含:四大域对象都可以共享。
- 动态包含:可以共享request,application,session域对象。
3 请求转发
格式:
- <jsp:forward page=“score2.jsp”></ jsp:forward>
- 使用和response没有什么不同。
4 useBean
<!-- 创建一个对象,将其放置到request域中 -->
<jsp:useBean id="student1" class="com.zhiyou.bean.Student" scope="request">
<!-- 给对象的属性进行赋值 -->
<jsp:setProperty property="sname" name="student1" value="韩梅梅"/>
<!-- 获取对象中指定的属性的值 -->
<jsp:getProperty property="sname" name="student1"/>
</jsp:useBean>
9 jsp页面的练习题
1)在jsp页面中输出九九乘法表。
<h2 >99乘法表</h2>
<%
for (int i = 1; i < 10; i++) {
for (int j = 1; j <= i; j++) {
out.print(j+"*"+i+"="+(i*j));
out.print("    ");
}
out.print("<br/>");
}
%>
<hr/><hr/>
<table>
<%for (int i = 1; i < 10; i++) {%>
<tr>
<%for (int j = 1; j <= i; j++) {%>
<td style="border: solid grey 1px">
<%=j%>*<%=i%>=<%=j*i%>
<td>
<%}%>
<%}%>
</tr>
</table>
2)jsp输出一个表格,里面有10个学生的信息。
<%
ArrayList<Student> students = new ArrayList<>();
for (int i = 0; i < 10; i++) {
students.add(new Student("id"+i,"name"+i,"phone"+i));
}
%>
<h2>学生信息表</h2>
<table >
<tr >
<td>id</td>
<td>名字</td>
<td>电话</td>
</tr>
<%
for (int i = 0; i < students.size(); i++) {
out.write("<tr>");
out.write("<td style=\"border: grey 1px solid\">" +
students.get(i).getId()+"</td>");
out.write("<td style=\"border: grey 1px solid\">" +
students.get(i).getName()+"</td>");
out.write("<td style=\"border: grey 1px solid\">" +
students.get(i).getPhone()+"</td>");
out.write("</tr>");
}
%>
</table>
10.Listener监听器
1)什么是Listener监听器?
-
是javaWeb的三大组件之一。
-
他是javaEE的规范,就是接口。
-
作用:监听某件事物的变化,通过回调函数,反馈给客户(程序)去做一些相应的处理。
2)ServletContextListen监听器
作用:来监听ServletContext对象的创建和销毁。监听到创建和销毁后会分别调用里面的两个方法
public interface ServletContextListener extends EventListener {
//ServletContext对象创建的时候马上调用,进行初始化==>web被部署或者启动的时候。
void contextInitialized(ServletContextEvent var1);
//ServletContext对象销毁后马上调用==>web工程关闭的时候。
void contextDestroyed(ServletContextEvent var1);
}
使用步骤:
1) 编写一个类实现来接口:ServletContextListener
2)实现其中的方法:
3)web.xml中配置监听器
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext对象被创建了!!!");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext对象被销毁了!!!");
}
}
//xml中配置
<listener>
<listener-class>com.atguigu.listener.MyListener</listener-class>
</listener>