首页 > 代码库 > Java笔记(9)

Java笔记(9)

JSP 存在两种 开发模式
Model1 : JSP + JavaBean 
* 不适合开发业务逻辑特别复杂web应用 ----- 业务逻辑复杂,控制代码多,而在jsp中编写控制代码,十分不便


Model2 : JSP + JavaBean + Servlet 
符合MVC设计模式 
JSP(View视图功能):负责页面显示
JavaBean(Model 模型功能):负责数据封装和处理
Servlet(Controller 控制器功能):连接模型和视图,对整个业务流程进行控制,调用JavaBean封装处理数据,调用JSP显示页面 


MVC模式 、JavaEE体系结构三层架构 关系?
三层架构:web层、业务层、数据层
MVC : Model 、View 、Controller
业务层和数据层 --- Model
web层 Servlet ---- Controller
web层 JSP ---- View


model1 分工
JSP 负责页面显示,跳转,调用JavaBean
JavaBean 封装和处理数据


什么是JavaBean?
1、是一个Java 类
2、必须存在无参数构造方法 
3、所有成员变量都是private 
4、如果想private成员变量被外界访问,提供public的get和set方法


单例?
1、private 构造方法
2、private static 实例对象
3、public static 对象访问方法 


JavaBean属性
1、必须小写字母开始 name 、age 合法的, City 是不合法属性 ---- 规范的 
2、每个属性可以提供public的getter和setter方法 
* 命名规则:属性name ---- 方法getName 、setName 
将属性首字母大写,在属性名前拼接get或set


在JSP规范中,提供三个与JavaBean相关 动作标签
<jsp:useBean>
<jsp:setProperty>
<jsp:getProperty>




<jsp:useBean id="person" scope="page" class="cn.itcast.javabean.Person"></jsp:useBean>
翻译为
      cn.itcast.javabean.Person person = null;   ----- 创建Person对象 null
      synchronized (_jspx_page_context) {
        person = (cn.itcast.javabean.Person) _jspx_page_context.getAttribute("person", PageContext.PAGE_SCOPE); ---- 获得page范围person属性
        if (person == null){  ----- 判断获得person对象是否为null 
          person = new cn.itcast.javabean.Person();  ----- 如果person对象为null,创建新的对象 
          _jspx_page_context.setAttribute("person", person, PageContext.PAGE_SCOPE); ---- 将创建person放入page范围 
        }
      }
代码效果:从page返回获得person对象,如果不为null 直接使用,如果为null 创建新的Person对象 


* 因为实际开发中,主要应用model2,所有javabean相关标签已经很少使用


setProperty特殊用法
<jsp:setProperty property="*" name="person" />  ---- 根据请求数据自动封装 Person属性 
* 因为model2 ---- 该标签也不经常使用 


Model1案例:计算器
1、输入字母 -- 报错
2、精度问题


非法数据 ---- 有效数据校验(客户端校验JS ,服务器端校验) ------ 服务器端校验必须的 
通过 JavaScript在客户端 校验数据合法性 
1) 将被校验数据 添加 id属性 
2) 在form标签中 添加 onsubmit函数  ----- onsubmit="return checkForm();"
3) 通过 JS编写 checkForm函数 
取得校验字段值 document.getElementById(id).value 


精度问题 : java.math.BigDecimal
add(BigDecimal augend) 
subtract(BigDecimal subtrahend) 
multiply(BigDecimal multiplicand) 
divide(BigDecimal divisor, int roundingMode) 


* 1/3 使用 BigDecimal会报错 ---- 四舍五入


什么是内省?为什么学内省? 
JDK提供一套JavaBean操作API ,对JavaBean通过反射技术操作,内省是一套基于反射技术,更便于操作JavaBean API 。


JavaBean属性计算方法 ?
1、通过Introspector获得 JavaBean 类相关信息
2、通过BeanInfo 获得方法描述器和属性 描述器 
getMethodDescriptors() 
getPropertyDescriptors()  ----重点 


JavaBean属性不是同成员变量计算的,是通过get和set方法计算
例如:getName ----- 去掉get将 Name首字母小写 ---- name属性
setAge ---- 去掉set 将Age的首字母小写 ---- age属性
* 每一个对象继承Object,继承getClass()方法 -- 得到class属性


