`

day 09内省,BeanUtils,Double精度问题,JSP动作标签,MVC设计模式

 
阅读更多

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

double精度问题 : java.math.BigDecimal 不能传入double传入string
add(BigDecimal augend)
subtract(BigDecimal subtrahend)
multiply(BigDecimal multiplicand)
divide(BigDecimal divisor, int scale,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="*" /> 原理
@Test
public void demo2() throws Exception {
// 将map的值保存 相应对象属性中
Map<String, String> map = new HashMap<String, String>();
map.put("name", "mary");
map.put("city", "beijing");
map.put("hobby", "music");
// map.put("age", "20"); age的值 与 person中age属性类型不匹配,无法封装

Person person = new Person();

saveMapValue2Object(map, person);
System.out.println(person.getName());
System.out.println(person.getCity());
System.out.println(person.getHobby());
System.out.println(person.getAge());
}

// 将map中key 与 object 中属性进行匹配,将map对应value保存 obj属性值
private void saveMapValue2Object(Map<String, String> map, Object obj)
throws Exception {
// 1.内省获得javabean信息
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
// 2、通过beanInfo获得所有属性
PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
// 3. 遍历每一个属性
for (PropertyDescriptor propertyDescriptor : descriptors) {
// 用属性 去map寻找对应key
String name = propertyDescriptor.getName();
if (map.containsKey(name)) { // 属性在map中存在对应key
String value = map.get(name);
// 通过属性描述器 ,获得写入该属性方法
Method setMethod = propertyDescriptor.getWriteMethod();
// 利用反射设置value ---- value类型必须和属性类型匹配
setMethod.invoke(obj, value);
}
}
}

@Test
public void demo1() throws Exception {
// 通过 Introspector获得 BeanInfo信息
BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);
// 获得所有javabean属性描述器 , 每一个属性描述代表javabean一个属性
PropertyDescriptor[] propertyDescriptors = beanInfo
.getPropertyDescriptors();
// 计算javabean属性
System.out.println(propertyDescriptors.length);
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
System.out.println(propertyDescriptor.getName());
}
}

在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注册转换器
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");// 处理乱码

// 将form参数 自动封装 Person对象
Person person = new Person();

// 将String类型 转换 java.util.Date类型 --- 自定义转换器
// 在封装数据之前 ,注册转换器
ConvertUtils.register(new MyDateConverter(), Date.class);

try {
BeanUtils.populate(person, request.getParameterMap());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}

System.out.println(person.getName());
System.out.println(person.getCity());
System.out.println(person.getHobby());
System.out.println(person.getAge());
System.out.println(person.getBirthday());
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}

}

// 自定义转换器 实现 Converter接口
class MyDateConverter implements Converter {

@Override
// 需要 将value数据转换 c的类型
// value 是 String类型,将String转换Date类型
public Object convert(Class c, Object value) {
String s = (String) value; // 代表用户输入生日
DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
try {
Object result = dateFormat.parse(s); // 将String解析为 Date
return result;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}


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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    jsp中标签库的使用

    在JavaServer Pages (JSP)开发中,标签库是一个重要的组成部分,它允许开发者通过自定义标签来增强页面的可读性和可维护性。本篇文章将深入探讨如何在JSP中使用标签库,以及与之相关的技术和工具。 首先,我们要...

    jstl(jsp标准标签)

    - 易于维护:JSTL遵循MVC(Model-View-Controller)设计模式,将业务逻辑与视图分离。 - 可移植性:由于JSTL是标准库,可以在任何支持JSP的环境中使用。 - 提升性能:JSTL标签在服务器端被编译为Java代码,执行效率...

    beanutils 1.8 jar包+源码_阿锦—小白

    这对于提升编程技巧,尤其是对于Java基础和设计模式的理解具有极大的价值。通过阅读源码,开发者可以了解到如何处理异常、如何优化性能,以及如何编写更加健壮和灵活的工具类。 在实际项目中,BeanUtils常被用于...

    commons-beanutils-1.8.0

    然而,`commons-beanutils-1.8.0`版本可能存在一些已知的安全问题,如CVE-2019-10081,因此在新项目中,建议使用更安全的更新版本,如1.9.4或更高版本,以避免潜在的安全风险。 总结来说,Apache Commons BeanUtils...

    commons-beanutils 源码

    - BeanUtils在处理异常时,通常会捕获并包装为`BeanException`或`InvocationTargetException`,提供友好的错误信息,便于开发者定位问题。 - 例如,在调用不存在的属性或者类型转换失败时,会抛出相应的异常。 4....

    beanutils-1.8.3开发包

    BeanUtils包的核心概念是JavaBeans,这是一种遵循特定设计模式的Java类,主要用于封装数据和提供简单的操作方法。它通过getter和setter方法来访问和修改对象的属性。BeanUtils库则提供了一种便利的方式来操作这些...

    commons-beanutils-1.9.4-API文档-中文版.zip

    标签:beanutils、commons、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心...

    BeanUtils工具 .jar 包

    EL用于在JSP页面上表达式求值,而JSTL则是一组标准标签库,它们都与BeanUtils一起,帮助开发者更高效地处理页面逻辑和数据展示。 总的来说,BeanUtils工具包是Java开发者日常工作中不可或缺的工具,它极大地提高了...

    BeanUtils_beanutils_

    BeanUtils 是 Apache commons组件的成员之一,主要用于简化JavaBean封装数据的操作。它可以给JavaBean封装一个字符串数据,也可以将一个表单提交的所有数据封装到JavaBean中。使用第三方工具,需要导入jar包:

    beanutils源码

    6. **性能优化**:BeanUtils在设计时考虑了性能,例如通过缓存反射信息来减少重复的反射操作,提高效率。 通过对BeanUtils源码的学习,开发者不仅可以掌握这个工具库的使用,还能深化对Java反射、属性操作、异常...

    Commons BeanUtils 1.8.3 API

    Apache Commons BeanUtils 1.8.3 是一个强大的Java库,专为简化Java Bean操作而设计。这个API提供了大量的实用工具方法,使得开发者能够更加便捷地处理Java对象,特别是那些符合Java Bean规范的对象。在Java编程中,...

    beanutils 的jar包

    Apache Commons BeanUtils库正是为了解决这些问题而诞生的,它提供了简单易用的API,极大地简化了JavaBean的操作。本文将深入探讨BeanUtils的核心功能及使用方法。 BeanUtils是Apache Commons项目的一部分,它的...

    Beanutils基本用法.doc

    ### Beanutils基本用法详解 #### 一、Beanutils简介 Beanutils是一个强大的Java工具类库,主要用于简化JavaBean的属性操作。它提供了一系列的方法帮助开发者处理Bean的属性读取、设置以及转换等问题,尤其在处理...

    BeanUtils工具

    BeanUtils工具是一种方便我们对JavaBean进行操作的工具,是Apache组织下的产品。beanUtils 可以便于对javaBean的属性、对象进行赋值,beanUtils可以将一个MAP集合的数据拷贝到一个javabean对象中。

    运用MVC模式及JavaWeb三层框架的学生管理系统

    3.(重点)MVC设计模式的应用 (3)导入的jar包: commons-beanutils-1.9.3.jar,commons-logging-1.2.jar,logback-classic-1.1.7.jar,logback-core-1.1.7.jar,mysql-connector-java-5.0.8-bin.jar,slf4j-api-...

    commons-beanutils-1.9.4-API文档-中英对照版.zip

    标签:beanutils、commons、jar包、java、中英对照文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请...

    beanutils的jar包

    这个"beanutils的jar包"是1.93版本,它包含了对bean操作的各种方法,同时也集成了log包,方便开发者进行日志记录,这对于在不同JDK版本环境中调试和解决问题特别有帮助。 首先,BeanUtils库的核心功能在于提供了一...

    commons-beanutils-1.9.4

    Apache Commons BeanUtils是Java开发中一个非常重要的工具库,它为开发者提供了大量便捷的JavaBean操作功能。在本文中,我们将深入探讨`commons-beanutils-1.9.4`这个版本,了解其核心功能、使用场景以及如何在项目...

    BeanUtils_1.8.3帮助文档

    BeanUtils_1.8.3最新帮助文档,希望对给位有用。。。

    beanutils包

    《Apache Commons BeanUtils:构建网络框架的利器》 在Java编程领域,Apache Commons BeanUtils库是一个不可或缺的工具,尤其在构建网络框架时更是扮演着重要角色。BeanUtils库是Apache软件基金会开发的一个开源...

Global site tag (gtag.js) - Google Analytics