【第47天】EL表达式、JSTL标签(c标签)、JSP的分页

1 EL表达式

       EL表达式(Express Language,表达式语言),凡是称之为表达式的技术,都一般用来输出数据,不能进行复杂的业务逻辑。类似前一天JSP中的“<%= %>”,都是只能取值不能赋值。注意,不管EL表达式放在JSP文件的什么位置,加载时都会被Java虚拟机先编译,在写的位置只是展示作用。

       EL表达式是一个可以跨技术应用的语法,不同于JSP的表达式“<%= %>”的是,它在JS、JSP中都可以使用,一定程度上实现了Java和JS的值共享。下面的1.1章节是实现值共享的方式。

	EL表达式的格式:
	${要输出的数据}

1.1 JSP九种内置对象在EL表达式中的应用

       EL表达式应用了JSP内置对象后,在Java、JS中均可被使用,实现值共享。

JSP内置对象EL表达式版EL表达式范围中提取值
pageContext${pageContext}${pageScope.key}
request${pageContext.request}${requestScope.key}
session${pageContext.session}${sessionScope.key}
application${pageContext.servletContext}${applicationScope.key}
response${pageContext.response}
config${pageContext.servletConfig}
out${pageContext.out}
page${pageContext.page}
exception${pageContext.exception}

1.2 特性测试

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>JspDay2_el_jstl</display-name>
  <!-- 
  	配置一个全局参数
  -->
  <context-param>
  	<param-name>context_param_key</param-name>
  	<param-value>context_param_value</param-value>
  </context-param>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

index.jsp

<%@ page language="java" import="java.util.*,com.test.po.Hero" pageEncoding="UTF-8" isErrorPage="true" %>
<!DOCTYPE HTML>
<html>
  <head>
    <title>EL表达式(Express Language)</title>
  </head>
  <body>
	<h3>算术运算</h3>
	${"3+1"}=${3+1} <br />
	${"10-5"}=${10-5} <br />
	${"2*3"}=${2*3} <br />
	
	<h3>关系运算</h3>
	${3>1} <br />
	${2<10} <br />
	
	<h3>逻辑运算</h3>
	${3>1&&2<5} <br />
	${1<0||3>10} <br />
	
	<h3>三目运算</h3>
	${3>1?true:false} <br />
	${2<10?1:0} <br />
	
	<h3>范围取值</h3>
	<%
		pageContext.setAttribute("key","valuePage");
		request.setAttribute("key","valueRequest");
		session.setAttribute("key","valueSession");
		application.setAttribute("key","valueApplication");
	%>
	<%--
	    JSP对应的源码中pageContext、config、application、session、request、response已定义好,
		可以直接拿来用(见前一天的源码截图)
	 --%>
	<%=pageContext.getAttribute("key") %>
	<%=request.getAttribute("key") %>
	<%=session.getAttribute("key") %>
	<%=application.getAttribute("key") %>
	<br />
	<%--
	    上面的JSP代码在EL表达式中如下书写:
		${范围.key} 注意点后面的是一个key值,对应setAttribute(对应这里,Object);
		范围有如下四种写法:
			pageScope requestScope sessionScope applicationScope
		注意在没有重复的key的前提下,范围一般省略不写
		如果不书写范围,存在多个重复的key,则默认输出现存范围最小的
		源码中是这样转换的,其余同理:
		out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${pageScope.key}", java.lang.String.class, (javax.servlet.jsp.PageContext)_jspx_page_context, null));
        out.write("\r\n");
      
        out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${key}", java.lang.String.class, (javax.servlet.jsp.PageContext)_jspx_page_context, null));
        out.write("\r\n");
	--%>
	${pageScope.key}
	${requestScope.key}
	${sessionScope.key}
	${applicationScope.key}
	${key}
	<br />
	
	<h3>拿取配置在web.xml中的全局参数</h3>
	<%=application.getInitParameter("context_param_key") %>
	<br />	
	${initParam.context_param_key}
	
	<h3>接受客户端通过表单或者链接提交过来的值</h3>
	接受值:<%=request.getParameter("test_param") %>
	<br />
	<%--
		${param.发送过来的key},上面的Java代码若没有值会显示null
		下面的EL表达式若没有值什么都不显示
	--%>
	接受值:${param.test_param}
	
	<h3>拿取自定义数据类型的属性值</h3>
	<%
		//创建一个自定义数据类型
		Hero hero = new Hero(1,"盖伦","战士");
		//赋范围
		session.setAttribute("myhero",hero);		
	%>	
	<a href="show.jsp">查看效果</a>
  </body>