将Map的key 与 JavaBean对象属性进行匹配,自动将value保存到对象中  ---- 内省应用 
* <jsp:setProperty property="*" /> 原理


在Model1中,完成form参数 ---- JavaBean自动封装  
<jsp:setProperty property="*" name="calculator" />


在Model2中 不可以使用 jsp标签,在Servlet中完成 将form数据 封装 javabean对象
使用内省技术(基于反射,方便操作javabean API )完成form数据 封装 javabean对象 -------- 内省在编写代码上复杂
BeanUtils 工具包 (完成对javabean封装操作)


BeanUtils一套开发包,Apache公司提供 ,专门进行javabean操作,在web层各种框架中 被使用 例如:struts 使用BeanUtils操作JavaBean 
采用BeanUtils编写快速入门案例
1、下载BeanUtils的jar :commons-beanutils 、commons-logging
BeanUtils依赖 Logging的jar包 
2、将beanutils和logging的 jar包复制 工程/WebRoot/WEB-INF/lib
3、编写BeanUtils的封装程序 
BeanUtils.populate(person, request.getParameterMap());


如果在Person类添加特殊类型Date类型,对于特殊类型如何封装 ?
1、自定义转换器 ---- 需要实现Converter接口 
2、在调用populate方法前,注册转换器 
ConvertUtils.register(Converter converter, Class clazz) 


结论:
1、如果form参数是String类型,javabean属性String类型 ---- 调用BeanUtils.populate 将form数据封装 javabean
2、如果JavaBean属性类型不是String ---- 将form数据封装javabean 需要转换器 ----- 在BeanUtils API 提供很多默认转换器(完成常见转换)
3、如果需要转换类型非常特殊,可以通过自定义转换器完成 定义类实现Converter接口,实现convert方法 ,在populate调用之前通过ConvertUtils.register注册转换器


Model2: JSP + JavaBean + Servlet 职责分工
JSP 页面显示
JavaBean 封装数据 处理数据
Servlet 控制整个处理流程,调用JavaBean,调用JSP


MVC设计模式
软件开发23种标准设计模式 ---- 解决问题方法 
MVC不属于 软件23种设计模式 


MVC架构模式 将web应用资源分为三个部分 : Model、View 、Controller 分工明确
为什么要使用MVC? 分工明确,便于维护


----------------------------------------------------------------------------------------------------


基于model2 案例:用户注册和登陆 
1、将用户信息保存xml文件中 ----- xml文件读写 XML PULL 
2、注册: 将用户信息写入xml --- xml增加节点操作  ----- 一次性验证码
3、登陆:XML中节点查询 ------ 记住用户名和密码 


注册功能:regist.jsp页面(注册form) ----- RegistServlet ---- 封装数据User ---- 将User信息写入XML UserModel ---- 注册结果页面


1、创建 web工程 day09user
2、导入jar包 xpp3.jar beanutils.jar logging.jar 复制WebRoot/WEB-INF/lib
3、创建package结构 
公司.部门.项目.分包  例如:cn.itcast.user.分包
因为工程采用MVC架构 


cn.itcast.user.controller
cn.itcast.user.model
cn.itcast.user.view
cn.itcast.user.utils


编写注册功能:
regist.jsp ---- 规定一些user有哪些数据 ?用户名、密码、邮箱、验证码 --- 引入验证码图片 --- 点击切换效果
RegistServlet 控制器
User 存放数据JavaBean
UserModel 处理数据JavaBean ---- 使用pull解析器 将数据写入xml *** 将xml中数据解析 List对象,将List对象数据序列化Xml
注册成功 跳转 login.jsp




编写登陆功能
login.jsp 登陆form 
LoginServlet 控制器
User 封装数据
UserModel 进行登陆处理 
成功 --- 跳转index.jsp 
失败 --- 跳转login.jsp


用户注销 ---- 原理注销session


记住用户名和密码 
原理:向客户端写cookie信息
什么情况下 需要记住用户名和密码:1、用户勾选记住checkbox 2、登陆成功


* 自动登陆 --- Filter 


cookie文件不能保存中文!!!
解决:手动对中文编码写入cookie,读取cookie时,进行手动解码


练习:在注册页面验证两次密码是否一致 JavaScript


练习任务:
1、计算器
2、用户登陆注册


理论:什么JSPmodel1 和 model2 、MVC