JavaWeb笔记
JSP
初步介绍
JSP全称为Java Server Pages,java的服务器页面,主要作用为替Servlet程序回传html页面的数据,因为Servlet程序回传html页面数据是一件非常繁琐的事情,开发成本和维护成本都很高
我们在使用Servlet程序回传html需要通过回传流需要一行一行地将html页面的数据传回,要会传完整一个html页面需要大量的代码使用write写入返回到客户端地浏览器
以下是一个代码示例,可见非常的繁琐
1 |
|
与此同时JSP可以很好的解决这个问题,代替了Servlet程序回传html页面的数据,注意JSP页面要通过服务器端进行解析,需要先运行Tomcat服务器后才可以显示动态生成出来,而不是像html一样可以直接通过本地的浏览器一样解析
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
JSP页面本质上是一个Servlet程序,当我们第一次访问JSP页面的时候,Tomcat服务器会帮我们将jsp页面翻译为一个java源文件,并且将其编译为class字节码程序
生成的Servlet继承自HttpJspBase,所以 JSP 本质上就是一个Servlet,生成的Servlet程序生成的html页面也是通过write输出流生成
1 | out.write("\r\n"); |
JSP page
jsp的page指令可以修改jsp页面中的一些重要属性或者行为
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
以下是一些常见的可以修改的属性
language 属性:表示jsp翻译后是什么语言文件,暂时只支持java
contentType 属性:表示jsp返回的数据类型是什么,也是源码中response.setContentType设置的编码类型(一般都是UTF-8)
pageEncoding 属性:表示当前jsp页面文件本身的字符集(一般都是UTF-8)
import 属性:和Java一致,导入包
1 | <%@ page import="java.util" %> |
autoFlush 属性:设置当out输出流缓冲区满了后,是否自动刷新缓冲区,默认为true
buffer 属性:设置out输出缓冲区大小,默认为8kb
errorPage 属性:设置当jsp页面运行出错的时候,会自动跳转的错误页面
isErrorPage 属性:设置当前jsp页面是否是错误信息页面,默认为false,如果是true可以获取异常信息
session 属性:设置访问当前jsp页面,是否会创建HttpSession对象,默认是true
extends 属性:设置jsp翻译出来的java类默认继承谁
JSP脚本
声明脚本
可以给JSP翻译出来的java类定义属性和方法,甚至是静态代码块和方法,定义的声明会生成到对应的Java源文件和class文件中
格式为
1 | <%! |
声明类属性
1 | <%! |
声明static静态代码块
1 | <%! |
声明类方法
1 | <%! |
声明内部类
1 | <%! |
表达式脚本
作用:在jsp页面上输出数据
格式
1 | <%=表达式%> |
1 | <%=12 %><br> |
输出内容
1 | JSP JSP JSP 12 |
特点
所有的表达式脚本都会被翻译到_jspService方法中
所有的表达式脚本都会被翻译成为out.print输出到页面上
由于表达式脚本翻译的内容都在_jspService方法中,所以jspService方法中的对象都可以直接使用
1 | <%=request.getParameter("name")%> |
http://localhost:8080/JSPTest/Test.jsp?name=1234
1 | 1234 |
表达式内容不可以 ; 结束
代码脚本
作用:可以在jsp页面中,编写我们自己需要的功能(java语句)
格式
1 | <% |
1 | <% |
代码脚本特点
1.代码脚本翻译之后都在_jspServive方法中
2.代码脚本中可以直接使用_jspService方法中的对象
3.代码脚本还可以由多个代码脚本块组合完成一个Java语句
1 | <% |
4.代码脚本还可以与表达式脚本组合使用在JSP页面打印
1 | <% |
当然也不建议这么使用,太过于混乱了,现在基本上都是直接使用框架了,这么些可维护性差
JSP注释
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
内置对象
JSP中的内置对象,指的是Tomcat在翻译JSP页面为Servlet源代码后,内部提供的九大对象称为内置对象
request:请求对象
response:响应对象
pageContext:jsp上下文对象
session:会话对象
application:ServletContext对象
config:ServletConfig对象
out:jsp输出流对象
page:指向当前jsp的对象
exception:异常对象(当页面异常isErrorPage开启时创建异常对象)
四个域对象
pageContext(PageContextImpl类)当前jsp页面范围内有效
request(HttpServletRequest类)一次请求内有效(请求转发不会丢失request数据)
session(HttpSession类)一个会话范围内有效(打开浏览器访问服务器,直到关闭浏览器)
application(ServletContext类)整个Web工程范围内都有效(Web停止后销毁)
域对象是可以像Map一样存取数据的对象,四个域对象的功能一样,不同的是特们对于数据的存取范围
我在这里遇到了pageContext无法解析set/getAttribute方法,应该是缺少 JSP API 依赖导致的
你的依赖中没有明确包含 jsp-api
这会导致 IDEA 无法解析 pageContext
的方法
添加如下的依赖配置即可
1 | <dependency> |
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
虽然都可以存取顺序,但是有使用优先顺序,最好在使用条件允许下使用小的范围
输出的细节
out与getWriter
response中表示响应,经常用于设置返回给客户端的内容(输出)
out也是给用户做输出使用
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
输出结果:我们发现response的write输出在标题的上边,和预期有些不符
- JSP 引擎先处理模板文本
<h1>JSP输出</h1>
- 遇到脚本片段时:
response.getWriter().write()
立即输出到客户端out.write()
写入缓冲区
- 最后 JSP 引擎刷新缓冲区,
out.write()
的内容才真正输出
一般在使用中统一使用out输出,避免打乱顺序
out.print与out.write
print会将内容逐个转为字符再通过write输出,而write输出整形数据会出现问题,会将内容转为字符串(并非单个字符转化)
所以在实际使用的时候输出数字用print完成(或者直接统一使用print)
常用标签
静态包含
有的时候我们将一个页面分为数个部分显示,为了保证页面的灵活性,我们可以将单个部分提取出来编写,方便随时替换或者修改
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
我们将页脚信息提取出来
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
使用jsp页面
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
静态包含的特点:不会翻译被包含的jsp页面,而是将被包含的jsp页面拷贝到包含的位置输出
动态包含
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
效果上和静态包含效果上差别不大,动态包含会把包含的jsp页面也翻译为java代码,动态包含底层调用了include方法调用被包含的页面进行输出(将被包含的页面的对象给包含页面进行使用)
工程上一般使用静态代码
请求转发
1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> |
Listener监听器
Listener监听器时JavaWeb的三大组件之一(Servler程序、Filter过滤器、Listener监听器)
是JavaEE的规范,即接口,作用为监听某种事物的变化,通过回调函数,反馈给客户(程序)做一些处理
ServletContextListener
可以监听ServletContext对象的创建和销毁(ServletContext对象在Web工程启动的时候创建,在Web工程停止的时候销毁)
监听到创建和销毁之后都会分别调用ServletContextListener监听器的方法反馈,这两个方法分别是contextInitialized和contextDestroyed,其中传入了ServletContextEvent对象
使用方式
1.编写一个类实现ServletContextListener
2.实现两个回调方法
3.配置web.xml监听器(配置注解@WebListener)
1 | package com.listener; |
这两天忙着准备面试+编译原理实验(最恶心的一个)+线性代数考试复习,暂时抽不出时间,等10号之后再开始EL表达式的学习