</html>

效果图
在这里插入图片描述
在这里插入图片描述

表单或链接传值
index1.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
  <head>
    <title></title>
  </head>
  <body>
	<% String str = "eric"; %>
	<a href="index.jsp?test_param=<%=str %>">使用链接传递值</a>
	
	<form action="index.jsp" method="get">
		传值: <input type="text" name="test_param" 
		required />
		<br />
		<input type="submit" value="提交" />
	</form>	
  </body>
</html>

使用表单传值时get后面的参数可以自定义,两个接受值也显示同一个传过来的参数
在这里插入图片描述

点击index.jsp中的链接后跳转到的show.jsp

<%@ page language="java" 
import="java.util.*,com.test.po.Hero" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
  <head>
    <title></title>
  </head>
  <body>
	
	拿取实体类属性:<%=((Hero)session.getAttribute("myhero")).getName() %>
  	<br />
  	<%--
  		${范围.key.属性名}
  	--%>
  	拿取实体类属性:${sessionScope.myhero.name}
  	
  	<h3>空验证</h3>
  	<%--
  		如果empty后面的范围取值不为空,则返回false,如果取值为空,则返回true
  	--%>
  	${empty pageScope.judgeEmpty}
  	
  	<h3>注意</h3>
  	<%--
		注意EL表达式并不是什么都可以往外拿取,必须根据范围提供的key往外拿取
		值,只能取存入Scope中的数据。
		如果没有定义范围且此时只有一个key为这个名字,可以直接取到这个key对应的value;
		没有定义范围且多个key重名,此时默认取最小范围的那个值。
		若key本身不存在,根本无法取值,也不输出null等内容,什么反应都没有
	--%> 
  	<% int i = 3;%>
  	取值1:<%=i %>
  	取值2:${i}
	<br />
	<%
		i = 4;
		pageContext.setAttribute("i",i);
	%>
	取值3:${pageScope.i}  
	取值4:${i}
    
    <%--
		若要在EL表达式中嵌套EL表达式,则被嵌套的EL表达式不需要写大括号。
	--%> 
	
  </body>
</html>

效果图:
在这里插入图片描述

2 JSTL标签(c标签)

       JSTL(JSP Standard Tag Lib,JSP标准标签库),因为引入的taglib指令标签中prefix为c(core,核心),后面的标签中冒号前也为c,所以也叫c标签。
       JSP页面不能大量存在Java代码 ,若这样会让页面混乱不堪且浏览器从上到下加载很慢。所以页面内前一天写的JSP页面内写的Java代码需要转换为JSTL标签展示。
       规范地编写JSP页面,是要把页面元素全部都被包裹在标签内,所以c标签会存在很多嵌套JSP标签和EL表达式的情况。

<%@ page language="java" import="java.util.*,com.test.po.Hero" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML>
<html>
  <head>
    <title>JSTL</title>
  </head>
  <body>
	
	<%--
		1)赋值
			var:表示key值
			value:表示value值
			scope:表示范围
			这里支持四种范围 page(PageContext) request(HttpServletRequest) 
			session(HttpSession) application(ServletContext)
	--%>
  	<c:set var="testVar" value="testPage" scope="page"></c:set>
  	<c:set var="testVar" value="testRequest" scope="request"></c:set>
  	<c:set var="testVar" value="testSession" scope="session"></c:set>
  	<c:set var="testVar" value="testApplication" scope="application"></c:set>
  
  	<%--
  		2)取值
  		可直接书写Java代码 
  		直接输出 
  		通过EL表达式拿取(推荐)
  	--%>
  	<c:out value="我是直接输出字符串!!!"></c:out>
  	
  	<% String str = "我是赋值的变量"; %>
  	<c:out value="<%=str %>"></c:out>
  	<c:out value="${pageScope.testVar}"></c:out>
  	<c:out value="${requestScope.testVar}"></c:out>
  	<c:out value="${sessionScope.testVar}"></c:out>
  	<c:out value="${applicationScope.testVar}"></c:out>
  	
  	<%--
  		3)删除值
  		var:要删除的键值对的键
  		scope:要删除的键值对的范围
  		注意如果不指定范围,则默认符合键的全部删除
  	--%>
  	<c:remove var="testVar" scope="request" />
  	<%--
  		default:如果value取值失败,则输出default值
  	--%>
  	<c:out value="${requestScope.testVar}" default="删除成功!"></c:out>

  	<%
  		List<Hero> list = new ArrayList<Hero>();
  		list.add(new Hero(1,"盖伦","战士"));
  		list.add(new Hero(2,"孙悟空","战士"));
  		list.add(new Hero(3,"宫本武藏","战士"));
  		list.add(new Hero(4,"露娜","战士"));
  		session.setAttribute("mylist",list);
  	%>
  	
  	<%--
  		4)重定向
  	--%>
  	<c:redirect url="showtb.jsp"></c:redirect> 
  
  </body>
