jsp
Posted petewell
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jsp相关的知识,希望对你有一定的参考价值。
原文引用https://www.dazhuanlan.com/2019/08/25/5d622c29a0f91/
jsp的简介
servlet中输出一个html页面很繁琐:
1 |
PrintWriter out = response.getWriter(); |
jsp脚本和注释
-
jsp脚本:
- <%java代码%>
不带!,jsp页面被翻译成java页面后,不带!的jsp脚本会被翻译到service方法中 - <%=java变量或表达式%>—->在页面输出
会被翻译成service方法的内部out.print()表达式:1+1
- <!%java代码%>
带!,jsp页面被翻译成java页面后,带!的jsp脚本会被翻译到service方法外面(成员变量),所以这个里面可以写方法,而不带!的不能写方法,因为方法中不能嵌方法
- <%java代码%>
-
注释:不同的注释可见范围不同
- html注释:
<!--注释内容-->
可见范围:jsp源码,翻译后的servlet,页面显示的html源码 - java注释:
//单行注释 /*多行注释*/
可见范围:jsp源码,翻译后的servlet - jsp注释:
<%--注释内容--%>
可见范围:jsp源码
- html注释:
-
jsp运行原理—–jsp本质就是servlet
jsp在第一次被访问时会被Web容器翻译成servlet,再执行。
过程:第一次访问—–>helloServlet.jsp——>helloServlet_jsp.java——->编译运行
ps:被翻译后的servlet在Tomcat的work目录中可以找到
-
jsp的命令(3个)
jsp的命令是指导jsp翻译和运行的命令,jsp包括三大命令:-
page命令—属性最多的命令(实际开发中page命令默认,我们不用写)
属性最多的一个命令,根据不同的属性,指导整个页面特性
格式:<%@ page 属性名1=”属性值1” 属性名2=”属性值2”…%>
常用属性如下:language:jsp脚本中可以嵌入的语言种类
pageEncoding:当前jsp文档本身的编码
contentType:response.setContentType(“text/html;charset=utf-8”);
import:导入java的包
errorPage:当前页面出错后跳转到哪个页面
isErrorPage:当前页面是一个处理错误的页面
session:是否jsp在翻译时自动创建session
buffer:out缓冲区的大小,通过out.write()输出的数据会先放入out缓冲区,输出时再放到response缓冲区,默认大小8kb,设置为0kb的话等于关闭了,输出数据就会直接放入response缓冲区了,response缓冲区是不能关闭的。
1
<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isErrorPage="true" errorPage="/error.jsp" buffer="8kb"%>
注意:errorPage只能配置500的错误,404不行,因为404连该页面都找不到,如果要404的错误页面的话,可以再web.xml中配置web应用的全局的错误页面
1
2
3
4<error-page>
<error-code>404</error-code>
<location>/error.jsp</location>
</error-page> -
include命令
页面包含(静态包含)命令,可以将一个jsp页面包含到另一个jsp页面中
格式:<%@ include file=”被包含的jsp地址”%> -
taglib命令
在jsp页面中引入标签库(jstl标签库、struts2标签库)
格式:<%@ taglib uri=”标签库地址” prefix=”前缀”%>
-
jsp内置/隐式对象(9个)——-笔试面试题
- 是什么?
就是<%…%>中可以直接使用的对象。
jsp被翻译成servlet之后,<%…%>中的代码会被放在service方法中,然而service方法外面,也就是成员变量已经定义并初始化完毕了这9个对象,所以我们在jsp脚本中可以直接使用这9个对象
名称 | 类型 | 描述 |
---|---|---|
out | javax.servlet.jsp.JspWriter | 用于页面输出 |
request | javax.servlet.http.HttpServletRequest | 得到用户请求信息 |
response | javax.servlet.http.HttpServletResponse | 服务器向客户端的回应信息 |
config | javax.servlet.ServletConfig | 服务器配置,可以取得初始化参数 |
session | javax.servlet.http.HttpSession | 用来保存用户的信息 |
application | javax.servlet.ServletContext | 所有用户的共享信息 |
page | java.lang.Object | 指当前页面转换后的Servlet类的实例 |
pageContext | javax.servlet.jsp.PageContext | JSP的页面容器 |
exception | java.lang.Throwable | 表示JSP页面所发生的异常,在错误页中才起作用 |
提醒:
config属于ServletConfig类型,之前servlet中说过,他有三个作用,获取servletname,获取servlet初始化参数,获得ServletContext对象。
exception对象只有在page命令中添加了isErrorPage属性值为true的jsp页面翻译后的java文档中定义了该对象,用来接收错误信息的,因为只有发生错误跳转到错误页面才能有错误对象及信息。
- 怎么记住9个隐式对象?
service方法中的形参就有request和response
域对象这里除去request和response外有ServletContext类型对应的application,还有session,还有pageContext
config(ServletConfig类型的配置信息),out(页面输出的),exception(错误页面的异常对象),page(当前页面翻译成servlet后的实例)
- out对象
out的类型:JspWriter(什么Writer不重要,重要的是Writer)
out作用就是向客户端输出内容——–out.write()
out缓冲区默认8kb,可以设置成0,代表关闭out缓冲区,内容直接写到response缓冲区
向页面输出的几种方式
1 |
<body> |
页面输出结果
1 |
顺序是ccc aaa bbb ddd |
上面几种方式,被翻译成servlet后aaa和ddd都被翻译成out.write()输出,bbb是手动写的out.write(),这几个输出方式是一样的,通过out输出的会将数据放到out缓冲区,response的会放到response缓冲区,然后out缓冲区中的数据再被放到response缓冲区中,然后tomcat默认从response缓冲区中拿数据。所以先输出response中原有的,再输出从out缓冲区中后放入的,如果在page命令中设置了buffer为0kb,那么out输出的数据就不会进入out缓冲区,直接进入response,所以会按照从上到下的顺序有序的输出aaa bbb ccc ddd
- pageContext
代表的是当前页的一个上下文,不和page一样,page代表的是当前页的这个对象(翻译后的servlet对象),pageContext封装的是当前页的其他信息。
jsp页面的上下文对象,作用如下:
- pageContext是一个域对象(作用范围当前页,所以也可以定义变量而不用该域对象,这个不是主要)
setAttribute(String name,Object obj)
getAttribute(String name)
removeAttribute(String name)
pageContext可以向指定的其他域中存取数据(主要):
可能觉得没什么用,因为我们直接就可以往想要的域中存取,没必要通过pageContext对象,但是如果有一个方法参数是pageContext,request,session,application这四个域对象呢?,传四个觉得太多,我们可以传一个pageContext全解决了。
setAttribute(String name,Object obj,int scope)
getAttribute(String name,int scope)
removeAttribute(String name,int scope)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<%
//使用pageContext向request域存数据
request.setAttribute("name","zhangsan");
//以下这个方法一样效果
pageContext.setAttribute("name","lisi",PageContext.REQUEST_SCOPE);
pageContext.setAttribute("name","sunba");
pageContext.setAttribute("name","lisi",PageContext.SESSION_SCOPE);
pageContext.setAttribute("name","lisi",PageContext.APPLICATION_SCOPE);
%>
<%=request.getAttribute("name")%>
<%=pageContext.getAttribute("name",PageContext.REQUEST_SCOPE)%>
<!-- findAttribute会从小到大搜索域的范围中的name -->
<!-- 习惯叫pageContext域为page域 -->
<!-- page域<request域<session域<application域 -->
<%=pageContext.fingAttribute("name")%>
findAttribute(String name)
—依次从pageContext域,request域,session域,application域中获取属性,在某个域中获取后将不在向后寻找
- 可以获得其他8大隐式对象
例如:
pageContext.getRequest()
pageContext.getSession()
作用和前面一样,只传一个pageContext就可以获得其他的隐式对象
关于四种域对象的总结
jsp的四个域对象的作用范围
page域(pageContext):只能作用于当前jsp页面,既不能用来做做转发的数据分享,也不能做重定向的数据分享
request域:只能作用于同一个请求的数据共享,所以只能在请求的转发中使用
session域:只能作用于一次对话中共享数据(一次对话:用户打开浏览器,浏览多个web站点后,关闭该浏览器),转发和重定向都可以使用
application域(ServletContext):只能在同一个web应用中使用。(全局的)
jsp的标签(动作)
- 页面包含(动态包含):
<jsp:include page="被包含的页面"/>
1 |
<body> |
静态与动态包含区别:
动态:先编译运行,再组合,结果有两个编译文档,如果jsp1中的对象引入是在jsp2中写的,使用jsp1动态包含jsp2会报错,因为是单独编译的,先编译jsp1的时候对象的类引入是在jsp2中写的,此时编译不到所以导致jsp1中的对象不存在报错。
静态:是编译前将jsp2的代码放进jsp1,再编译jsp1文档,结果只有一个编译文档,这样就解决的动态包含的那个对象出错问题。
- 请求转发:
<jsp:forword page="要转发的资源"/>
<jsp:forword page="/forward2.jsp"></jsp:forward>
以上是关于jsp的主要内容,如果未能解决你的问题,请参考以下文章
JSP运行过程 JSP脚本 静态动态包含 jsp指令 jsp内置对象jsp四大作用域 jsp动作元素 EL表达式 JSTL 设计模式 JSP开发模式 EL内置对象