目录
Jsp与Servlet
关系:jsp文件在容器中会转换成servlet文件执行,jsp是对servlet的一种高级封装,本质还是servlet。
区别:与servlet相比:jsp可以很方便的编写或者修改html网页而不用去写大量的println语句。
Sevlet与JSP的区别:
Servlet:
1.编码:继承HttpServlet + 注解 或 配置web.xml
2.修改:重新部署,重启服务器
3.访问:http://...//servlet
4.标签:printWriter.println("<html>");
JSP:
1.编码:html中可直接编写java代码
2.修改:刷新页面
3.访问:http://...//jsp01.jsp
4.标签:直接编写html标签
JSP实现原理
Tomcat会将xxx.jsp转换成java代码,进而编译成.class文件,最终将运行结果通过response响应给客户端。
可通过运行终端的第一行"路径"去查找jsp转换成servlet的java代码的文件
普通脚本
语法:<%Java代码%>
<%System.out.println("hello jsp")%>
普通脚本可以使用所有Java语句,除了定义自定义方法。
脚本与脚本之间不可嵌套,脚本与html标签不可嵌套。
声明脚本
语法:<%!定义变量或方法>
<%! int i = 0 %>
<%! String str = new String() %>
<%!
public void way(){
System.out.println("hello jsp");
}
%>
声明脚本声明的变量是全局变量。
声明脚本的内容必须在普通脚本<%%>中调用。
如果声明脚本中的方法具有返回值,使用输出脚本调用<%=%>。
JSP注释
<%--注释--%>:JSP注释,注释内容不会被发送至浏览器甚至不会变编译
<!--注释-->:HTML注释,通过浏览器查看网页源代码时可以看见注释内容
JSP指令
JSP指令用来设置与整个JSP页面相关的属性。
<%@ page...%>:定义页面的依赖属性,比如脚本语言、error页面、缓存需求等等
<%@ include...%>:包含其他文件
<%@ taglib... %>:引入标签库的定义,可以是自定义标签
page指令:
属性:contentType 描述:指定当前JSP页面的MIME类型和字符编码格式
属性:errorPage 描述:指定当前JSP页面发生异常时需要转向的错误处理页面
属性:isErrorPage 描述:指定当前页面是否可以作为另一个JSP页面的错误处理页面
属性:import 描述:导入要使用的Java类
属性:language 描述:定义JSP页面所使用的脚本语言,默认为Java
属性:session 描述:指定JSP页面是否可以使用session,默认为true立即创建,false为使用时创建
属性:pageEncoding 描述:指定JSP页面的解码格式
include指令:
静态引入
语法:<%@ include file="被包含的JSP路径"%>
通过include指令来包含其他文件,被包含的文件可以是JSP文件,HTML文件或文本文件。包含的文件可作为JSP的一部分,会被同时编译执行。
例:<%@ include file="header.jsp" %>
注:可能有重命名的冲突问题,不推荐使用。
动态引入
语法:<jsp:include page="被包含的JSP路径">
<jsp:include 为动态包含,<jsp:include 如包含jsp文件,这每次加载主页面的时候,被包含的页面都要重新编译。 就是说不管你包含了几个jsp页面转译成servlet时中有一个class文件,在运行时插入“a.jsp"的响应。
例:<jsp:include page="header.jsp" %>
taglib指令:
语法:<%@ taglib uri="外部标签库路径" prefix="前缀">
例:<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c">
useBean
语法:<jsp:useBean id="name" class="package.className"/>
用来加载一个将在JSP页面中使用的JavaBean
<jsp:useBean id="user" class="com.tyh.entity.User/>
在类加载后,可通过jsp:setProperty和jsp:getProperty动作来修改和获取bean的属性
setProperty:
属性:name 描述:name属性是必须的。他表示要设置属性的是哪个Bean
属性:property 描述:property属性是必须的。他表示要设置哪个属性
属性:value 描述:value属性是可选的。该属性用来指定Bean属性的值
<jsp:useBean id="user" class="com.tyh.entity.User/>
<jsp:setProperty name="user" property="name" value="xiaoteng"/>
getProperty:
属性:name 描述:要检索的Bean属性名称。Bean必须已定义
属性:property 描述:表示要提取Bean属性的值
<jsp:useBean id="user" class="com.tyh.entity.User"/>
<jsp:setProperty name="user" property="name" value="xiaoteng"/>
<jsp:getProperty name="user" property="name"/>
forward:<jsp:forward page="index.jsp"/> 把请求转到另外的页面
param:在转发动作内部使用,做参数传递
<jsp:forward page="index.jsp">
<jsp:param name="sex" value="nan"/>
<jsp:forward/>
内置对象:request、response、session(由session="true"开关)、application、cofig、exception(由isErrorPage="false"开关)、out、pageContext、page(当前servlet实例)
四大作用域对象
JSP有四大作用域对象,存储数据和获取数据的方式一样,不同的是取值的范围有差别
pageContext 当前JSP页面有效
request 一次请求有效
session 一次会话有效(关闭浏览器失效)
application 整个Web应用有效(服务器重启或关闭失效)
EL表达式(Expression Language)
概念:EL是JSP写起来更简单、简洁。主要用于获取作用域中的数据
作用:用于替换作用域对象,getAttribute("name");
EL的应用(获取基本类型、字符串)
${scope.name} 获取具体某个作用域中的数据
${name} 获取作用域中的数据,逐级查找(pageContext、request、session、application)
EL和JSP脚本的区别:
<%=request.getAttribute()%> 没有找到返回null
${requestScope.name} 没有找到返回""(推荐)
EL的应用(获取引用类型)
使用EL获取作用域中的对象调用属性时,只能访问对象的get方法,必须遵守命名规范定义
<%
User user = new User();
user.setName("小滕");
user.setAge("21");
request.setAttribute("user",user);
%>
${requestScope.user.name} <%--调用getName()方法--%>
EL的应用(获取数组、集合的元素)
EL可以获取Array、List、Map中的元素,Set由于没下标,无法直接访问元素,后续可遍历
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>数组、集合的访问</title>
</head>
<body>
<%
int[] array = new int[]{1,2,3,4,5,6};
request.setAttribute("array",array);
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("D");
request.setAttribute("list",list);
Map<String,String> map = new HashMap<>();
map.put("CN","中国");
map.put("US","美国");
map.put("IT","意大利");
request.setAttribute("map",map);
%>
<%--访问数组--%>
${array[0]}
${array[1]}<br>
<%--访问List集合--%>
${list[0]}
${list.get(1)}<br>
<%--访问Map集合--%>
${map["CN"]}
${map.US}<br>
</body>
</html>
EL运算符
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL表达式</title>
</head>
<body>
<%
request.setAttribute("nums",1234);
request.setAttribute("ss",null);
%>
<h1>empty判空运算符</h1>
<h1>${empty ss}</h1>
<hr>
<h1>算数运算符</h1>
<h1>${nums + 2}</h1>
<h1>${nums - 2}</h1>
<h1>${nums * 2}</h1>
<%--除/--%>
<h1>${nums div 2}</h1>
<%--取余%--%>
<h1>${nums mod 2}</h1>
<hr>
<h1>关系运算符</h1>
<%--等于==--%>
<h1>${nums eq 1234}</h1>
<%--不等于!=--%>
<h1>${nums ne 1235}</h1>
<%--小于<--%>
<h1>${nums lt 1235}</h1>
<%--大于>--%>
<h1>${nums gt 1233}</h1>
<%--小于或等于<=--%>
<h1>${nums le 1234}</h1>
<%--大于或等于>=--%>
<h1>${nums ge 1234}</h1>
<%--逻辑与&&--%>
<h1>${nums > 1233 and nums < 1235}</h1>
<%--逻辑或||--%>
<h1>${nums > 1234 or nums < 1235}</h1>
<%--取反!--%>
<h1>${not(nums > 1235)}</h1>
</body>
</html>
获取应用上下文(项目名):
<%=request.getContext()%>
${pageContext.request.contextPath}
获取Cookie对象:
${cookie.username} //获取名为username的cookie对象
${cookie.password} //获取名为password的cookie对象
${cookie.password.value} //获取password的cookie的value值
JSTL标准标签库
现有问题
1.EL主要是用于作用域获取数据,虽然可以做运算判断,但是得到的都是一个结果做展示。
2.EL不存在流程控制,比如判断。
3.EL对于集合只能做单点访问,不能实现遍历操作,比如循环。
什么是JSTL?
JSP标准库(JSTL)是一个JSP标签集合
JSTL的作用
可对EL获取到的数据进行逻辑操作,与EL合作完成数据的展示。
JSTL的使用
导入两个jar文件:standard.jar和jstl.jar文件拷贝到Web的/WEB-INF/lib/下
在JSP页面引入标签库<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
核心标签:
条件标签if判断:
语法:<c:if test="条件"></c:if>
<%--if判断--%>
<c:if test="${username == '小滕'}">
<h1>欢迎你,${username}</h1>
</c:if>
多条件choose判断:
<%--多重if判断--%>
<c:choose>
<c:when test="${age < 18}"><h1>少年</h1></c:when>
<c:when test="${age >= 18 && age < 30}"><h1>青年</h1></c:when>
<c:when test="${age >= 30 && age < 50}"><h1>中年</h1></c:when>
<c:otherwise><h1>老年</h1></c:otherwise>
</c:choose>
迭代foreach标签(遍历集合):
<%--遍历集合--%>
<%--var="变量名",items="集合",begin="起始下标",end="结束下标",step="间隔长度",
varstatus="遍历状态"(first是否为第一行,last是否为最后一行,count当前行数,index当前元素的下标)--%>
<c:forEach var="s" items="${list}" begin="0" end="3" step="1" varStatus="i">
<h1>值:${s} 是否首个:${i.first} 是否尾个:${i.last} 当前行数:${i.count} 当前元素下标:${i.index}</h1>
</c:forEach>
<c:forEach var="s" items="${users}">
<h1>${s.username} ${s.password}</h1>
</c:forEach>
url标签:
在Cookie禁用的情况下,通过重写URL拼接JSESSIONID来传递ID值。便于下一次访问时任可查找到上一次的Session对象
<c:url context='${pageContext.request.contextPath}' value='/error.jsp'></c:url>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>重写URL</title>
</head>
<body>
<%
String url = response.encodeRedirectURL(request.getContextPath()+"\\error.jsp");
%>
<a href="<%=url%>">点击跳转</a>
<br>
<a href="<%=response.encodeRedirectURL(request.getContextPath())+"\\error.jsp"%>">点击跳转</a>
<br>
<a href="<c:url context='${pageContext.request.contextPath}' value='/error.jsp'></c:url>">点击跳转</a>
</body>
</html>
分页查询
概念
分页是Web应用程序非常重要的一个技术。数据库中的数据可能是成千上万的,不可能把这么多的数据一次性的显示在浏览器上。一般根据每行数据在页面上所占的空间设置每页显示若干行,比如一般20行是一个比较理想的显示状态。
分页实现思路
对于海量的数据查询,需要多少就取多少,显示是最佳的解决方法,假如某个表中有200万条记录,第一页取前20条,第二页取21-40条记录。
select * from 表名 (order by id) limit 起始页码,显示条数; (起始页 = (页码 - 1) * 显示条数大小)
分页代码实现步骤
1.确定每页显示的数据数量
2.确定分页显示所需的总页数
3.编写SQL查询语句,实现数据查询
4.在JSP页面中进行分页显示设置