JSP是运行在服务端的语言
实际上是被tomcat编译成serlvet程序
1.JSP脚本
声明脚本(声明类属性,static代码块,类方法,内部类):<%! java声明代码 %>
表达式脚本(在jsp页面输出数据):<%= 表达式 %>
所有的表达式都会被翻译到_jspService()方法中,本质还是用out.print()输出到页面
代码脚本(在jsp页面编写需要的功能):<% java语句 %>
因为会被翻译到_jspService()中,所以可以使用_jspService()的对象request,response。
2.JSP四大域对象
分别是:
pageContext (PageContextImpl类) 当前jsp页面有效
request (HttpServletRequest类) 一次请求有效
session (HttpSession类) 一次会话范围有效(会话:打开浏览器访问服务器)
application (ServletContext类) 整个web工程内有效
3.在JSP页面中一般使用out.print()输出,因为其原理是将参数转为阿斯克码再调用out.write()按字符输出
4.JSP 包含指令
静态包含:不会翻译被包含的jsp页面,其实是将被包含的页面代码拷贝执行
<%@ include /相对地址 %> :包含其他文件(JSP页面)
(/代表http://ip:port/工程路径/ ,映射web目录)
动态包含:<jsp:include page=""></jsp:include>
翻译被包含的jsp页面为java代码
5.👌JSP的使用
客户端请求->servlet处理请求参数,通过Dao查询结果,保存在request域对象中->请求转发到jsp页面,jsp页面输出数据。
6.Listener监听器
作用:监听某事物变化,通过回调函数反馈给客户(程序)做处理
ServletContextListener监听器(监听ServletContext对象创建和销毁)
ServletContext对象在web工程启动时创建,停止时销毁
使用步骤:
1.编写一个类实现ServletContextListener(接口)
2.实现两个回调方法
3.到web.xml配置监听器
<listener>
<listener-class>
包名类名
</listener-class>
</listener>
-------------------------------------------------------------------------------
7.EL表达式
作用:代替JSP页面表达式脚本进行输出
EL表达式格式:${表达式}
表达式值出null时,输出空串
❗主要用于jsp页面输出域对象:按照四个域的从小到大顺序搜索,找到就输出。
EL表达式输出bean对象:
pageContext.setAttribute(“key”,对象a);
${a.属性b} (找到属性b的get方法)
8.EL表达式11个隐含对象
对象 | 类 | 作用 |
---|---|---|
pageContext | PageContextImpl | 获取jsp九大内置对象 |
pageScope | Map<String,Object> | 获取pageContext的域对象 |
requestScope | Map<String,Object> | 获取Request的域对象 |
sessionScope | Map<String,Object> | 获取Session的域对象 |
applicationScope | Map<String,Object> | 获取ServletContext的域对象 |
param | Map<String,String> | 获取请求参数 |
paramValues | Map<String,String[]> | 获取多个请求参数 |
header | Map<String,String> | 获取请求头信息 |
headerValues | Map<String,String[]> | 获取多个请求头信息 |
cookie | Map<String,Cookie> | 获取当前请求Cookie信息 |
initParam | Map<String,String> | 获取web.xml配置的上下文参数 |
9.pageContext对象使用(EL表达式实际上是调用了属性的get方法)
请求的获取协议:
p
a
g
e
C
o
n
t
e
x
t
.
r
e
q
u
e
s
t
.
s
c
h
e
m
e
请
求
的
服
务
器
i
p
:
{pageContext.request.scheme} 请求的服务器ip:
pageContext.request.scheme请求的服务器ip:{pageContext.request.serverName}
请求的服务器端口:
p
a
g
e
C
o
n
t
e
x
t
.
r
e
q
u
e
s
t
.
s
e
r
v
e
r
P
o
r
t
工
程
路
径
:
{pageContext.request.serverPort} 工程路径:
pageContext.request.serverPort工程路径:{pageContext.request.contextPath}
请求方式:
p
a
g
e
C
o
n
t
e
x
t
.
r
e
q
u
e
s
t
.
m
e
t
h
o
d
客
户
端
i
p
:
{pageContext.request.method} 客户端ip:
pageContext.request.method客户端ip:{pageContext.request.remoteHost}
会话id:${pageContext.session.id}
10.当key值的属性内包含特殊字符(-,+)使用键语法:
例如 ${header[“User-Agent”]}
-------------------------------------------------------------------------------
11.JSTL标签库
为了替代JSP代码脚本
使用步骤:
(1)导入jar包
(2)使用taglib标签引入标签库(core核心库):
<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>
(3)core核心库使用:
✏<c:set scope=“page” var="" value=""/>
set标签往域中保存数据,scope代表哪个域对象(page代表pageContext),var代表key值,value代表value值
✏<c:if test="${表达式}"}>表达式为true时输出</c:if>
if标签来做判断
✏
<c:choose>
<c:when test="${表达式1}">结果1 </c:when>
<c:when test="${表达式2}"> 结果2</c:when>
<c:otherwise>剩下的情况的结果</c:otherwise>
</c:choose>
用来做多路判断,类似java的switch case语句,标签内必须使用jsp注释
✏<c:forEach>
进行遍历
-------------------------------------------------------------------------------
12.文件上传与文件下载
文件上传:
(1)需要form标签,method=post
(2)form标签的encType属性值必须为multipart/form-data(多段的形式拼接,以流的方式提交)
(3)在form标签使用input=file添加上传的文件
(4)编写服务器代码接收,处理上传的文件
(5)servlet程序接收文件需要使用流来接收
🔧 导入commons-fileupload与commons-io的jar包
😀方法:ServletFileUpload类
📌ServletFileUpload.isMultipartContent(HttpServletRequest request)
//判断请求是否是多段格式
📌public List parseRequest(HttpServletRequest request)
//解析表单中的每一个表单项,封装成FileItem对象,以List方式返回
📎FileItem.isFormField()//判断是否是普通表单项
FileItem.getFieldName()//得到表单项的name属性值
FileItem.getString()//获取当前表单项的值
📎
FileItem.getName()//获取上传文件名
FileItem.write(file)//将上传的文件写道file指向的硬盘位置
💻servlet接收文件代码演示(HttpServlet类内的doPost方法)
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("接收到请求了");
if( ServletFileUpload.isMultipartContent(request)){
FileItemFactory fileItemFactory=new DiskFileItemFactory();
ServletFileUpload servletFileUpload=new ServletFileUpload(fileItemFactory);
try {
List<FileItem> list=servletFileUpload.parseRequest(request);
for(FileItem fileItem:list){
if(fileItem.isFormField()){
System.out.println("普通表单项名字"+fileItem.getFieldName());
System.out.println("表单项的值"+fileItem.getString("UTF-8"));
}else{
System.out.println("文件表单项名字"+fileItem.getFieldName());
System.out.println("文件名"+fileItem.getName());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
文件下载:
💻代码加注释演示
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.获取要下载的文件名,该文件放在工程的web目录下
String downloadFileName = "BMW.jpg";
// 2.servletContext读取下载文件内容,this.getServletContext()获取上下文对象
ServletContext servletContext = getServletContext();
// 3.获得文件类型,通过响应头告诉客户端返回的数据类型,/在服务被解析为 http://ip:端口号/工程名字映射到idea的web工程的web目录
String mimeType=servletContext.getMimeType("/"+downloadFileName);
System.out.println(mimeType);
response.setContentType(mimeType);
// 4.告诉客户端收到的数据用于下载(响应头),attachment表示附件,下载使用,filename表示下载的文件名,如果是中文,谷歌会乱码,可以使用:URLEncoder.encode("宝马M4.jpg","UTF-8")
response.setHeader("Content-Disposition","attachment;filename="+downloadFileName);
// 通过输入流得到资源
InputStream resourceAsStream = servletContext.getResourceAsStream("/"+downloadFileName);
// 获取输出流
OutputStream outputStream = response.getOutputStream();
// 读取输入流的全部数据,复制给输出流。输出给客户端
IOUtils.copy(resourceAsStream,outputStream);
}