Servlet的用途主要有:接受浏览器的请求,获取数据;转发、重定向;负责调用业务层。
Servlet缺点:不适合展示数据,jsp技术可以解决这个问题,将从数据库获取的数据展示在前端页面。
一、JSP概述
全称: Java Server Pages,java服务器页面。和Servlet一样,是sun公司定义的一种动态网页开发技术。
特点:基于html模版,可以在html模版嵌入java代码和jsp中的标签。
tomcat可以包含的资源:
(1)静态资源
html:静态页面。
CSS:修饰美化html页面。
JavaScript:动态修改html页面和css样式。
(2)动态资源
Servlet:运行在服务器上的java小程序。适合编写java代码,写网页困难,适合业务处理
Servlet三个用途:1 接受浏览器发送的数据 2转发重定向 3 负责调用业务层
JSP:适合编写动态内容,不适合写java代码,主要用于显示页面。
为什么要使用JSP?
jsp性能好,可以在html页面中动态嵌入元素
服务器调用的是已经编译好的JSP文件
JSP基于Java Servlet Api,有很多强大企业的支持
JSP可以与处理业务逻辑的Servlet一起使用,该模式被Java Servlet模版引擎所支持。
JSP优势
与纯 Servlet 相比:JSP可以很方便的编写或者修改HTML网页而不用去面对大量的println语句
与JavaScript相比:虽然JavaScript可以在客户端动态生成HTML,但是很难与服务器交互,因此不能提供复杂的服务,比如访问数据库和图像处理等等。
与静态HTML相比:静态HTML不包含动态信息
二、JSP语法
<%@ page import="java.util.Date" %><!--导包-->
<%@ page contentType="text/html;charset=UTF-8" language="java" %><!--编码格式-->
<html>
<head>
<%--本质就是servlet技术,只不过是用来展示数据--%>
<title>jsp语法</title>
</head>
<body>
<ul>
<li>指令:page</li>
<li>脚本</li>
<li>脚本表达式:表达式</li>
<li>静态内容:html,css,javascript</li>
</ul>
<%
//脚本,<% %>内可以写java代码
String name = "张三";
int age = 20;
int num = 100;
System.out.println(name);//控制台输出
out.println(age);
out.println("<br/>");
out.println(new Date());
%>
<br/>
<%=num%> <%--相当于是out.println--%>
<br/>
<%!
//定义方法
public String getUpper(String s) {
return s.toUpperCase();
}
%>
<br/>
<%=getUpper("hello")%> <%--调用方法--%>
<%@include file="footer.jsp"%>
<jsp:include page="footer.jsp"></jsp:include>
</body>
</html>
【重点】
执行并访问Jsp页面以后,在控制台可以看到路径【Using CATALINA_BASE: “C:\Users\seaho.IntelliJIdea2018.2\system\tomcat\Tomcat_8_5_45_0902web2”】,访问,并在项目下的【C:\Users\seaho.IntelliJIdea2018.2\system\tomcat\Tomcat_8_5_45_0902web2\work\Catalina\localhost\0902web2\org\apache\jsp】找到对应的目录,会发现,都是【java类和class类】文件,所以其本质还是java代码,只是格式上的变化。
三、JSP标签
jsp:include 动态包含
jsp:forward请求转发
jsp:param 请求设置参数
注意:主页面中设置编码类型utf-8 jsp:param的value属性才可以使用中文,不然会乱码
jsp:useBean 创建一个对象
jsp:setProperty给指定的对象属性赋值
jsp:getProperty取出指定的对象属值
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
request.setCharacterEncoding("utf-8");
%>
<html>
<head>
<title>jsp6个标签</title>
</head>
<body>
<h1>jsp标签(动作标签)</h1>
<ul>
<li>jsp:include 动态包含</li>
<li>jsp:forward 转发</li>
<li>jsp:param 包含或转发的参数</li>
<li>jsp:useBean 创建java对象</li>
<li>jsp:setProperty 设置java对象属性</li>
<li>jsp:getProperty 获取java对象属性</li>
</ul>
<!--包含footer.jsp,一并显示-->
<jsp:include page="footer.jsp">
<jsp:param name="username" value="张三"></jsp:param>
</jsp:include>
<%--<!--跳转到jsp语法,地址栏不变,内容是jsp语法的-->
<jsp:forward page="jsp语法.jsp?username=张三">
<jsp:param name="age" value="20"></jsp:param>
</jsp:forward>--%>
<!--创建对象,必须在java中有对应的类,然后设置和获取属性-->
<jsp:useBean id="user" class="domain.User"></jsp:useBean>
<jsp:setProperty name="user" property="username" value="李四"></jsp:setProperty>
<jsp:setProperty name="user" property="password" value="123"></jsp:setProperty>
<jsp:setProperty name="user" property="email" value="lisi@163.com"></jsp:setProperty>
<jsp:getProperty name="user" property="username"></jsp:getProperty>
<jsp:getProperty name="user" property="password"></jsp:getProperty>
<jsp:getProperty name="user" property="email"></jsp:getProperty>
</body>
</html>
四、九大内置对象和域对象
Jsp本质是Servlet类,包含九个内置对象,自然包含有Servlet类方法
对象名 | 类型 | 说明 |
---|---|---|
request | javax.servlet.http.HttpServletRequest | |
response | javax.servlet.http.HttpServletResponse | |
session | javax.servlet.http.HttpSession | 由session=“true”开关 |
application | javax.servlet.ServletContext | |
config | javax.servlet.ServletConfig | |
exception | java.lang.Throwable | 由isErrorPage=“false”开关 |
out | javax.servlet.jsp.JspWriter | javax.servlet.jsp.JspWriter |
pageContext | javax.servlet.jsp.PageContext | |
page | java.lang.Object当前对象this | 当前servlet实例 |
r r s a c e o p p
pageContext作用:
- 代表页面上下文,获取其他八个内置对象
getException方法返回exception隐式对象
getPage方法返回page隐式对象
getRequest方法返回request隐式对象
getResponse方法返回response隐式对象
getServletConfig方法返回config隐式对象
getServletContext方法返回application隐式对象
getSession方法返回session隐式对象
getOut方法返回out隐式对象
- 作用容器使用
域对象
jsp中共包含四个域对象分别是pageContext、request、session、application(范围依次扩大)
pageContext域的使用场景:只能当前页面。
request域的使用场景:本次请求之后,数据就不再使用了,根据学号查询学生,根据新闻id查询新闻,依赖于转发,如果重定向,则数据无法给到对应界面。
session域的使用场景:同一个会话中共享的数据,使用session,用户登录信息,不依赖与抓饭和重定向,始终都可以获取,除非会话结束,会话结束一般是该会话长时间(默认30分钟)不使用,就会销毁。《Web的状态管理——Cookie和session技术的使用》
application域的使用场景:所有用户共享的数据。整个程序的配置信息,除非程序退出。
其中pageContext可以操作其他三个域对象(request,session,application)的数据
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>jsp九大内置对象</title>
</head>
<body>
<h1>jsp九大内置对象</h1>
<ul>
<li>request</li>
<li>response</li>
<li>session</li>
<li>application</li>
<li>config</li>
<li>exception</li>
<li>out</li>
<li>pageContext</li>
<li>page = this</li>
</ul>
<h1>out对象</h1>
<h3>jsp中out和servlet中的response.getWrite()区别</h3>
<ul>
<li>类型:jsp中的out类型是JspWriter,response.getWrite()是printWriter打印流</li>
<li>jsp的out输出会放到缓存中,并没有放到response中(除非flush清空缓冲),而response.getWrite()直接写入到response中</li>
</ul>
<%
out.println("jsp中的out<br/>");
out.flush(); //由于在缓冲区,打印结果,肯定是response的out在前
response.getWriter().println("response中的out");
%>
<h1>pageContext对象,代表【页面】上下文</h1>
<h3>用途1:可以获取其他八个内置对象</h3>
<h3>用途2:可以作为容器使用</h3>
<%
pageContext.setAttribute("username", "Jack");
Object username = pageContext.getAttribute("username");
out.println(username);
//可以操作其他三个域对象,这样可以在其他jsp文件中读取
pageContext.setAttribute("r_username", "Julia", PageContext.REQUEST_SCOPE);
pageContext.setAttribute("s_username", "Jone", PageContext.SESSION_SCOPE);
pageContext.setAttribute("a_username", "Bios", PageContext.APPLICATION_SCOPE);
%>
<jsp:forward page="sub.jsp"></jsp:forward>
</body>
</html>
读取数据
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>获取数据</title>
</head>
<body>
<%
Object r_username = pageContext.findAttribute("r_username");
out.println(r_username);
Object s_username = pageContext.findAttribute("s_username");
out.println(s_username);
Object a_username = pageContext.findAttribute("a_username");
out.println(a_username);
%>
</body>
</html>
跳转和包含简易方法
pageContext.forward(“2.jsp”);//转发 request.getRequestDispatcher().forward();
pageContext.include(“2.jsp”);//动态包含
五、EL表达式
四种添加元素的容器:pageContext、request、session、application,作用范围依次扩大,但是第一种可以操作其他域对象,原则是能用范围小的,不用范围大的。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL表达式的使用</title>
</head>
<body>
<h2>EL表达式的使用</h2>
<h3>案例一:获取简单数据</h3>
<%
//以下为四种容器使用形式,集合必须使用域
pageContext.setAttribute("username", "张三");
request.setAttribute("age", 25);
session.setAttribute("phone", "13770710803");
application.setAttribute("address", "北京");
//添加对象的方式,对象中还有对象,比如地址address
User user = new User("李四", "123", "166@qq.com");
Address address = new Address("山东省", "德州");
user.setAddress(address);
//必须使用域pageContext添加,后面才能用EL表大会
pageContext.setAttribute("user", user);
%>
<h5>不使用EL表达式,一个个获取,很麻烦</h5>
<%=pageContext.findAttribute("username")%><br/>
<%=pageContext.findAttribute("age")%><br/>
<%=pageContext.findAttribute("phone")%><br/>
<%=pageContext.findAttribute("address")%><br/>
<h5>使用EL表达式,注意$开头,并且不要有双引号</h5>
<%--使用EL表达式,$符号开头--%>
${"username"}<br/> <%--不要添加双引号,这就是字符串--%>
${username}<br/> <%--这才是变量--%>
${age}<br/>
${phone}<br/>
${address}<br/>
<h5>获取对象的toString方法</h5>
${user}<br/> <%--toString方法执行--%>
<h5>获取对象各个属性,对象中还有对象,则一点到底即可</h5>
${user.username}<br/>
${user.password}<br/>
${user.email}<br/>
${user.address.province}<br/>
${user.address.city}<br/>
<h3>案例三:使用List和Map集合</h3>
<h4>使用List集合</h4>
<%
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("华为");
arrayList.add("小米");
arrayList.add("三星");
arrayList.add("苹果");
//必须使用域pageContext添加,后面才能用EL表大会
session.setAttribute("list", arrayList);
ArrayList<User> users = new ArrayList<>();
users.add(new User("jace", "23", "ahgh@163.com"));
users.add(new User("BUl", "156161", "aga125@163.com"));
request.setAttribute("users", users);
%>
${list[0]}<br/>
${list[1]}<br/>
${list[2]}<br/>
${list[3]}<br/>
<h5>对象加入到list集合,获取各个属性值</h5>
${users[0].username}<br/>
${users[0].password}<br/>
${users[0].email}<br/>
<h4>使用map集合</h4>
<%
Map<String, String> map = new HashMap<>();
map.put("CN", "中国");
map.put("USA", "美国");
map.put("UK", "英国");
application.setAttribute("map", map);
%>
<h5>可以使用中括号,但是必须是【双引号或者单引号】引起来,也可以用【点】的方式</h5>
${map["CN"]}<br/>
${map["USA"]}<br/>
${map["UK"]}<br/>
${map.CN}<br/>
${map.USA}<br/>
${map.UK}<br/>
</body>
</html>
规则【重点】:
- 在【<% %>】内添加java代码,注意,必须将值存入【域】
- 用EL表达式【${ }】输出结果
- 注意EL表达内不能用双引号,Map集合角标必须是双引号或单引号
六、EL运算符
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL表达式执行运算</title>
</head>
<body>
<h3>EL表达式执行运算</h3>
<h4>算数运算符</h4>
${10 * 5}<br/>
<h4>关系比较运算符,有简写英文对照</h4>
${10 > 5}<br/>
${10 != 5}<br/>
${10==9 }<br/>
${10 eq 5}<br/>
${10>20}<br/>
${10 gt 20}<br/>
${5 < 10}<br/>
${5 lt 10}<br/>
${5 != 10}<br/>
${5 ne 10}<br/>
<%
pageContext.setAttribute("s1", new String("hello"));
pageContext.setAttribute("s2", new String("hello"));
%>
<h5>与java不同,new的字符串也是相同的</h5>
${s1 == s2}<br/>
<h4>empty判断元素是否为null/""/集合为0</h4>
<h5>没有就是true</h5>
${empty user}<br/>
<h4>三目运算</h4>
<%
pageContext.setAttribute("score", 90);
pageContext.setAttribute("gender", 1);
pageContext.setAttribute("user", "Jack");
%>
${score > 90 ? "优秀" : "一般"}<br/>
${empty user ? "没有登录" : "登录了"}<br/>
<h4>逻辑运算符</h4>
${true && false}<br/>
${true || false}<br/>
${!true}<br/>
${true and false}<br/>
${true or false}<br/>
${not true}<br/>
</body>
</html>
注意:empty 对象为null或者“”或者0,显示true
七、隐式对象
JSP 表达式语言定义了一组隐式对象,其中许多对象在 JSP servlet和表达式中可用:
pageContext:页面上下文,可以获取jsp中其他八个内置对象
pageScope、requestScope、sessionScope、applicationScope表示四个域对象中集合
param 表示【request.getParameter(“username”); 或 ${param.username} 】
paramvalues 表示【request.getPrameterValues(“hobby”) 或 ${paramValues.hobby}】
header 表示【request.getHeader(“accept”); 或 ${header.accept};】 request.getHeader(“accept”); 或 ${header.accept};
headerValues 表示 【request.getHeaderValues(“accept-encoding”); 或 ${headerValues[“accept-encoding”][0]}】
cookie 表示【request.getCookies(); 或 ${cookie.JSESSIONID}】
initParam 表示 ServletContext(application)初始化参数
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL隐式对象</title>
</head>
<body>
<h2>pageContext</h2>
可以获取其他八个内置对象${pageContext.request}<br/>
获取项目名称【重点】:${pageContext.request.contextPath}<br/>
<form action="${pageContext.request.contextPath}/usersevlet" method="post">
</form>
<h2>当域中name值相同,需要使用域的集合Scope进行指定获取,否则自动从小域到大域查找</h2>
<%
pageContext.setAttribute("address", "北京");
request.setAttribute("address", "上海");
session.setAttribute("address", "广州");
application.setAttribute("address", "深圳");
%>
${pageScope.address}<br/>
${requestScope.address}<br/>
${sessionScope.address}<br/>
${applicationScope.address}<br/>
<h2>param paramValues:获取浏览器发送的参数</h2>
${param.username}<br/>
${param.password}<br/>
${paramValues.hobby[0]}<br/>
${paramValues.hobby[1]}<br/>
${paramValues.hobby[2]}<br/>
<h2>header headerValues :获取浏览器发送请求头数据</h2>
${header.accept}
</body>
</html>
八、JSTL
8.1 概述
JSTL:全称Java Server Pages Standard Tag Library,JSP标准标签库,代替jsp页面的脚本,实现逻辑控制。
现JSP页面中逻辑处理。如判断, 循环等。
8.2 使用JSTL
- 下载库,并导入jar包
下载JSTL库
把jstl.jar、standard.jar放入WEB-INF/lib目录下 - 在JSP页面添加tablib指令库
//导包,注意prefix="c" 一个标记,后面调用JSTL的工具必须c开头
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c">
- 四大标签:通用、条件、迭代和url
<html>
<head>
<title>JSTL</title>
</head>
<body>
<h3>通用标签remove/set/out</h3>
<%--向pageScope域中放入username:张三--%>
<c:set var="username" value="张三"></c:set>
<%--向requestScope域中放入age:20--%>
<c:set var="age" value="20" scope="request"></c:set>
${username}<br/>
${requestScope.age}<br/>
<%
User user = new User();
pageContext.setAttribute("user", user);
%>
<%--向对象中添加属性值--%>
<c:set target="${user}" property="username" value="Jack"></c:set>
<c:out value="${user.username}"></c:out>
<c:out value="${user.password}" default="xxxx"></c:out><br/>
<c:remove var="haha"></c:remove>
<h3>条件标签if,choose</h3>
<%
pageContext.setAttribute("score", 99);
pageContext.setAttribute("gender", "男");
%>
<c:if test="${score > 90}">
优秀
</c:if>
<c:if test="${gender == '男'}">
帅哥
</c:if>
<c:choose>
<c:when test="${score > 90}">优秀</c:when>
<c:when test="${score > 80}">良好</c:when>
<c:when test="${score > 60}">及格</c:when>
<c:otherwise>不及格</c:otherwise>
</c:choose>
<h3>迭代标签</h3>
<%
ArrayList<String> list = new ArrayList<>();
list.add("北京");
list.add("上海");
list.add("广州");
list.add("深圳");
pageContext.setAttribute("list", list);
%>
<c:forEach var="city" items="${list}">
${city}
</c:forEach><br/>
<h5>输出下标和个数</h5>
<c:forEach var="city" items="${list}" varStatus="vs">
${city}---${vs.index}---${vs.count}
</c:forEach><br/>
<h5>输出1到100的偶数</h5>
<c:forEach var="n" begin="1" end="100" step="2">
${n}  
</c:forEach><br/>
<h3>自定义url标签,然后在a标签进行跳转</h3>
<c:url var="jspyufa" value="/jsp语法.jsp">
<c:param name="name" value="张三"></c:param>
</c:url>
<a href="${jspyufa}">跳转</a>
</body>
</html>
注意:可以发现,在JSTL中获取变量和值,必须使用EL标签语句