JSP(java Server Page)
简介
因为Servlet中用来做页面需要疯狂的拼接字符,为了解决在service中响应页面的问题,使用JSP技术来实现更为合适
- Servlet中的写法:
xml
resp.setCharacterEncoding("UTF-8");
PrintWriter printWriter = resp.getWriter();
printWriter.println("<!DOCTYPE html>\n" +
"<html lang="en">\n" +
"<head>\n" +
" <meta charset="UTF-8">\n" +
" <title>登录</title>\n" +
"</head>\n" +
"<body>\n" +
"欢迎使用\n" +
"</body>\n" +
"</html>");
JSP和Servlet区别
- JSP底层就是一个Servlet,在执行的时候先转成Servlet然后同样要经历Servlet的生命周期;
- 如果想把页面做好看一些,怎么做?很明显Servlet是不行的,所以需要用到JSP(看上去就跟HTML页面差不多),Servlet主要是处理业务为主(Java后台代码),JSP主要以表现为主(HTML,CSS,JS等前端代码);
- Servlet更擅长逻辑的编写,Jsp更擅长于数据的显示,以后我们开发会慢慢达到一个目标,servlet里面不要写HTML代码,jsp里面不要写java代码;
入门
- 创建一个javaWeb项目
- 创建JSP文件
- 启动tomacat测试
JSP原理
语法
语法用于在JSP页面使用java代码 语法分类:
<%Java语法%>
<%=%>
<%!%>
erlang
<%--原封不动的进行转换--%>
`<%Java语法%>`
<%String name="嘿哟";%>
<%--向页面输出值--%>
`<%=%>`
<%=name%>
<%--成员变量--%>
<%!%>
<%!int age =18;%>
注意
- 如果没有导入jsp的jar包,页面会报错,但是不影响运行(tomcat -- lib -- jsp.ar);
- 不能直接拖到浏览器上面运行,它只能在服务器上面(JSP是服务器端页面)使用,服务器对它作了编译的。如下图直接运行时显示的是源码,并不是页面效果:
JSP三大指令
- page
当前页指令,只对当前页作
eg:如果当前head.jsp页面报错,需要给客户转到hello.jsp页面,只需要在Page指令后面加errorPage
属性,然后在hello.jsp页面的Page指令里面加属性isErrorPage
并设值为true
ini
head.jsp页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="hello.jsp" %>
ini
hello.jsp页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
- include
静态引入
;
不同的页面包含相同的内容,可以把相同的页面提取出来进行引用,比如导航栏head.jsp是a.jsp页面和b.jsp页面共有的,就可以对head.jsp页面进行引用
ini
页面a和页面b都使用这句代码引用head.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
先引入head代码,然后同意转换成一个.java文件
<%@include file="head.jsp"%>>
- taglib:标签指令(JSTL);
内置对象
JSP转换成java代码的时候自动生成的对象代码
内置对象 | 类 | |
---|---|---|
application | ServletContext | 全局对象 |
session | HttpSession | 会话对象 |
request | HttpServletRequest | 请求对象 |
pageContext | PageContext | 当前页对象 |
response | HttpServletResponse | 响应对象 |
out | JspWriter | 输出对象 |
page | this | 当前对象 |
config | ServletConfig | 配置对象 |
exception | 异常对象 |
四大作用域对象 存取数据
类 | 对象(叫法) | 范围 |
---|---|---|
PageContext | pageContext | 当前页面(作用不大) 当前页,直接使用就是,根本不需要在放到对象里面 |
HttpServletRequest | request | 一次请求(必需请求转发) |
HttpSession | session | 一次会话 |
ServletContext | application | 整个应用(有且只有一个对象) |
在Servlet中的操作
- 一次session包含多次Request,session就像打电话,而Request只是其中一个话题
注意:
不能跨域取值
arduino
//获取数据
<%request.setAttribute("name","王子文");%>
//打印数据
<%=request.getAttribute("name")%>
<%=session.getAttribute("name")%>
<%=application.getAttribute("name")%>
如上,只能读取Request域的值,其他域因为没有赋值就不能读取,显示``NULL`
- 在自己写的类中使用内置对象 先使用
Request.get作用域的类
,拿到对象再使用
ini
HttpSession session = request.getSession();
ServletContext application = request.getServletContext();
- 获取Servletcontext的方式
ini
//兼容性差
ServletContext application1 = request.getServletContext();
//麻烦,但兼容性好
HttpSession session = request.getSession();
ServletContext application2 = session.getServletContext();
//从父类中继承,兼容性好
ServletContext application3 = super.getServletContext();
ServletContext application4 = super.getServletConfig().getServletContext();
JSP动作元素
在body里面写,语法
ini
<jsp:include page="相同的.jsp"></jsp:include>
静态引入和动态引入的区别
- 动态引入指的是标签jsp:include,静态引入指的是指令include
- 静态引入是先把页面包含进来再翻译成一个java代码,动态引入是先大欧编译成java代码,再将内容进行包含
- 如果是静态页面(HTML),就适合用静态引入include;如果是动态引入(jsp),就用jsp:include;
EL表达式
EL可以获取四大作用域中的共享数据,获取到值就直接打印输出,没有获取不会输出NULL值,而是直接跳过
perl
<%request.setAttribute("age",18);%>
<%=request.getAttribute("age")%>
${name}
${age}
具体使用
之前我们用jsp的表达式从作用域里面拿到值,并且判断为空,为了防止出现显示为NULL的写法
vbscript
<%=request.getAttribute("msg")==null?"":request.getAttribute("msg")%>
EL可以替代之前的部分写法,如:
lua
<%--原写法--%>
<%=request.getAttribute("msg")==null?"":request.getAttribute("msg")%>
<%--EL写法--%>
${msg}
<form action="/login" method="post">
账号:<input type="text" name="userName"><br>
密码:<input type="password" name="pwd"><br>
<input type="submit" value="登录">
不同域中取值
不同域中有相同的名字
,取值过程是作用域从小到大,为了让他们显示全,需要在值前面加上指定作用域,最小的作用域不用添加指定作用域(不然会页面错误)
perl
<%pageContext.setAttribute("age",15);%>
<%request.setAttribute("age",16);%>
<%session.setAttribute("age",17);%>
<%application.setAttribute("age",18);%>
${age}
${requestScope.age}
${sessionScope.age}
${applicationScope.age}
EL的其他作用
-
EL算术运算符
(1) <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 + 2 {1+2} </math>1+2{2-1} <math xmlns="http://www.w3.org/1998/Math/MathML"> 2 ∗ 3 {2*3} </math>2∗3{16/5}
-
EL关系运算符
(1) <math xmlns="http://www.w3.org/1998/Math/MathML"> 16 > 5 或 {16>5} 或 </math>16>5或{16 gt 5}
(2) <math xmlns="http://www.w3.org/1998/Math/MathML"> 16 < 5 或 {16<5} 或 </math>16<5或{16 lt 5}
(3) <math xmlns="http://www.w3.org/1998/Math/MathML"> 16 > = 5 或 {16>=5} 或 </math>16>=5或{16 ge 5}
(4) <math xmlns="http://www.w3.org/1998/Math/MathML"> 16 < = 5 或 {16<=5} 或 </math>16<=5或{16 le 5}
(5) <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 = = 2 或 {1==2} 或 </math>1==2或{1 eq 2}
(6) <math xmlns="http://www.w3.org/1998/Math/MathML"> 2 ! = 1 或 {2!=1} 或 </math>2!=1或{2 ne 1}
-
EL逻辑运算符
(1) ${true && true}:结果 true
(2) ${true and true}:结果true
(3) <math xmlns="http://www.w3.org/1998/Math/MathML"> t r u e ∣ ∣ f a l s e {true || false} </math>true∣∣false{true or false}:结果 true
(4) <math xmlns="http://www.w3.org/1998/Math/MathML"> ! t r u e 或 {!true} 或 </math>!true或{not true}:结果false
-
EL其他运算符
(1) ${empty param.name} :如果param.name 为空返回true否则false
-
EL三目运算符
(1) <math xmlns="http://www.w3.org/1998/Math/MathML"> A ? B : C ,比如: {A?B:C},比如: </math>A?B:C,比如:{user.sex?"男":"女"}
注意事项
特殊的写法:session.setAttribute("KEY.IN.SESSION", "你是session")
错误写法:${sessionScope.KEY.IN.SESSION}
代码如下:
正确写法:${sessionScope["KEY.IN.SESSION"]}
这样才拿得到值:
2.6.2、注意事项二
${pageContext.request.contextPath} :拿到上下文路径,页面上的href,src等属性可以使用这种方式制定绝对路径;
比如下面的代码:
Servlet交互
Servlet三大职责
- 接受参数
- 调用方法处理业务
- 响应页面
重定向
不能访问WEB-INF底下的资源,会进行多次请求,地址栏会变为最后一次请求的地址
请求转发
在服务器内部进行跳转页面,能访问WEB-INF底下的资源,只进行一次请求,地址栏不会变
访问到WEB-INF中的资源
普通访问和重定向不能访问到WEB-iNF中的资源,请求转发可以