第02天 java基础加强
今日内容介绍
u Properties的基本操作
u 反射综合案例
u BeanUtils概述及使用
第1章 Properties的基本操作
1.1 Properties的概述及基本使用
1.1.1 Properties的概述
Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
特点:
1、Map接口的子类,map中的方法都可以用。
2、该集合没有泛型。键值都是字符串。
3、它是一个可以持久化的属性集。键值可以存储到集合中,也可以存储到持久化的设备(硬盘、U盘、光盘)上。键值的来源也可以是持久化的设备。
4、有和流技术相结合的方法。
1.2 常用方法
l public Object setProperty(String key, String value)调用 Map 的方法 put。
l public Set<String> stringPropertyNames()返回此属性列表中的键集,
l public String getProperty(String key)用指定的键在此属性列表中搜索属性
1.2.1 案例代码一
public class PropsDemo_01 {
@Test
public void demo01(){
//Properties对象 特殊Map<String,String>
//1 创建对象
Properties props = new Properties();
//2 设置数据
//props.put(key, value)
props.setProperty("k01", "v01");
props.setProperty("k02", "v02");
props.setProperty("k03", "v03");
//3 获得指定名称的数据
String prop = props.getProperty("k02");
System.out.println(prop);
//4获得所有名称,并遍历获得所有的数据
System.out.println("--------------");
Set<String> names = props.stringPropertyNames();
for(String name : names){
String value = props.getProperty(name);
System.out.println(name + " : " + value);
}
}
}
1.3 Properties加载文件写入文件
1.3.1 将集合中内容存储到文件
l store(OutputStream,commonts)
l stroe(Writer,comments);
把集合中的数据,保存到指定的流所对应的文件中,参数commonts代表对描述信息
1.3.2 案例代码二
@Test
public void demo01() throws Exception{
//将内容写入到文件
// * Properties 对应一种特殊文件:*.properties
// * 一行表示一个键值对,格式:k=v
//1 创建对象
Properties props = new Properties();
//2 设置数据
//props.put(key, value)
props.setProperty("k01", "v01黑马");
props.setProperty("k02", "v02程序员");
props.setProperty("k03", "v03");
//3 将props写入到硬盘
Writer writer = new OutputStreamWriter(new FileOutputStream("1.properties"),"UTF-8");
props.store(writer, "描述");
writer.close();
}
1.3.3 读取文件中的数据,并保存到集合
l load(InputStream)
l load(Reader)
把指定流所对应的文件中的数据,读取出来,保存到Propertie集合中
1.3.4 案例代码三
@Test
public void demo02() throws Exception{
//从properties文件中获得数据
//1 获得资源流
Reader reader = new InputStreamReader(new FileInputStream("1.properties"),"UTF-8");
//2 通过Properties对象加载流
Properties props = new Properties();
props.load(reader);
//3 遍历所有
for(String name : props.stringPropertyNames()){
String value = props.getProperty(name);
System.out.println(name + " @ " + value);
}
}
第2章 反射综合案例
2.1 需求分析
将javaBean的数据以配置文件的方式写进properties中,读取配置文件写进BeanConfig进行封装,在测试类中去读BeanConfig中封装的数据,并以反射的方式根据读取的数据创建对象,给对象的属性设置值。
反射的好处:我们不用将数据写死到java代码中,可以使用配置文件将数据写入配置文件中。提高了代码的灵活性。
2.2 案例代码四
2.2.1 首先编写JavaBean
User类
package com.itheima_02_demo.bean;
public class User {
private String uid;
private String username;
private String password;
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [uid=" + uid + ", username=" + username + ", password=" + password + "]";
}
}
Book类
package com.itheima_02_demo.bean;
public class Book {
private String bid;
private String title;
private String price;
public String getBid() {
return bid;
}
public void setBid(String bid) {
this.bid = bid;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
@Override
public String toString() {
return "Book [bid=" + bid + ", title=" + title + ", price=" + price + "]";
}
}
2.2.2 创建配置文件
bean.properties
id=id001
className=com.itheima.domain.User
data.properties
uid=u001
userName=jack
password=1234
2.2.3 编写BeanConfig类
目的: 封装2个Properties文件中的内容
import java.util.Properties;
public class BeanConfig {
private String id;
private String className;
private Properties props = new Properties();
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public Properties getProps() {
return props;
}
public void setProps(Properties props) {
this.props = props;
}
@Override
public String toString() {
return "BeanConfig [id=" + id + ", className=" + className + ", props=" + props + "]";
}
}
2.2.4 解析Properties
public class Demo_02 {
@Test
public void demo01() throws Exception{
//读取配置文件,获得具体信息
BeanConfig beanConfig = new BeanConfig();
//1 读取bean.properties文件,设置id和className属性
Properties beanProps = new Properties();
beanProps.load(new InputStreamReader(new FileInputStream("bean.properties"), "UTF-8"));
beanConfig.setId(beanProps.getProperty("id"));
beanConfig.setClassName(beanProps.getProperty("className"));
//2读取data.properties文件,设置getProps().setProperty()
Properties dataProps = new Properties();
dataProps.load(new InputStreamReader(new FileInputStream("data.properties"), "UTF-8"));
for(String name : dataProps.stringPropertyNames()){
String value = dataProps.getProperty(name);
beanConfig.getProps().setProperty(name, value);
}
System.out.println(beanConfig);
}
}
2.2.5 使用BeanConfig数据
import java.lang.reflect.Method;
import org.junit.Test;
import com.itheima.domain.BeanConfig;
public class Demo_03 {
@Test
public void demo01() throws Exception{
//模拟数据
BeanConfig beanConfig = new BeanConfig();
beanConfig.setId("id001");
beanConfig.setClassName("com.itheima.domain.User");
beanConfig.getProps().setProperty("uid", "u001");
beanConfig.getProps().setProperty("userName", "jack");
beanConfig.getProps().setProperty("password", "1234");
//使用数据创建JavaBean实例,并为JavaBean封装具体数据
//1 创建实例,使用反射
Class clazz = Class.forName(beanConfig.getClassName());
Object obj = clazz.newInstance();
//2 调用JavaBean的setter方法进行数据封装
for(String name : beanConfig.getProps().stringPropertyNames()){
String value = beanConfig.getProps().getProperty(name);
// 获得方法名称 : set前缀 + 大写首字母 + 其他内容
String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
// 调用setter方法
Method method = clazz.getMethod(methodName, String.class);
method.invoke(obj, value);
}
System.out.println(obj);
}
}
2.2.6 综合案例整合
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.Properties;
import org.junit.Test;
import com.itheima.domain.BeanConfig;
public class Demo_04 {
//获得配置文件具体数据
public BeanConfig getBean() throws Exception{
//读取配置文件,获得具体信息
BeanConfig beanConfig = new BeanConfig();
//1 读取bean.properties文件,设置id和className属性
Properties beanProps = new Properties();
beanProps.load(new InputStreamReader(new FileInputStream("bean.properties"), "UTF-8"));
beanConfig.setId(beanProps.getProperty("id"));
beanConfig.setClassName(beanProps.getProperty("className"));
//2读取data.properties文件,设置getProps().setProperty()
Properties dataProps = new Properties();
dataProps.load(new InputStreamReader(new FileInputStream("data.properties"), "UTF-8"));
for(String name : dataProps.stringPropertyNames()){
String value = dataProps.getProperty(name);
beanConfig.getProps().setProperty(name, value);
}
return beanConfig;
}
@Test
public void demo01() throws Exception{
//真实具体数据
BeanConfig beanConfig = getBean();
//使用数据创建JavaBean实例,并为JavaBean封装具体数据
//1 创建实例,使用反射
Class clazz = Class.forName(beanConfig.getClassName());
Object obj = clazz.newInstance();
//2 调用JavaBean的setter方法进行数据封装
for(String name : beanConfig.getProps().stringPropertyNames()){
String value = beanConfig.getProps().getProperty(name);
// 获得方法名称 : set前缀 + 大写首字母 + 其他内容
String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
// 调用setter方法
Method method = clazz.getMethod(methodName, String.class);
method.invoke(obj, value);
}
System.out.println(obj);
}
}
第3章 BeanUtils的概述及使用
3.1 BeanUtils的概述和简单使用
3.1.1 BeanUtils概述
BeanUtils 是 Apache commons组件的成员之一,主要用于简化JavaBean封装数据的操作。它可以给JavaBean封装一个字符串数据,也可以将一个表单提交的所有数据封装到JavaBean中。
3.1.2 需要的jar包
BeanUtils工具常用工具类有两个:BeanUtils、ConvertUtils[WU1] 。BeanUtils用于封装数据,ConvertUtils用于处理类型转换
常用方法:
setProperty(Object obj,String name,Object value) |
设置属性值,如果指定属性不存在,不抛异常 |
getProperty(Object obj,String name) |
获得属性值,如果指定属性不存在,抛方法找不到异常 |
3.1.3 案例代码五
使用BeanUtils把数据封装进User对象
import org.apache.commons.beanutils.BeanUtils;
import org.junit.Test;
import com.itheima_01_bean.User;
public class BeanUtilsDemo_01 {
@Test
public void demo01(){
//模拟向User对象封装数据
User user = new User();
user.setUid("u001");
user.setUserName("jack");
user.setPassword("1234");
System.out.println(user);
}
@Test
public void demo02() throws Exception{
/* 实际开发中,需要封装到JavaBean中的数据存放在配置文件
* * 内容:uid=u001 、userName=jack
*
* JavaBean中两个概念:字段Field、属性Property
* * 字段:就是成员变量。
* 例如:private String userName;
* 字段名称:userName
* * 属性:通过getter或setter方法推敲获得
* 获得方式:省略set或get前缀,首字母小写
* 例如:getUserName --> UserName --> userName
* * 注意:一般情况下,字段名称和属性名称一致的。
*
* * 特殊情况
* private String description; //字段名:description
* public String getDesc(){ //属性名:desc
* return description;
* }
*/
//1 BeanUtils工具类,提供setProperty 给指定属性设置内容 和 getProperty获得指定属性的值
User user = new User();
System.out.println("封装前:" + user);
// * 封装数据来自配置文件 , 底层其实 user.setUid("u002")
BeanUtils.setProperty(user, "uid", "u002");
BeanUtils.setProperty(user, "userName", "rose");
System.out.println("封装后:" + user);
//2 获得属性值
String userName = BeanUtils.getProperty(user, "userName");
System.out.println(userName);
}
}
User类
import java.util.Arrays;
public class User {
private String uid;
private String userName;
private String password;
private String[] hobbies; //爱好
private int age;
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String[] getHobbies() {
return hobbies;
}
public void setHobbies(String[] hobbies) {
this.hobbies = hobbies;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [uid=" + uid + ", userName=" + userName + ", password=" + password + ", hobbies="
+ Arrays.toString(hobbies) + ", age=" + age + "]";
}
}
3.2 BeanUtils的populate方法的使用
3.2.1 方法说明
BeanUtils对象 populate(Object bean, Map<String,String[]> properties) 将Map数据封装到指定Javabean中,一般用于将表单的所有数据封装到javabean。
3.2.2 案例代码六
使用populate方法将数据封装到User对象中
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import org.junit.Test;
import com.itheima_01_bean.User;
public class BeanUtilsDemo_02 {
@Test
public void demo01() throws Exception{
//1.模拟数据,创建一个Map,填充需要的数据
Map<String,String[]> map = new HashMap<String,String[]>();
map.put("uid", new String[]{"u001"});
map.put("userName", new String[]{"jack","rose"});
map.put("password", new String[]{"1234"});
//2 将使用populate进行填充
User user = new User();
BeanUtils.populate(user, map);
System.out.println(user);
}
@Test
public void demo02() throws Exception{
//1.模拟数据,创建一个Map,填充需要的数据
Map<String,String[]> map = new HashMap<String,String[]>();
map.put("uid", new String[]{"u001"});
map.put("userName", new String[]{"jack","rose"});
map.put("password", new String[]{"1234"});
map.put("hobbies", new String[]{"敲代码","早上敲代码","晚上敲代码"});
map.put("age", new String[]{"123"});
//2 将使用populate进行填充
// * 可以向指定的属性,填充一组数据。需要类型必须是[]
// * 如果属性不是数组,将使用map.value表示数组中的第一个。
// * BeanUtils支持类型:基本类型 和 基本类型对应的包装类 。自动将字符串转换基本类型
User user = new User();
BeanUtils.populate(user, map);
System.out.println(user);
}
}
3.3 BeanUtils自定义工具类
3.3.1 自定义工具类的基本使用
3.3.2 案例代码七
1.定义静态的一个工具类,定义方法populate,参数为Object 和 Map<String,String[]>
返回值类型为void
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
public class MyBeanUtils {
/**
* 自动填充
* @param bean
* @param properties
*/
public static void populate(Object bean , Map<String,String[]> properties ){
try {
BeanUtils.populate(bean, properties);
} catch (Exception e) {
//将编译时异常,转换成运行时,方便调用者(使用者不需要再次处理异常)
throw new RuntimeException(e);
}
}
}
测试代码
@Test
public void demo01() {
//1.模拟数据,创建一个Map,填充需要的数据
Map<String,String[]> map = new HashMap<String,String[]>();
map.put("uid", new String[]{"u001"});
map.put("userName", new String[]{"jack","rose"});
map.put("password", new String[]{"1234"});
//2 将使用populate进行填充
User user = new User();
MyBeanUtils.populate(user, map);
System.out.println(user);
}
2.定义静态的一个工具类,定义方法populate,参数为Class 和 Map<String,String[]>
返回值类型为Object
/**
* 自动填充
* @param bean
* @param properties
*/
public static Object populate(Class beanClass , Map<String,String[]> properties ){
try {
//1 使用反射进行实例化
Object bean = beanClass.newInstance();
//2 填充数据
BeanUtils.populate(bean, properties);
//3 将填充好JavaBean实例返回
return bean;
} catch (Exception e) {
//将编译时异常,转换成运行时,方便调用者(使用者不需要再次处理异常)
throw new RuntimeException(e);
}
}
}
3.3.3 带泛型的自定义工具类
3.3.4 代码案例八
1.定义静态的一个工具类,定义方法populate,参数为Class<T>和 Map<String,String[]>
返回值类型为T
public class MyBeanUtils3 {
/**
* 自动填充
* @param bean
* @param properties
*
* Class<T> 此处的T就是一个变量,在运行时,接收具体类型。例如:User
* 变量必须先定义在使用
* 泛型变量的定义方式:修饰符 <变量名> 返回值
*/
public static <T> T populate(Class<T> beanClass , Map<String,String[]> properties ){
try {
//1 使用反射进行实例化
T bean = beanClass.newInstance();
//2 填充数据
BeanUtils.populate(bean, properties);
//3 将填充好JavaBean实例返回
return bean;
} catch (Exception e) {
//将编译时异常,转换成运行时,方便调用者(使用者不需要再次处理异常)
throw new RuntimeException(e);
}
}
}
2.测试类
@Test
public void demo03() throws Exception{
//工具类使用
Map<String,String[]> properties = new HashMap<String,String[]>();
properties.put("id", new String[]{"18"});
properties.put("username", new String[]{"jack"});
properties.put("pwd", new String[]{"1234"});
User obj = MyBeanUtils.populate2(User.class, properties);
System.out.println(obj);
/* 结果:
* User [id=18, username=jack, pwd=1234]
*/
}
已经删除