</html>

在注释重定向标签时,效果图是:
在这里插入图片描述

重定向后的showtb.jsp

<%@ page language="java" 
import="java.util.*,com.test.po.Hero" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML">
<html>
  <head>
    <title></title>
  	<style>
  		table{
  			width:500px;
  			border-collapse:collapse;
  		}
  		table,tr,td{
  			border:solid 2px silver;
  		}
  	</style>
  </head>
  <body>
	<table>
		<tr>
			<td>ID</td>
			<td>英雄名</td>
			<td>英雄类型</td>
		</tr>
		<%--
			5)循环遍历	
			items:循环体,可以从Java代码或者El表达式中拿取
			var:表示每次遍历时循环体中被遍历对象的key值,
			范围默认是pageContext范围		
			begin:起始索引值
			end:结束索引值
			注意索引值从0开始
			step:步长,以几条数据为一个单位进行遍历,默认是1
            
            这里从第三条选取到了第五条,因为没有第五条所以只输出到最后即结束
		--%>
		<c:forEach items="${sessionScope.mylist}"
		var="mList" begin="2" end="4">
		<tr>
			<td><c:out value="${pageScope.mList.id}"></c:out></td>
			<td><c:out value="${mList.name}"></c:out></td>
			<td><c:out value="${mList.type}"></c:out></td>
		</tr>
		</c:forEach>
	</table>
	
	<%--
		6)流程控制
			test如果为true则进入内部分支		
	--%>
	<c:if test="${3>1}">
		<c:out value="输出这里啦!!!"></c:out>
	</c:if>

	<%--
		6)流程控制
			<c:choose>中的<c:when><c:otherwise>互为互斥条件
			类似于 java 中的 if else.		
	--%>	
	<c:choose>
		<c:when test="${3>10}">
			<c:out value="输出这里"></c:out>
		</c:when>
		<c:otherwise>
			<c:out value="最终输出这里啦!!"></c:out>
		</c:otherwise>
	</c:choose>	
  </body>
</html>

效果图:
在这里插入图片描述

3 JSP的分页

       分页有两种形式:假分页,一次将所有的数据全部取出,用户需要哪几条就显示哪几条,用于数据不多但是有强大的缓存机制情况,现在用得少;真分页,用户需要哪几条就从数据库中取出哪几条,不会预先一次性全部取出。

3.1 分页公式

		select 字段 from 表 limit x, y;
		x:起始索引值
		y:本页一共显示多少条记录

3.2 分页四要素及公式演化

不管使用何种技术,完成分页需要获取这四个参数,其中:

要素名称获取方式
总记录数通过dao到数据库中查询
每页记录数自定义
总页数*(总记录数 + 每页记录数 - 1)/每页记录数
当前页默认值是1,此值会随着用户的操作不断发生变化
  • *总页数公式如何记:
    在这里插入图片描述

  • 以上前三个值都是常量,最后一个值为变量。

  • 公式演化:

      select 字段 from 表 limit x, y
      	x:(当前页-1)*每页记录数 [起始索引值]
      	y:[本页一共显示多少条记录]
    

以16条记录,每页5条,分4页为例:

页名页码范围公式计算x,yx,y
page11~5(1-1)*5,50,5
page21~5(2-1)*5,55,5
page31~5(3-1)*5,510,5
page41~5(4-1)*5,515,5

3.3 编码测试

       省略实体类、dao层的步骤,着重测试分页功能。

