一、JDK注解
*JDK注解
-jdk5.0新特性
-三个注解:
--@Override注解一:
当子类进程父类并复写父类方法时候,需要保持子父类方法名一致加注解
--@Override注解二:
在jdk1.6后可以在子类继承父接口时加注解,保持方法名一致
--@SuppressWarnings({"all"}):注解所有类型警告
--@Deprecated:方法过时了
二、自定义注解
*自定义注解:主要用于反射
注释属性mytest.d的参数类型只允许基本类型、字符串、类、注释、枚举或一维的数组
@interface mytest{
//定义参数(属性)
int param1();
String param2();
String param3() default "bb";
String[] arrs();
Class clazz();
//枚举
Color color();
//注解
test11 test();
//特殊的注解:当参数名称是value时,当只有一个参数时,使用注解时,不写key也可以,直接值
String value();
}
@interface test11{}
enum Color{
RED,YELLOW,GREEN;
}
public class TestDemo {
@mytest(param1=1,param2="aa",arrs={"cc"},clazz=TestDemo.class,color=Color.GREEN,test=@test11,value="value")
public void run1(){
}
}
练习一:
-模拟Junit 的 Test注解
*涉及到一个知识点:自定义注解作用域在源代码阶段,要想让范围扩大,需要使用元注解
@Retention(RententionPolicy.RUNTIME)-代码演示
---------------------------------------Annotation---------------------------------------
package com.ayit.annotation1;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* 自定义注解模拟Test注解实现测试功能
* @author XiaYuJia
*/
//元注解:默认情况下,注解只在源代码阶段存在,要想使注解范围扩大,需要使用注解
@Retention(RetentionPolicy.RUNTIME)
public @interface MyJunitTest {
}
--------------------------------------TestAnnotation------------------------------------package com.ayit.annotation1;
public class TestJunit {
@MyJunitTest
public void test1(){
System.out.println("Test1");
}
public void test2(){
System.out.println("Test2");
}
}
--------------------------------------RunAnnotation------------------------------------
package com.ayit.annotation1;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 让所有含有注解的方法执行
* @author XiaYuJia
*
*/
public class TestMain {
public static void main(String[] args) {
/**
* 最终目的:得到有注解的方法,让这个方法执行
* 如何得到注解方法?
* -使用反射得到要操作方法所在类的Class
* -首先得到所有的方法Method[] getMethods()
* -判断方法上面是否有注解isAnnotationPresent(Class<?extends Annotation>annotationClass)
* -如果方法上面有注解,让这个方法执行invoke(Object obj ,Object...args)
*/
Class clazz = TestJunit.class;
Method[] methods = clazz.getMethods();
for (Method method : methods) {
//判断方法是否存在注解
boolean flag = method.isAnnotationPresent(MyJunitTest.class);
if(flag){
try {
method.invoke(clazz.newInstance());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
练习二:
-模拟Junit 的 Test注解
*涉及到一个知识点:自定义注解作用域在源代码阶段,要想让范围扩大,需要使用元注解
@Retention(RententionPolicy.RUNTIME)*-注解实现JDBCUtils dirvername url username password 传递参数
-代码演示
----------------------------------------JDBCAnnotation----------------------------------package com.ayit.annotation2;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* 通过注解实现JDBC加载数据库驱动,建立连接操作
* @author XiaYuJia
*
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface JDBCAnnotation {
String drivername();
String url();
String username();
String password();
}
----------------------------------------JDBCUtils------------------------------------
package com.ayit.annotation2;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
public class JDBCUtils {
@JDBCAnnotation(drivername="com.mysql.jdbc.Driver",url="jdbc:mysql://127.0.0.1:3306/day21",username="root",password="root")
public Connection getConnection() throws Exception, NoSuchMethodException{
/**
* 从注解里面把这些信息获取处理
* 目的:得到方法上的注解里面的属性值
* 步骤:
* -得到方法所在类Class
* -得到注解所在的方法
* -得到方法上面注解
* -得到注解里面属性
*/
Class clazz = JDBCUtils.class;
//得到注解方法
Method method = clazz.getMethod("getConnection");
//得到注解
JDBCAnnotation annotation = method.getAnnotation(JDBCAnnotation.class);
//得到属性值
String drivername = annotation.drivername();
String url = annotation.url();
String username = annotation.username();
String password = annotation.password();
Class.forName(drivername);
Connection connection = DriverManager.getConnection(url, username, password);
return connection;
}
}
----------------------------------------JDBCTest-------------------------------------
package com.ayit.annotation2;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class TestJDBCUtils {
public static void main(String[] args) {
try {
Connection connection = new JDBCUtils().getConnection();
String sql = "select * from book";
PreparedStatement pst = connection.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
while(rs.next()){
System.out.println(rs.getString(2));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
三、servlet3.0的注解的开发
* 之前使用servlet版本都是2.5版本,从servlet3.0版本开始支持注解开发
** servlet2.5和servlet3.0区别
*** 3.0可以实现2.5的功能
*** 3.0支持注解的开发,但是2.5不支持
*** 创建servlet3.0和servlet2.5 不相同了
* 方式:创建web项目时候,选择JAVAEE 6.0版本
* 特点:不需要web.xml,可以直接使用注解代替web.xml
* servlet3.0运行在tomcat7.X及其以上版本
* servlet3.0还可以是异步请求
(1)使用注解配置servlet:
- @WebServlet(urlPatterns={"/通过浏览器访问的路径"})
** 相当于servelt2.5里面的web.xml中 <url-pattern>/...</url-pattern>
(2)使用注解配置监听器
- @WebListener
- 在servelt2.5版本里面需要配置 <listener></listener>
** 演示监听servletContext域对象的创建和销毁
(3)使用注解配置过滤器
- @WebFilter(urlPatterns={"/过滤的路径"})
- 在servlet2.5版本如何配置过滤器
<filter>
<filter-name></filter-name>
<filter-class></filter-class>
</filter>
<filter-mapping>
<filter-name></filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(4)在servelt3.0里面使用注解配置初始化参数
- @WebServlet(urlPatterns={"/demo1"},
initParams={@WebInitParam(name="username",value="zhangsan"),@WebInitParam(name="password",value="123456")})
- 在servelt2.5里面配置方式:<init-param> <param-name> <param-value>
* 如果使用servlet2.5实现文件上传,需要使用组件
* 但是在servlet3.0开始,支持文件上传了
-注意事项及代码实现
package com.ayit.upload;
import java.io.File;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
/**
* servlet3.0=实现文件上传,不需要组件
* -注意:表单三个要求
* -servlet:注解
* @author XiaYuJia
*
*/
@MultipartConfig
@WebServlet(urlPatterns="/upload")
public class upload extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//文件上传项
Part part = req.getPart("filename");
//文件大小和表单输入文件项名称
long size = part.getSize();
String name = part.getName();
System.out.println(size+":"+name);
//http请求头包含文件完全(相对)路径(浏览器不同)和文件项name和form-data
//form-data; name="filename"; filename="proxy.zip"
String header = part.getHeader("Content-Disposition");
//获取文件名称
String filename = null;
String pathPart = header.substring(header.indexOf("filename=\"")+"filename=\"".length());
if(pathPart.lastIndexOf("\\")!=-1){
filename = pathPart.substring(pathPart.lastIndexOf("\\"),pathPart.length()-1);
}else{
filename = pathPart.substring(0,pathPart.length()-1);
}
System.out.println(filename);
//把文件上传到服务器
String realPath = getServletContext().getRealPath("source");
File file = new File(realPath);
if(!file.exists()){
file.mkdirs();
}
part.write(realPath+"\\"+filename);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
}
}