大道至简,殊途同归,记录JSP学习过程。端午节快乐!
随着学习的内容越来越多,越发感觉到大道至简,殊途同归。
之前大二学过c#,随着现在学习的过程,感觉c#跟java也没啥大的区别,可能直接拿来做东西,不会立即整出来。但是真正用的时候,会发现哪怕是搜问题的过程都是一样的。以至于我现在看python,虽然我不了解语法,但是一看别人写的代码,思路就了然于胸了。
之前学校教过asp,我又自学了php,现在学到jsp的各种东西,老是不自觉得联想到asp与php的东西。用法虽然不一样,本质却是一样的。
大道至简,殊途同归,用这句话概括,再明白不过了。
一、JSP
jsp的概念以及运行原理,看这里
1.1 指令
作用:用于配置jsp页面,导入资源文件
格式:<%@ 指令名称 属性名1=属性值 属性名2=属性值2 %>
分类:
- page:配置jsp页面
- contentType:等同于response.setContentType()。
- 可以设置响应体的MIME类型以及字符集编码
- 设置当前jsp页面的编码(只能是高级的IDE才能生效,如果使用记事本之类的,则需要设置pageEncoding来设置当前页面编码)
- pageEncoding:设置页面编码
- language:jsp刚出现的时候,想要一统江湖(表现层技术),但是目前为止也只是java而已
- buffer:out输出流缓冲区大小,默认8KB
- import:导包,跟java中导包是一样的。
- errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
- isErrorPage:默认是false。标识当前页面是否是错误页面
- true:是错误页面,可以使用内置对象exception来获取错误信息
- false:默认值。不能使用内置对象
- contentType:等同于response.setContentType()。
- include:页面包含的,导入页面的资源文件
- <%@include file="资源文件" %>
- taglib:导入资源。如导入标签库
- <%@taglib prefix="前缀" uri="标签库" %>,前缀可以自定义。但是都已经约定俗成了,所以还是按习惯来。
1.2 注释
- html注释
<!-- 注释 -->:只能注释html片段,会保存在html源码中
- jsp特有的注释
<%-- 注释 --%>:可以注释所有,不会保存在html源码中,在jsp中推荐都使用jsp注释
1.3 内置对象
9个内置对象
- 域对象:共享数据,以下域的范围是从小到大
- pageContext:PageContext类型
- 当前页面共享数据
- 可以通过getXXX()获取其他的八个对象
- request:HttpServletRequest类型
- 一次请求访问的多个资源间共享数据,如转发
- session:HttpSession类型
- 一次会话的多个请求间共享数据
- application:ServletContext类型
- 多个用户间共享数据
- pageContext:PageContext类型
- 响应对象 5. response:HttpServletResponse类型 6. page:Object类型,当前页面的引用,相当于该Servlet的this 7. out:JspWriter类型,将数据输出到页面
- 配置对象 8. config:ServletConfig类型,Servlet的配置对象
- 异常 9. exception:Throwable类型,异常对象
具体如何查看其类型,可以在jsp编译后的java文件中,在service方法下找到。
二、MVC开发模式
2.1 jsp演变历史
早期只有Servlet,只能通过response输出标签数据,非常麻烦。
后来sun公司出了jsp,简化了Servlet的开发,非常方便,但是,与html的混编,导致后期大量的代码让人无法阅读
再后来,javaweb开发,借鉴了MVC这种开发模式,使得程序的设计更加有合理性
2.2 MVC
将程序分为三部分
- Model:模型
- 业务逻辑操作,如查询数据库、封装数据等
- View:视图
- 展示数据
- Controller:控制器
- 获取客户端输入
- 调动模型
- 将数据交给视图展示
流程
用户访问网站,会先进入Controller,然后Controller调用Model,Model返回数据给Controller。
Controller将接收到的数据传递给View,View将数据呈现出来。
在javaweb中
- Model:JavaBean
- View:JSP
- Controller:Servlet
MVC优缺点
优点:
- 耦合性低,方便维护,利于分工协作
- 重用性高
缺点:使得项目架构变得复杂,对开发人员的要求就会变高
在jsp中要尽量少写java代码,由此就需要用到EL表达式跟jstl
三、EL表达式
概念:Expression Language,表达式语言
作用:可以替换和简化jsp页面中java代码的编写
语法:${表达式}
注意:jsp默认是支持el表达式的
忽略el表达式:
- 在page指令中添加
isELIgnored="true",忽略整个页面的el表达式 - 只忽略某一el表达式,可以通过
\${3>4},前面加个反斜杠\即可
el表达式在maven项目中无效,经过百度,发现,需要配置isELIgnored和web.xml,经过测试只配置isELIgnored就可以。
3.1 使用
实际使用:
- 运算:后面括号里表示该运算符也可以替换成括号里内容
- 支持算术运算符:+,-,*,/(div),%(取余,mod)
- 比较运算符:>,<,<=,>=,==,!=
- 逻辑运算符:&&(and),||(or),!(not)
- 空运算符:empty
- 功能非常强大,用于判断字符串和集合以及数组是否为null并且其长度是否为0
- 举例,如
${empty array},只要array不为空,就为true(此处让我联想到了php中的empty()方法)
- 获取值
- el表达式只能从域对象(4个)中获取值
- 语法1:
${域名称.键名}:从指定域中获取指定键的值。- 如果没有该值,就会返回空字符串
- 语法2:
${键名}:依次从最小的域中查找是否有该键对应的值,直到找到第一个值为止。 - 域名称:
- pageScope:从pageContext域中获取值
- requestScope:从request域中获取值
- sessionScope:从session域中获取值
- applicationScope:从application(ServletContext)域中获取值
- 如在request域中存储了name=胡列娜,我们可以通过${pageScope.name}来获取
- 获取对象、List集合、Map集合的值
- 对象:
${域名称.键名.属性名},属性名的定义参照这篇文章- 本质上会调用对象的getter方法
- List集合:
${域名称.键名[索引]}- 如果索引越界就会返回空字符串
- Map集合:
${域名称.键名.key名称}或者${域名称.键名["key名称"]}
- 对象:
当然,以上的域名称都是可以省略的。
| |
3.2 隐式对象
概念:el表达式中不需要创建的、直接拿来用的对象
el表达式中有11个隐式对象(类似于jsp中的内置对象)
- pageContext
- JSP 页的上下文。它可以用于访问 JSP 隐式对象,如请求、响应、会话、输出、servletContext 等。例如,${pageContext.response} 为页面的响应对象赋值。
- param
- 表达式 ${param.name}相当于 request.getParameter (name)。
- paramValues
- 表达式 ${paramvalues.name} 相当于request.getParamterValues(name)。
- header
- 表达式 ${header.name} 相当于 request.getHeader(name)。
- headerValues
- 表达式 ${headerValues.name} 相当于 request.getHeaderValues(name)。
- cookie
- 表达式 ${cookie.name.value} 返回带有特定名称的第一个 cookie 值。如果请求包含多个同名的 cookie,则应该使用 ${headerValues.name} 表达式。
- initParam
- 将上下文初始化参数名称映射到单个值(通过调用 ServletContext.getInitparameter(String name) 获得)。
- pageScope
- requestScope
- sessionScope
- applicationScope
具体可参照360百科
四、JSTL
4.1 了解
概念:JavaServer Pages Tag Library,jsp标准标签库
jstl是由apache组织提供的开源的,免费的jsp标签
作用:用于简化和替换jsp页面上的java代码
步骤:
- 导入jar包
- 引入标签库:通过taglib指令<@ taglib %>
- 使用标签
4.2 常用标签
详细参照这里
常用的jstl标签
- if:相当于java代码的if语句
- 属性:test是必需属性,可以结合el表达式一块使用
- 如果test是true,则显示标签体内容
- 如果test是false,则不显示标签体内容
- 注意:c:if没有else情况,如果想要实现else,可以再定义一个c:if标签
- 属性:test是必需属性,可以结合el表达式一块使用
- choose:相当于java代码的switch语句
- 使用choose标签声明:相当于switch声明
- 使用when标签做判断:相当于case
- 使用otherwise标签做其他情况的判断:相当于default
- forEach:相当于java代码的for语句
- 普通for循环,如
for(int i=0;i<10;i++)- begin:开始值,相当于上面的0
- end:结束值,10
- var:临时变量,i
- step:步长,1
- varStatus:循环状态对象(这个在普通for循环中,使用很少)
- index:容器中元素的索引,从0开始
- count:表示循环次数,从1开始
- 增强for循环,如
List<Person> list;for(Person p:list)- items:容器对象,list
- var:容器中元素的临时变量,p
- varStatus
- 普通for循环,如
if标签代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>jstl</title>
</head>
<body>
<%--
c:if这标签
必需属性:test,接收布尔表达式,如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容
一般情况下,这个test属性值会结合el表达式一起使用
实现:判断request域中的一个list集合是否为空,如果不为null,则显示遍历集合
注意:c:if标签没有else情况,想要else情况,则可以再定义一个c:if标签
--%>
<%
List list=new ArrayList();
list.add("hhh");
request.setAttribute("list",list);
%>
<c:if test="true">我是真</c:if>
<c:if test="${not empty list}">
遍历集合
</c:if>
<c:if test="${3%2==0}">
3%2==0
</c:if>
<c:if test="${3%2!=0}">
3%2!=0
</c:if>
</body>
</html>choose标签代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>jstl</title>
</head>
<body>
<%--完成数字编号对应星期几的案例--%>
<%
request.setAttribute("day",54);
%>
<c:choose>
<c:when test="${day==1}">星期一</c:when>
<c:when test="${day==2}">星期二</c:when>
<c:when test="${day==3}">星期三</c:when>
<c:when test="${day==4}">星期四</c:when>
<c:when test="${day==5}">星期五</c:when>
<c:when test="${day==6}">星期六</c:when>
<c:when test="${day==7}">星期七</c:when>
<c:otherwise>输入有误</c:otherwise>
</c:choose>
奥利给
</body>
</html>forEach标签代码
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>jstl</title>
</head>
<body>
<%--相当于for(int i=0;i<10;i++)--%>
<c:forEach begin="1" end="10" var="i" step="1" varStatus="s">
${i},${s.index},${s.count}<br>
</c:forEach>
<%
ArrayList list=new ArrayList();
list.add("1");
list.add("2");
request.setAttribute("list",list);
%>
<%--相当于for(int i:list)--%>
<c:forEach items="${list}" var="i" varStatus="s">
${i},${s.index},${s.count}<br>
</c:forEach>
</body>
</html>4.3 练习
需求
在request域中,有一个存有User对象的List集合,需要使用jstl和el将List集合数据展示到jsp页面的表格table中
实现
<%@ page import="java.util.ArrayList" %>
<%@ page import="demo03.domain.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>案例</title>
</head>
<body>
<%
ArrayList<User> list = new ArrayList<User>();
// 可以通过构造方法,修改需要重启服务器,懒得整了,直接用
User u1 = new User();
u1.setId(1);
u1.setUser("胡列娜");
u1.setPassword("玄机中最美");
User u2 = new User();
u2.setId(2);
u2.setUser("江厌离");
u2.setPassword("姐姐中最善良");
list.add(u1);
list.add(u2);
request.setAttribute("list", list);
%>
<table border="1">
<tr>
<th>id</th>
<th>用户名</th>
<th>密码</th>
<th>时间</th>
</tr>
<c:forEach items="${list}" var="u" varStatus="s">
<c:if test="${s.count%2==0}">
<tr bgcolor="#f0f8ff">
<td>${u.id}</td>
<td>${u.user}</td>
<td>${u.password}</td>
<td>${u.time}</td>
</tr>
</c:if>
<c:if test="${s.count%2!=0}">
<tr bgcolor="#f5f5dc">
<td>${u.id}</td>
<td>${u.user}</td>
<td>${u.password}</td>
<td>${u.time}</td>
</tr>
</c:if>
</c:forEach>
</table>
</body>
</html>