<%@ page language="java" 
import="java.util.*,com.test.po.Computer,com.test.dao.*" 
pageEncoding="UTF-8"
contentType="text/html; charset=utf-8"%>
<% request.setCharacterEncoding("utf-8"); %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML>
<html>
  <head>
    <title>JSP分页</title>
    <style>
    		table,tr,th,td{
    			border:solid 2px silver;
    		}
    		table{
    			width:500px;
    			border-collapse:collapse;
    		}
    		th{
    			background-color:gray;
    		}
    </style>
  </head>
  <body>	
	<%
		ComputerDaoIf dao = new ComputerDaoImpl();
		//1:拿取总记录数
		Integer allRecord = dao.getCount();
		
		//2:拿取每页记录数
		Integer pageRecord = 5;
		
		//3:拿取总页数
		Integer allPage = (allRecord+pageRecord-1)/pageRecord;
		
		//4:设置当前页
		Integer currentPage = 1;
		
		//接受表单提交的值
		String value = request.getParameter("cup");
		if(value!=null){
			currentPage = Integer.parseInt(value);
		}
		
		List<Computer> list = dao.getPage((currentPage-1)*pageRecord,pageRecord);
		request.setAttribute("mylist",list);
	%>
	<table>
		<tr>
			<th>ID</th>
			<th>品名</th>
			<th>售价</th>
			<th>产地</th>
		</tr>
		<c:forEach items="${mylist}" var="test">
		<tr>
			<td><c:out value="${test.id}"></c:out></td>
			<td><c:out value="${test.name}"></c:out></td>
			<td><c:out value="${test.total}"></c:out></td>
			<td><c:out value="${test.location}"></c:out></td>
		</tr>
		</c:forEach>
	</table>
	
	
	
	<form action="index.jsp" method="get">
	
		<%--隐藏表单域,当前在第几页--%> 
		<input type="hidden" name="cup" />
		
		<%--当已经是首页时,首页按钮被禁用--%>
		<input type="button" value="首页" onclick="change(1)"  <%=currentPage==1?"disabled":"" %> />
		
		<%--当已经是首页时,上一页按钮被禁用--%> 
		<input type="button" value="上一页" onclick="change(<%=currentPage-1 %>)" <%=currentPage==1?"disabled":"" %> />
		
		<%--当已经是末页时,下一页按钮被禁用--%> 
		<input type="button" value="下一页" onclick="change(<%=currentPage+1 %>)" <%=currentPage==allPage?"disabled":"" %> />
		
		<%--当已经是末页时,下一页按钮被禁用--%> 
		<input type="button" value="末页" onclick="change(<%=allPage %>)" <%=currentPage==allPage?"disabled":"" %> />
		
	</form>	
	<script>
		function change(cr){
			//将当前页的值赋值给隐藏域的value值
			document.forms[0].cup.value = cr;
			//使用JS提交表单
			document.forms[0].submit();
		}
	</script>
  </body>
</html>

效果图:
在这里插入图片描述

在这里插入图片描述

4 Servlet、JSP和HTML的中文编码的问题

       当出现乱码问题时,首先检查代码的拼写,若没有问题检查添加如下代码。

4.1 Servlet

4.1.1 doPost
  • 使用软编码

      response.setContentType("text/html;charset=编码");
      request.setCharacterEncoding("编码");
    
4.1.2 doGet
  • 使用软编码

      response.setContentType("text/html;charset=编码");
      request.setCharacterEncoding("编码");
    
  • 若软编码无效

      	在Tomcat的conf文件夹中修改server.xml的第69行代码
      	添加如下语句,使Tomcat中的项目不按浏览器的地址栏中编码方式进行编码,
      	而是按照页面内的编码方式编码
      	useBodyEncodingForURI="true"
    
  • 若以上方法均无效,只能将获取到的Get值使用硬编码按字节强转:

      public void doGet(HttpServletRequest request,HttpServletResposne)
      throws Exception{
      	response.setContentType("text/html;charset=编码");
      	request.setCharacterEncoding("编码");
      	
      	String name = request.getParameter("key");
      	String newName = change(name);
      }
      
      //硬编码
      public String change(String old){
      	try{
      		return new String(old.getBytes("iso-8859-1"),"编码");
      	}catch(Exception ex){
      		ex.printStackTrace();
      		return null;
      	}
      }
    

4.2 JSP

<%@ page contentType="text/html;charset=utf-8" %>
<% request.setCharacterEncoding("utf-8"); %>

4.3 HTML

       head标签中添加<meta charset=“utf-8”/>

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值