1.动态代理:proxy
1.写一个类
2.目标对象:
3.写一个获得Proxy对象的方法:
4.使用JDK中的Proxy创建代理对象,这个代理对象是程序动行时产生,因此叫动态代理
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
三个参数:
参数一:代理对象是由哪个类加载器加载器UserDaoProxy.class.getClassLoader(),
参数二:代理对象要与目标对象有相同的方法iUserDao.getClass().getInterfaces(),
参数三:在代理对象中,如何去处理客户端调用的方法
5.获得动态代理对象后,强转成指定接口
6.最后一个参数是一个内部类:
1.//返回值
Object returnValue = "";
2.//获取客户端调用的方法名
String methodName = method.getName();
3.判断://如果客户端调用的方法是addUser的话
if("addUser".equals(methodName)){
1.//写日志
log.write();
2.//增加用户,并接收返回值
returnValue = method.invoke(iUserDao,args);
3.//写日志
log.write();
否则://查询用户,并接收返回值,相当于iUserDao.findAll()
else{
//查询用户,并接收返回值,相当于iUserDao.findAll()
returnValue = method.invoke(iUserDao,args);
}
4.//将返回值返回
return returnValue;
动态代理在web上应用:
解决get post请求的编码问题:(和装饰设计模式比较)
2.发送复杂邮件:
1.send.jsp发送复杂邮件:
2.生成上传地址文件夹upload
3.sendServlet:接受客户端发送的数据:
1.导包:
定义一个Map集合,用于存贮普通文本的字段名和值。
2.生成一个处理上传文件的方法:
上传文件的代码:
初始化一个文件对象。
1.创建DiskFileItemFactory对象
2.创建ServletFileUpload对象
3.设置上传文件的编码格式:
4.通过ServletFileUpload对象解析请求
5.遍历解析得到的FileItem对象
6.判断是普通文本还是附件。
7.如果是普通文本则获取名字和值,解决编码问题,且收集fieldName和fieldValue
8.如果是文件附件则获取名字并封装成一个文件对象,再获取文件对象的名字。
9.获取上传文件夹根地址:
10.封装上传文件保存的目录为文件对象:
11.写入
12.删除
13.返回获得的文件
3.创建一个复杂邮件:
处理上传文件,保存到指定的服务端目录下,并返回这个上传的文件
1.创建一个复杂邮件:
2.设置主机名:
3.权限认证:
4.设置编码
5.设置邮件发送方from
6.设置邮件接受方to
7.设置邮件主题
8.设置邮件信息:
4.权限认证:
5.判断是否有附件:
如果有附件
1.创建附件对象:
2.封装附件位置
3.封装附件标题:
4.将附件加入到上述的邮件中
6.发送邮件:
7.响应信息:
1.设置响应的编码格式:
2.向页面写入一段js代码,弹出发生成功对话框。
3.并重定向到send.jsp页面。
3.反射泛型:
1.创建sql文件,写入sql语句:
2.Student类Teacher类
3.StudentDao;TeacherDao:
4.BaseDao:
继承BaseDao:
5.要进行与数据库交互数据。所以要
导包:c3p0,数据库驱动,dbutils。
c3p0-config.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///javaweb(数据库名)</property>
<property name="user">root</property>
<property name="password">123456</property>
</default-config>
</c3p0-config>
写一个dbUtils工具类获取数据库连接池:
BaseDao中写两个方法:
findById();
findAll();
在写这两个方法时,发现问题:
1.需要动态获取表名。
2.需要动态获取class字节码文件。
解决方法是通过反射泛型来解决该问题。
BaseDao代码内容:
1.定义两个变量:
1.clazz就是Student或Teacher的字节码:
2.表名
2.通过空参构造器为实例变量设置值:
1.获得子类的字节码文件:
2.通过子类的字节码文件获得父类的泛型得到的是Type
3.父子接口强转,将Type装换为参数化类型(泛型类型)
4.返回泛型类型中的实际类型:
5.取出第一个与元素,即Student或Teacher类型
6.类名和表名有一定的关系,所以可以获得表名:
3.findById();
注意class字节码文件和表名的动态获取。
4.findAll();
注意class字节码文件和表名的动态获取。
4.反射注解:
1.演示常用的注解:
1.@Override
2.@Deprecated :注解在方法上时表示方法过时的,废弃的。
3.@SuppressWarnings :压制警告。
2.自定义注解:
语法:@interface MyAnnotation{}
@interface MyAnnotation{
//用户名
String name();
//年龄
int age();
//收入
double salary();
}
@MyAnnotation(age=22, name="哈哈", salary=7000)
public void run(){
}
可以设置初始化值:
@interface YouAnnotation{
//用户名
String name() default "嘻嘻";
//年龄
int age() default 22;
//收入
double salary() default 6500;
}
字段可以是字符串和字符串数组。value 可以省略。
3.注解的应用:用来替代配置文件。
这个注解,就相当于原来的db.properties或db.xml配置文件
@Retention(RetentionPolicy.RUNTIME)表示运行时还有效。。
@Target({METHOD})这是表示只能用在方法上
@interface DB{
String driver() default "com.mysql.jdbc.Driver";
String url() default "jdbc:mysql://127.0.0.1:3306/javaweb";
String username() default "root";
String password() default "root";
}
1.自定义一个注解:取名为DB。
2.写一个获取数据库连接的方法:getConnection();在方法上加上注解。
反射注解:
1.获取该类的字节码:
2.获取getConnection方法:
3.获取方法上的注解:
4.分别获取DB注解中的所以属性:
5.注册数据库驱动:
6.用JDBC方式获取连接对象并返回:
3.写个主方法测试结果:
三元表达式判断是否获得连接。
易发生的错误是:
1. @Retention(RetentionPolicy.RUNTIME)这是自定义注解的生命周期
这是修饰注解的注解,叫做元注解。
2.没有将注解写到方法上。
5.为字符串动态设置值:
1.创建一个模式字符串:
2.创建默认语言环境和指定模式的字符串格式对象:
3.准备3个实际参数:
4.动态为模式字符串设置值:
5.显示: