第13天 JSTL标签、MVC设计模式、BeanUtils工具类
目录
1.2. c:choose c:when c:otherwise 2
知识点回顾:
pageContext对象的三个功能?
获取其他八个内置对象
给四个容器设置数据
从四个容器取出数据
什么是jsp中的指令,说出它的格式是什么?
格式:<%@ 指令的名称 key=value…. %>
Page指令的作用,taglib指令的作用,include指令的作用?
Page:对页面进行设置
Include:引入其他页面合成一个页面
Taglib:导入标签库和函数库
EL表达式的主要作用?
输出数据,容器(page request session servletContext)
JSTL的核心标签库使用(重点:必须掌握)
JSTL的由来:
为什么要使用标签和函数(主要指JSTL标签和EL表达式),代替jsp页面中java代码?
提供一些简单的标签和函数,让java程序员和前端工程师都可以使用,前端和后台的配合比较的方便。
学习的途径:通过《第8章 标准标签库_0519.doc》这篇文档进行学习
创建新工程:
- 将jar包导入工程
2)API文档
手动测试
- 引入标签库到jsp页面中
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
prefix 表示的是标签的小名。
Uri 表示的是引入那个标签库
当我们使用快捷键出现提示的时候,表示引入标签库成功。
注意版本:
JSTL标签库提供5大功能(了解):
core:jstl的核心标签库,使用最多(必须掌握)
fmt:国际化的标签(数字的格式化和日期的格式化)
functions:jstl中提供的函数库 (现在在页面上显示数据,要么后台直接处理好(json),要么前端工程师使用javascript进行处理)
sql:jstl提供的在jsp页面上书写sql,操作数据库,目前已经不再使用
补充:以前的设计模式,jsp页面可以处理所有的请求、响应、业务逻辑。。。,所以在jsp中可以操作数据库,但是现在的设计模式,不允许在jsp页面处理数据的操作,所以,sql的jstl标签,不允许使用那个。
xml:jstl操作xml文件的。目前已经不再使用(json数据格式更加简单好用)
注意:jstl+el 通常一起使用。就是减少jsp页面的java代码。
c:if标签(重点:必须掌握)
作用:相当于java代码中if语句
使用c:if 标签,在JSP页面上可以完成if判断。注意:在JSTL核心标签库中没有c:else.
只有if(){}结构 没有 if(){}else{}结构
写法:<c:if 属性=属性值。。。 > 条件成立的时候,执行标签中的内容 </c:if>
API截图:
Test:属性:判断是否执行标签内的内容(true——执行标签中的内容,false,不执行)。
Var:用来保存test属性的结果(使用var属性给他取个名字),这个结果可以保存到指定的容器中。(如果没有指定容器,默认存入page容器中)
Scope:指定容器,保存数据
是否支持EL表达式:当前这个属性中是否可以书写EL表达式
属性类型:当前属性可以接受一个什么类型的值
C:if标签异常,如果test属性接受一个不是boolean类型的数据,发生类型转换异常
演示标签:
测试代码:
<%-- 演示if标签 --%>
<%-- test:一定要有 --%>
<c:if test="true">
测试if标签,true
</c:if>
<hr>
<c:if test="false">
测试if标签,false
</c:if>
<hr>
<c:if test="${false }">
测试if标签,使用EL
</c:if>
<hr>
<c:if test="${true }" var="flag">
测试if标签,测试var属性
</c:if>
<%-- var 属性:test的执行结果,会保存在容器中,需要给他起个名字,使用var来完成 --%>
<%-- flag,那么需要知道这个数据到底存在哪个容器中,通过EL表达式获取数据,可以指定容器获取--%>
${pageScope.flag }
<hr>
<c:if test="${true }" var="info" scope="session">
测试if标签,测试scope属性
</c:if>
${sessionScope.info }
效果:
c:choose c:when c:otherwise(重点:必须掌握)
c:choose c:when c:otherwise 相当于:
if(){
}else if(){
} else if(){
}
。。。。。
else{
}
<c:choose>标签它必须与<c:when>和<c:otherwise>标签一起使用,它表示哪些when和otherwise是在一组的。
使用<c:choose>,<c:when>和<c:otherwise>三个标签,可以构造类似 "if-else if-else" 的复杂条件判断结构。
c:when ,c:otherwise 属于同一级别标签。同时是c:choose的子标签 给
演示标签:
测试代码:
<%-- 演示,choose when otherwise标签 --%>
<%
pageContext.setAttribute("num", 5);
%>
<%
pageContext.setAttribute("flag", 1);
%>
<%-- 当when中有一个符合条件的时候,下面的内容就不再执行 --%>
<c:choose>
<c:when test="${num == 1 }">星期一</c:when>
<c:when test="${num == 2 }">星期二</c:when>
<c:when test="${num == 3 }">星期三</c:when>
<c:when test="${num == 4 }">星期四</c:when>
<c:when test="${num == 5 }">星期五</c:when>
<c:when test="${num == 6 }">星期六</c:when>
<c:when test="${num == 7 }">星期日</c:when>
<c:when test="${flag == 1 }">白天</c:when>
<c:when test="${flag == 2 }">黑夜</c:when>
<c:otherwise>参数不合法</c:otherwise>
</c:choose>
效果:
异常:使用when otherwise标签的时候,一定要写在choose标签内,不然报错
异常:一组choose中有多个otherwise,就出现异常。
异常:
c:set和c:out标签
c:set它可以给某个容器中保存数据,或者去修改某个对象的属性值。
注:相当于代替了pageContext.setAttribute
API截图:
Var:声明了一个变量空间,用来存储数据(value属性的值)的
Value:要保存的数据
Scope:指定保存在那个容器中
Target:指定要修改的对象
Property:指定要修改的属性
演示标签:
测试代码:
<%-- 演示set标签存数据 --%>
<%-- var : 声明一个变量空间,然后用来保存数据(数据最终是保存在容器中) int i = 0; --%>
<%-- value: 需要被保存的数据 --%>
<%-- scope:指定数据存放的容器 --%>
<c:set var="root" value="${pageContext.request.contextPath }" scope="session"></c:set>
pageScope:${pageScope.root }<br>
sessionScope:${sessionScope.root }
<hr>
<%-- 演示set标签修改对象的属性 --%>
<%
Person p = new Person();
pageContext.setAttribute("p", p);
String str = "";
pageContext.setAttribute("str", str);
%>
${p }
<c:set target="${p }" property="name" value="毛毛"></c:set>
<c:set target="${p }" property="age" value="35"></c:set>
${p }
效果:
异常原因: 修改对象属性的时候不能修改它所在的域对象。Var 属性和scope属性必须一起使用。
异常原因:Target属性和property属性是要一起使用的,如果修改的数据不是自定义对象,那么就会报错
c:out 它可以把数据输出到页面上,相当于JSP的内置对象out
API截图:
演示标签:
测试代码:
<%
String str = null;
pageContext.setAttribute("str", str);
%>
<c:out value="${str }" default="《蓝翔挖掘机职业技术学校》"></c:out>
<hr>
<%-- escapeXml="true" : 不解析html,直接输出文本内容 --%>
<%-- escapeXml="false" : 解析html,直接输出文本内容 --%>
<c:out value="<a href='http://www.baidu.com'>百度</a>" escapeXml="false"></c:out>
效果:
c:forEach标签(重点:必须掌握)
c:forEach 循环的标签。 实现 java中for循环的功能
API截图:
Foreach不循环对象(集合、数组)的情况下,单单控制循环的次数。
Var:用来设置,保存在page容器中的数据的名称
测试代码:
<%-- foreach不循环对象,控制循环次数 --%>
<%-- begin :循环开始 int i = 1--%>
<%-- end :循环结束 i<=5--%>
<%-- step:步长,
次,控制循环,隔几次循环执行标签中的内容
step="1" :隔一次循环,执行一次标签中的内容, 1 2 3 4 5 M M M M M
step="2" :隔两次循环,执行一次标签中的内容, 12 34 5 M M M
step="3" :隔三次循环,执行一次标签中的内容, 123 45 M M
step="4" :隔四次循环,执行一次标签中的内容, 1234 5 M M
step="5" :隔五次循环,执行一次标签中的内容, 12345 M
step="6" :隔五次循环,执行一次标签中的内容, 12345 M
小结:step,控制隔几次循环执行标签中的内容
--%>
<%
for(int i = 1;i<=5;i++){
}
%>
<%-- var :用来保存数据(当前循环的控制变量)的,相当于i++中的i --%>
<%-- varStatus:保存了循环的状态信息(循环索引号、当前循环的次数、是否是第一次循环,是否是最后一次循环) --%>
<c:forEach begin="1" end="5" step="1" var="p" varStatus="sta">
${sta.index}
${sta.count}
${sta.first}
${sta.last}<br>
</c:forEach>
效果:
Foreach循环对象的情况下(数组,集合:list和map)
测试代码:
<%-- items:用来指定要循环的对象 --%>
<%
int[] arr = {42,67,24,51};
pageContext.setAttribute("arr", arr);
%>
<%-- var="num" :在循环对象的时候,他保存的都是对象中的元素 --%>
<c:forEach items="${arr }" var="num">
${num }
</c:forEach>
<%
List list = new ArrayList();
list.add("游戏币");
list.add("纸");
list.add("娃娃");
list.add("润滑油");
pageContext.setAttribute("list", list);
%>
<c:forEach items="${list }" var="listNum">
${listNum }
</c:forEach>
<hr>
<%
Map map = new HashMap();
map.put("vg1", "黄瓜");
map.put("vg2", "苦瓜");
map.put("vg3", "大宝");
map.put("vg4", "眉笔");
pageContext.setAttribute("map", map);
%>
<c:forEach items="${map }" var="ppp">
${ppp }
${ppp.key }
${ppp.value }<br>
</c:forEach>
效果:
jstl中的其他标签(了解)
<c:forTokens是对字符串进行操作的一个标签。
<c:forTokens 它指的是把 itmes中提供的字符串,使用delims提供的分隔符进行分割
起到做到字符串的分割作用。
假设"a,b,c,d" 可以使用逗号进行字符串的分割 ---------> a b c d
测试代码:
效果:
<c:import url=""></c:import>可以在当前页面引入其他的页面
Include指令,可以引入其他页面,静态引入
<jsp:include> , 可以引入其他页面,动态引入
用那个随你喜欢,随你开心。
同样功能实现,它的使用并没有区别,知识新技术出现之后,同样实现了老技术功能。
测试代码:
效果:
<c:catch var="ex"></c:catch> 捕获异常的 ---当页面某些位置可能出现异常的时候,可以使用c:catch.抓取异常,不会报错500。
效果:
<c:redirect context="" url=""></c:redirect> 完成重定向的
什么时候,使用相对路径,什么时候,使用绝对路径?
使用转发 request.getrequsetDispather("你要访问的资源路径:/index.jsp")
在页面上,使用a标签(href)或者使用form(action)表单的是时候,写项目名称/资源路径(例如:/itcast-jstl2/index.jsp)
代码演示:
<%-- context : 重定向要跳转的项目名称 url :请求地址注意:两个属性,必须加上/--%>
<c:redirect context="/day12" url="/head.jsp"></c:redirect>
效果:
异常原因:当前标签在使用的时候,context 和url属性开头必须使用"/"。
<c:url></c:url> 完成Cookie禁用之后的url重写的
把一个url进行重写。
cookei被禁用之后。session不能使用。因为少了jsessionid
在一个链接上,去添加jsessionid。
测试代码:
效果:
开发模式&JavaBean
JavaBean介绍
JavaBean:它是一个简单的Java类。属性要求是private 这个类中拥有get或set方法即可,但要求这个类必须有一个公开的空参数的构造函数。
特点:1、一定要有一个无参数的构造函数---public 无参的构造函数
2、属性必须是 private的。
3、为这个私有的属性,提供公有的访问方法getter ,setter。
注意:目前使用的javaBean是用来封装数据的(处理业务逻辑,spring框架)。
提示:后期开发中,这些类一般会保存在名称为domain或者 beans.或者entity 或者pojo包中,这是一个开发的习惯,你在公司,拿到公司项目的所有封装数据的Javabean一般都会在这里包中。
不封装数据的javabean,spring学习的时候,才会了解。
<bean>
JSP开发模式一(早期开发模式,现在已经淘汰了)
在JSP刚刚推出的时候,基于JSP出现了JSP开发模式一:
使用JSP处理用户的请求以及响应,使用JavaBean来封装用户的数据
这种模式问题:
- java代码、html代码、混杂在一起,代码阅读性差
- 维护不方便(前端和后台开发人员都在的情况下,才能维护页面(jsp))
- 耦合性高(处理请求,处理响应,处理业务方法 操作数据库方法都写在jsp中)
jsp开发模式一:它可以解决一些小型的需求,但是后期项目需求越来越复杂,这种开发模式已经不行了。JSP页面中的JAVA代码太多难以维护和升级。
耦合性高:所有的代码都拥挤到一个类或者jsp文件中,导致,只要某一个部分出问题,其他功能,也无法执行。
MVC设计(开发)模式(重点:必须掌握)
掌握:可以画出MVC设计模式的流程图
MVC设计模式:
M:model 模型--- 数据模型(JAVABean)。 存取数据。
V:view 视图 主要是用来展示数据和页面效果的,jsp
C:Controller 控制器(servlet)。处理请求,调用业务处理方法,给出浏览器响应的作用
控制器:struts2:action springMVC:Controller
JSP开发模式二:jsp model 2:
总结设计模式实现:
使用JSP显示数据,把JSP当做MVC中的view层。
使用JavaBean封装数据,它是MVC中的Model。模型层
使用Servlet处理用户的请求和响应。它是MVC中的Controler 控制层
优点:耦合性低,可维护性高。程序整体非常清晰。
使用接口开发:
接口作用:定义规则,拓展功能
接口定义,规定了方法的返回值,方法的名称,定义方法的参数列表(接口一般由技术总监或者项目经理定义好),接口定义好之后,所有人拿到接口相关的开发文档,根据文档进行开发
案例—注册功能(重点:必须掌握)
掌握:动手写出来。
分析:注册功能流程是什么?
流程:先做什么,在做什么,然后做什么
- 填写注册信息
- 启动注册检查数据库中是否已经存在
- 如果存在,提示用户,用户名已经存在(dao service web 浏览器)
以后分析任务功能实现的通用思路:
第一:用户的操作
第二:服务器的处理
第三:给用户响应
画图分析:
功能(需求)分析:
- 用户的操作(页面需要什么东西)(浏览器)
- 服务器接收数据(校验哪些数据)(servlet)
- 将数据封装到那个自定义对象中(servlet)
- 处理业务逻辑的方法(例如:注册,用户名不重复,才可以注册)(service)
- 要操作数据库的那些表,并且数据要设置成什么状态(dao)
1、数据库准备:
create database day13;
use day13;
CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`password` varchar(32) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`sex` varchar(4) DEFAULT NULL,
`email` varchar(100) DEFAULT NULL,
`hobby` varchar(120) DEFAULT NULL,
`address` varchar(200) DEFAULT NULL,
`description` varchar(200) DEFAULT NULL,
`birthday` date DEFAULT NULL,
PRIMARY KEY (`id`)
)
分析注册案例开发准备:
- 创建一个web工程
- 准备jar包:Mysql数据库驱动包,c3p0jar包
- 准备配置文件:c3p0-config.xml
- 准备工具类:JDBCUtils工具类
- 准备一个与数据库user表对应的javaBean,User类
回顾jdbc的编程步骤(书写注册Dao)
1、加载驱动 ; Class.forname("驱动类的全路径");
2、建立连接;Connection conn = DriverManager.getConntection(url,user,password);
url: mysq===== jdbc:mysql://localhost:3306/数据库名
3、获取statement对象; Preparedstatement 可以防止sql注入,预编译的sql执行器。
String sql = "select * from user where username=?"; 如果需要参数使用问号进行替代
Preparedstatement pstmt = conn.preparedStatement(Sting sql);
pstmt.setXXX(问号的顺序,具体的值); 问号只能是要替换的参数,不能是表名
4、执行sql
ResulstSet rs = pstmt.executeQuery(); 执行select 操作
pstmt.executeUpate(); 执行 insert ,update, delete 操作
5、如果是select 语句,就有结果集
while(rs.next()){
rs.getXXX("列名,别名");
}
6、关闭连接;
代码演示:
package cn.itcast.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import cn.itcast.dao.UserDao;
import cn.itcast.domain.User;
import cn.itcast.utils.JDBCUtils;
public class UserDaoImpl implements UserDao {
@Override
public User findUserByName(String name) {
//定义一个链接对象
Connection conn = null;
//定义一个操作sql语句的对象
PreparedStatement stmt = null;
//定义一个封装结果集的对象
ResultSet rs = null;
//获取连接
try {
conn = JDBCUtils.getConnection();
//定义一个sql语句
String sql = "select * from user where name = ?";
//获取操作sql语句的对象
stmt = conn.prepareStatement(sql);
//设置sql语句的参数
stmt.setString(1, name);
//执行sql语句
rs = stmt.executeQuery();
//rs.next()如果有数据,返回一个非空的User,用户已经存在
//如果没有数据,返回一个null;
if(rs.next()){
return new User();
}else{
return null;
}
} catch (SQLException e) {
e.printStackTrace();
return null;
}finally{
//释放资源
JDBCUtils.release(rs, stmt, conn);
}
}
}
效果:
注册页面展示:
验证码servlet配置:
BeanUtils的使用(重点:必须掌握)
BeanUtils工具类介绍
在页面上的form表单提交数据之后,一般都需在Servlet中的使用getParameter方法获取表单中的所有数据。如果提交的数据量过大,获取的重复代码会很多,封装数据到javabean的代码繁琐。
解决方案就是使用工具类——BeanUtils。
Apache提供的很多技术之间通过都会有jar包的相互依赖。
解压压缩包:
复制到当前项目的WEB-INF下的lib中。
BeanUtils类使用
BeanUtils类的功能是把一个Map集合中的数据,封装到一个JavaBean上。
使用BeanUtils工具类中的populate方法就可以把Map集合中的数据封装到指定的bean上。
注意:Map中的key名称(表达中name值)必须和bean对象的属性名一致。
代码演示:
效果:
通过上面测试发现,只要能获取到请求参数,并且将数据封装的map集合中,那么使用BeanUtils封装数据就非常的方便。
Request对象就提供了这样一个方法:request.getParamterMap(); 获取用户提交所有数据,并且封装到map中返回,map中key就是表单标签的name的值。
如果使用beanUtils.popublate 需要表单中的name属性的值,和JavaBean里面的属性的名字要一致,才可把表单数据自动的封装到bean里面。
注意:如果map的值是多个内容。只会封装第一个。 如果是复选框,还需要自己去处理。
BeanUtils的使用总结
1、需要导入两个jar包
2、使用BeanUtils里面的populate方法
第一参数:数据要封装到的对象(User)
第二个参数:要被封装数据,这个数据存放在一个map集合中
最后就会把map中的数据,封装到bean对象中。
注册业务:(重点:必须掌握)
web层的servlet
package cn.itcast.servlet;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
import cn.itcast.domain.User;
import cn.itcast.service.UserService;
import cn.itcast.service.impl.UserServiceImpl;
public class RegisterServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//第一步:接受请求参数,校验验证码
//验证码,用户提交的,session中保存的
String checkImg = request.getParameter("checkImg");
String servletImg = (String)request.getSession().getAttribute("servletImg");
if(servletImg.equals(checkImg)){
//验证码通过
//第二步:封装数据到User对象
//bean:数据要被封装的对象
//properties(map):拥有数据的map集合
User u=new User();
//获取所有的请求参数的方法
Map<String, String[]> map = request.getParameterMap();
try {
BeanUtils.populate(u, map);
} catch (Exception e) {
e.printStackTrace();
}
//数据封装中,爱好数据缺失,只能单独再封装爱好
String[] values = request.getParameterValues("hobby");
String hobby = "";
for (String str : values) {
hobby = hobby +","+ str;
}
hobby = hobby.substring(1);
u.setHobby(hobby);
//第三步:调用service方法注册用户
UserService userService = new UserServiceImpl();
int info = userService.register(u);
//第四步:根据返回值不同处理
if(info == 1 ){
//注册成功,跳转登录页面
//什么时候使用转发:需要向下一个servlet或者jsp发送数据的时候。
//什么时候使用重定向:不需要发送数据
response.sendRedirect(request.getContextPath()+"/login.jsp");
return;
}else if(info == -1){
//用户已存在
request.setAttribute("msg", "用户已存在");
request.getRequestDispatcher("/register.jsp").forward(request, response);
return;
}else{
//服务器异常,提示用户服务器忙
request.setAttribute("msg", "服务器忙");
request.getRequestDispatcher("/register.jsp").forward(request, response);
return;
}
}else{
//验证码不通过
request.setAttribute("msg", "验证码不通过");
request.getRequestDispatcher("/register.jsp").forward(request, response);
return;
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
-
service层
service的接口
package cn.itcast.service;
import cn.itcast.domain.User;
public interface UserService {
/**
* 注册用户的方法
* @param u
* @return
*/
int register(User u);
}
servcie的实现:
package cn.itcast.service.impl;
import cn.itcast.dao.UserDao;
import cn.itcast.dao.impl.UserDaoImpl;
import cn.itcast.domain.User;
import cn.itcast.service.UserService;
public class UserServiceImpl implements UserService {
@Override
public int register(User u) {
//查询数据库,当前用户是否存在
UserDao userDao = new UserDaoImpl();
int info = userDao.findUserByName(u.getName());
if(info != -1){
//如果不存在,注册用户
int register = userDao.register(u);
return register;
}
return info;
}
}
-
dao层
dao的接口
package cn.itcast.dao;
import cn.itcast.domain.User;
public interface UserDao {
/**
* 用户注册的方法
* @param u
* @return
*/
public int register(User u);
/**
* 根据用户名查询用户的方法
* @param name
* @return
*/
public int findUserByName(String name);
}
dao的实现:
package cn.itcast.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import cn.itcast.dao.UserDao;
import cn.itcast.domain.User;
import cn.itcast.utils.JDBCUtils;
public class UserDaoImpl implements UserDao {
@Override
public int register(User u) {
//加载驱动,c3p0做了
//定义数据库连接对象
Connection conn = null;
//操作sql语句的对象
PreparedStatement pstmt = null;
//获取连接
try {
conn = JDBCUtils.getConnection();
//定义一个sql语句
String sql = "insert into user values(null,?,?,?,?,?,?,?,?,?)";
//创建预编译对象pstmt
pstmt = conn.prepareStatement(sql);
//设置参数
pstmt.setString(1, u.getName());
pstmt.setString(2, u.getPassword());
pstmt.setInt(3, u.getAge());
pstmt.setString(4, u.getSex());
pstmt.setString(5, u.getEmail());
pstmt.setString(6, u.getHobby());
pstmt.setString(7, u.getAddress());
pstmt.setString(8, u.getDescription());
pstmt.setDate(9, u.getBirthday());
//执行
pstmt.executeUpdate();
return 1;
} catch (SQLException e) {
e.printStackTrace();
return -2;
}finally{
//释放资源
JDBCUtils.release(pstmt, conn);
}
}
@Override
public int findUserByName(String name) {
//定义数据库连接对象
Connection conn = null;
// 操作sql语句的对象
PreparedStatement pstmt = null;
//定义封装结果集的对象
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
String sql = "select * from user where name = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, name);
rs = pstmt.executeQuery();
if(rs.next()){
//表示有数据,重复
return -1;
}else{
return 1;
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("根据用户名查询用户失败");
}
}
}
包结构:
注意:注册的时候必须使用日期格式—— yyyy-MM-dd(BeanUtils默认支持的日期转换格式)
作业:
-
使用c:if标签或者c:choose c:when c:otherwise标签完成当天日期是星期几的判断。(10点积分)
- 试用<c:set>标签设置一个数字到page域对象中
- 试用c:if标签或者c:choose c:when c:otherwise标签完成星期的判断,显示数字对应的星期
-
使用c:foreach标签显示集合中的数据(10点积分)
- 定义一个list集合(集合内存放一年所有的月份)存放在page对象中
- 使用c:foreach遍历集合中的数据
- 定义一个map集合(集合存放了一年所有的季节)存放在page对象中
- 使用c:foreach遍历集合中的数据
根据老师的笔记画一个MVC设计模式的解析图(20点积分)
完成注册案例,使用BeanUtils工具类完成数据封装(参考课堂笔记)(60点积分)
邮箱地址E-mail:wangjianan@itcast.cn