zoukankan      html  css  js  c++  java
  • javase(14)_java基础增强

    一、Eclipse的使用

    1、在eclipse下Java程序的编写和run as,debug as,及java运行环境的配置.
    2、快捷键的配置,常用快捷键:
    •内容提示:Alt + /        
    •快速修复:Ctrl + 1
    •导包:Ctrl + shift + O
    •格式化代码块:ctrl + shift + F
    •向前向后:Alt + 方向键
    •添加注释 Ctrl+Shift+/
    •除去注释 Ctrl+Shift+
    3、程序的调试和运行
    •F5(跳入)、F6(跳过) 、F7(跳出) 、drop to frame(回撤到当前方法起始位置)、resume(跳到下一个断点 ) 、选中变量或表达式后watch可观察当前值.

    二、Junit使用

    1、@Before、@Test、@After基本使用
    public class Demo4 {
        @Before
        public void before() {
            System.out.println("before");
        }
        @Test
        public void testRun() {
            Person p = new Person();
            p.run();
        }
        @Test
        public void testEat() {
            Person p = new Person();
            p.eat();
        }
        @After
        public void after() {
            System.out.println("after");
        }
    }

    运行结果:

    before
    eating.
    after
    before
    runing.
    after

    2、@BeforeClass、@Test、@AfterClass基本使用

    public class Demo5 {
        @BeforeClass
        public void beforeClass() {
            System.out.println("beforeclass");
        }
        @Test
        public void testRun() {
            Person p = new Person();
            p.run();
        }
        @Test
        public void testEat() {
            Person p = new Person();
            p.eat();
        }
        @AfterClass
        public void afterClass() {
            System.out.println("afterclass");
        }
    }

    运行结果:

    before
    eating.
    runing.
    after

    三、JDK 5.0 新特性

    JDK5中新增了很多新的java特性,利用这些新语法可以帮助开发人员编写出更加高效、清晰,安全的代码.

    1、静态导入,(了解即可,一般没人这么用)

    语法:•Import static 包名.类名.静态属性|静态方法|*
    import static java.lang.System.out;
    import static java.util.Arrays.sort;
    
    public class Demo1 {
        public static void main(String[] args) {
            out.print("main");
            int[] a = new int[] { 6, 5, 3 };
            sort(a);
            for (int i : a)
                out.print(i);
        }
    }

    2、自动装箱/拆箱

    •自动装箱:指开发人员可以把一个基本数据类型直接赋给对应的包装类.
    •自动拆箱:指开发人员可以把一个包装类对象直接赋给对应的基本数据类型.
    public class Demo2 {
        public static void main(String[] args) {
            Integer i = 1;// 装箱
            int j = i;// 拆箱
            // 典型应用,list里只能装对象
            List<Integer> list = new ArrayList<Integer>();
            list.add(1);// 1被自动包装为Integer
            int k = list.get(0);// 自动拆箱
            Iterator<Integer> it = list.iterator();
            while (it.hasNext()) {
                int m = it.next();// 拆箱
            }
        }
    }

    3、增强for循环

    •引入增强for循环的原因:在JDK5以前的版本中,遍历数组或集合中的元素,需先获得数组的长度或集合的迭代器,比较麻烦!
    •JDK5中定义了一种新的语法——增强for循环,以简化此类操作.增强for循环只能用在数组、或实现Iterable接口的集合类上,如list,set可以,map不行.

    Map for增强实例:

    package cn.itcast.demo;
    
    import java.util.*;
    import java.util.Map.Entry;
    import org.junit.Test;
    
    public class Demo3 {
    
        @Test
        public void test3(){
            Map map=new HashMap();
            map.put("1", "aaa");
            map.put("2", "bbb");
            map.put("3", "ccc");
            //传统方式1
            Set set=map.keySet();
            Iterator it=set.iterator();
            while(it.hasNext()){
                String key=(String)it.next();
                String value=(String) map.get(key);
                System.out.println("key="+key+",value="+value);
            }
            //传统方式2
            Set set2=map.entrySet();
            Iterator it2=set2.iterator();
            while(it2.hasNext()){
                Map.Entry  entry=(Entry)it2.next();
                System.out.println("key="+entry.getKey()+",value="+entry.getValue());
            }
            //增强for循环的1种方式,实际转为的set视图只存了key
            for(Object obj:map.keySet()){
                String key2=(String)obj;
                String value2=(String)map.get(key2);
                System.out.println("key2="+key2+",value2="+value2);
            }
            //增强for循环的2种方式
            for(Object obj:map.entrySet()){
                Map.Entry entry3=(Entry) obj;
                String key3=(String) entry3.getKey();
                String value3=(String) entry3.getValue();
                System.out.println("key3="+key3+",value3="+value3);
            }
            //增强for循环需要注意的问题:只适合取数据,不适合更改
            int arr[]={1,2,3};
            for(int i: arr){
                i=10;
            }
            System.out.println(arr[0]); // 1
            List li=new ArrayList();
            li.add("1");
            for(Object obj : li){
                obj="888";
            }
            System.out.println(li.get(0));// 1
        }
    }

    4、可变参数

    语法:

    public void foo(int … args){}//三个点
    注意事项:
    •调用可变参数的方法时, 编译器将自动创建一个数组保存传递给方法的可变参数,因此,程序员可以在方法体中以数组的形式访问可变参数.
    •可变参数只能处于参数列表的最后, 所以一个方法最多只能有一个长度可变的参数.
    public class Demo4 {
        @Test
        public void testSum(){
            sum(1,2,3,4);
            int arr[]={5,6,7};
            sum(arr);
        }
        public void sum(int ...nums){
            int sum=0;
            for(int i:nums){
                sum+=i;
            }
            System.out.println(sum);        
        }
        //可变参数注意的问题
        //public void aa(int ...nums,int s)//不可以,编译器晕逼了
        //public void bb(int s ,int ...nums)//可以
        @Test
        public void  asListTest(){//api: public static <T> List<T> asList(T... a)
            List list=Arrays.asList("1","2","3");
            System.out.println(list);//[1, 2, 3] 
            
            String arr[]={"1","2","3","4"};
            list=Arrays.asList(arr);
            System.out.println(list);//[1, 2, 3, 4] arr是对象数组
            
            int nums[]={1,2,3,4,5};
            list=Arrays.asList(nums);
            System.out.println(list);//[[I@120d62b],nums是一个对象
            
            Integer nums2[]={1,2,3,4,5};
            list=Arrays.asList(nums2);
            System.out.println(list);//[1, 2, 3, 4, 5]  
        }
    }

    5、枚举类

    为什么需要枚举?
    •一些方法在运行时,它需要的数据不能是任意的,而必须是一定范围内的值,Java5以后可以直接使用枚举予以解决.新增的 enum 关键字用于定义一个枚举类.
    枚举类具有如下特性:
    •枚举类也是一种特殊形式的Java类.
    •枚举类中声明的每一个枚举值代表枚举类的一个实例对象.
    •与java中的普通类一样,在声明枚举类时,也可以声明属性、方法和构造函数,但枚举类的构造函数必须为私有的.
    •枚举类也可以实现接口、或继承抽象类.
    •JDK5中扩展了swith语句,它除了可以接收int, byte, char, short外,还可以接收一个枚举类型.

    定义枚举的狗找函数、方法、字段:

    /*
     * jdk5之前,只能这么定义
     * class Grade{ 
     *      private Grade(){ }
     *      public static final Grade A=new Grade();
     *      public static final Grade B=new Grade();
     *      public static final Grade C=new Grade(); 
     *      public static final Grade D=new Grade();
     *      public static final Grade E=new Grade(); 
     *  }
     */
    enum Grade { 
        A("100-90"), B("89-80"), C("79-70"), D("69-60"), E("59-0");
        private String value;
        private Grade(String value){
            this.value=value;
        }
        public String getValue(){
            return this.value;
        }
    }
    
    public class Demo1 {
        @Test
        public void test() {
            print(Grade.B);
        }
        
        public void print(Grade g){ // A B C D E
            String value=g.getValue();
            System.out.println(value);
        }
    }

    带抽象方法的枚举:

    enum Grade {// class A 100-90优 B 89-80良 C 79-70 一般D 69-60差 E 59-0不及格
        //必须实现抽象方法
        A("100-90"){
            public String localeValue(){
                return "优";
            }
        },
        B("89-80"){
            public String localeValue(){
                return "良";
            }
        },
        C("79-70"){
            public String localeValue(){
                return "一般";
            }
        };
        
        private String value;
        private Grade(String value){
            this.value=value;
        }
        public String getValue(){
            return this.value;
        }
        public abstract String localeValue();
    }
    
    public class Demo1 {
        @Test
        public void test() {
            print(Grade.B);    //89-80,良    
        }
        
        public void print(Grade g){ // A B C D E
            String value=g.getValue();
            String value2=g.localeValue();
            System.out.println(value+","+value2);
        }
    }

    注意:

    Java中声明的枚举类,均是java.lang.Enum类的孩子,它继承了Enum类的所有方法.常用方法:

    •name() //返回此枚举常量的名称,有毛用
    •ordinal() //返回枚举常量的序数
    •values() 此方法虽然在JDK文档中查找不到,但每个枚举类都具有该方法,它遍历枚举类的所有枚举值非常方便.

    6、反射

    1、java反射机制是在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法.简而言之,动态获取类中信息就是反射.

    2、java反射应用在很多java软件和框架中,例Tomcat,提供了处理请求和应答的方式,因为具体的处理动作不同,所以对外提供了接口,由开发者来实现具体的请求和应答处理.这个接口就是 servlet,开发者只要实现servlet接口,并配置相应的配置文件,对Tomcat来说就是在web.xml中配置servletname也就是类名,这样tomcat就能通过所谓的反射来加载该类的class文件,并获取类中的所有信息,从而实现开发者自定义的请求和应答处理方式.

    3、类用来描述对象共性的信息,用来描述字节码文件的共性的类是Class类,该类提供获取字节码文件中的内容,包括类名称,属性和函数.反射依靠该类来完成.

    4、获取字节码文件对象的三种方式:

      1.Object类的getClass()方法,必须实例化类

      2.任何数据类型都具备一个class静态属性(Objcet类的属性)来获取对于的Class对象.

      3.通过给定的类的字符串名称就可以获取该类Class对象,更易扩展,该方法是forName(). 一般使用这种

      例:String name="cn.itcast.Person"; Class c = Class.forName(name);

    5、反射构造函数

    import java.lang.reflect.Constructor;
    
    class Person{
        String name;
        int age;
        public Person(){
            System.out.println("wu can");
        }
        public Person(String name,int age){
            System.out.println("you can");
        }
    }
    
    public class TestPerson {
        public static void main(String[] args) throws Exception{
            Person p = new Person();
            //根据字符串的名称查找该类的字节码文件,加载进内存,创建该字节码文件对象,创建对应的Person对象.
            String name="com.czbk.faceObjcet.Person";
            Class clazz = Class.forName(name);
            //只能调用无参构造函数
            Person p1 =(Person)clazz.newInstance();  
            //调用有参构造函数,getDeclaredConstructor可获取私有构造函数
            Constructor c = clazz.getConstructor(String.class,int.class);
            Object o=c.newInstance("ww",26);
        }
    }

    6、反射字段

    public class TestPerson {
        public static void main(String[] args) throws Exception{
            String str="com.czbk.faceObjcet.Person";
            Class clazz = Class.forName(str);
            Object o = clazz.newInstance();
            Field f = clazz.getField("name");  //只能获取公有属性,可获取父类
            Object obj = f.get(o);
            
            Field f1 = clazz.getDeclaredField("age");//可获取私有属性,只限本类
            f1.setAccessible(true); //对私有字段的访问取消权限检查,暴力访问
            System.out.println(f1.get(o));
            f1.setInt(o,22);
            System.out.println(o);
        }
    }

    7、反射方法

    public class TestPerson {
        public static void main(String[] args) throws Exception{
            String str="com.czbk.faceObjcet.Person";
            Class clazz = Class.forName(str);
            Object o = clazz.newInstance();
            //调用无参方法
            Method method=clazz.getMethod("toString", null);
            method.invoke(o, null);
            //调用有参方法
            Method method1=clazz.getMethod("toString1", String.class);
            method1.invoke(o, "sss");
        }
    }

    8、主板运行实例(接口+配置)

    public interface PCI {
        void run();
        void close();
    }
    
    public class SoundCard implements PCI{
        public void run() {
            System.out.println("SoundCard Run");
        }
        public void close() {
            System.out.println("SoundCard Close");
        }
    }
    
    public class NetCard implements PCI{
        public void run() {
            System.out.println("NetCard run");
        }
        public void close(){
            System.out.println("NettCard clase");
        }
    }
    
    public class MainBoard {
        /*public void run(PCI p){
            p.run();
        }
        public void clase(PCI p){
            p.close();
        }*/
        public static void main(String[] args) throws Exception {
            //这种方式每次增加新硬件时都需要修改主板源代码
            /*SoundCard sc = new SoundCard();
            MainBoard mb = new MainBoard();
            mb.run(sc);
            mb.clase(sc);*/
            
            //增加硬件无需修改MainBoard源代码,只要在配置文件中添加
            Properties pt = new Properties();
            FileInputStream is = new FileInputStream(new File("PCI.properties"));
            pt.load(is);
            
            for(int x=0;x<pt.size();x++){
                String PCIName=pt.getProperty("pci"+x);
                Class clazz = Class.forName(PCIName);
                PCI p=(PCI)clazz.newInstance();
                Method method = clazz.getMethod("run", null);
                method.invoke(p, null);
            }
        }
    }

    7、内省(Introspector)

    1、为什么要学内省?
    •开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作java对象的属性.
    public class Demo1 {
        //得到bean所有属性
        @Test
        public void test1() throws IntrospectionException{
            BeanInfo info=Introspector.getBeanInfo(Person.class);
            //去掉Object里的属性(也就是class属性)
            BeanInfo info2=Introspector.getBeanInfo(Person.class,Object.class);
            PropertyDescriptor[] pds=info.getPropertyDescriptors();
            for(PropertyDescriptor pd:pds){
                System.out.println(pd.getName());
                //ab age class name  password
            }
        }
        //操纵bean的指定属性:age
        @Test
        public void test2() throws  Exception{
            Person p=new Person();
            PropertyDescriptor pd=new PropertyDescriptor("age", Person.class);
            //得到属性的写方法,为属性赋值
            Method method=pd.getWriteMethod();
            method.invoke(p, 45);
            System.out.println(p.getAge());//45
            
            //获取属性的值
            method=pd.getReadMethod();
            System.out.println(method.invoke(p, null));//45
        }
        //高级内容,获取当前操作的属性的类型
        @Test
        public void test3() throws  Exception{
            Person p=new Person();
            PropertyDescriptor pd=new PropertyDescriptor("age", Person.class);
                
            //得到属性的写方法,为属性赋值
            Method method=pd.getWriteMethod();
            System.out.println(pd.getPropertyType());//int
            method.invoke(p, 45);
            System.out.println(p.getAge());//45
            
            //获取属性的值
            method=pd.getReadMethod();
            System.out.println(method.invoke(p, null));//45
        }
    }

    2、内省—beanutils工具包

    Sun公司的内省API过于繁琐,所以Apache组织结合很多实际开发中的应用场景开发了一套简单、易用的API操作Bean的属性——BeanUtils
    Beanutils工具包的常用类:•BeanUtils、•PropertyUtils、•ConvertUtils.regsiter(Converter convert, Class clazz)•自定义转换器
    //使用beanUtils操纵bean的属性 ( 第三方)
    public class Demo1 {
        @Test
        public void test1() throws Exception{
            Person p=new Person();
            BeanUtils.setProperty(p, "age", 456);
            System.out.println(p.getAge());//456
        }
        @Test
        public void test2() throws Exception{
            String name="aaaa";
            String age="123";
            String password="pw";
                    
            Person p=new Person();
            //支持8种基本类型自动转换
            BeanUtils.setProperty(p, "name", name);
            BeanUtils.setProperty(p, "age", age);
            BeanUtils.setProperty(p, "password", password);
            
            System.out.println(p.getName());//aaaa
            System.out.println(p.getAge());//123
            System.out.println(p.getPassword());//pw
    
        }
        @Test
        public void test3() throws Exception{
    
            String birthday="1983-12-1";
            
            //为了让日期赋值到bean的birthday属性上,给beanUtils注册一个日期转换器
            //ConvertUtils.register(converter, clazz);
            ConvertUtils.register(new Converter(){
                
                public Object convert(Class type, Object value) {
                    if(value==null) return null;
                    if(!(value instanceof String)){
                        throw new ConversionException("只支持String类型的转换");
                    }
                    String str=(String)value;
                    if(str.trim().equals("")) return null;
                    SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd",Locale.US);
                    try {
                        return df.parse(str);
                    } catch (ParseException e) {
                        throw new RuntimeException(e);                    
                    }
                }
            }, Date.class);
            Person p=new Person();
            BeanUtils.setProperty(p, "birthday", birthday);
            System.out.println(p.getBirthday());//pw
            System.out.println("___"+BeanUtils.getProperty(p, "birthday"));
        }
        public void test5() throws Exception {
            Map map=new HashMap();
            map.put("name", "aaa");
            map.put("password", "123");
            map.put("brithday", "1980-09-09");
            ConvertUtils.register(new DateLocaleConverter(), Date.class);
            Person p=new Person();
            //用map集合填充bean属性,map关键字和bean属性要一致
            BeanUtils.populate(p, map);
        }
    }

    8、泛型(Generic)

    1、JDK5以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免就会引发程序的一些安全性问题,例:

    ArrayList list = new ArrayList();
    list.add("abc");
    Integer num = (Integer) list.get(0);  //运行时会出错,但编码时发现不了
    JDK5中的泛形允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定性(尤其在大型程序中更为突出).
    2、注意:泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据.但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为"擦除".
    •使用泛形时,泛形类型须为引用类型,不能是基本数据类型
    ArrayList<String> list = new ArrayList<Object>(); 错,左右必须完全一致
    ArrayList<Object> list = new ArrayList<String>(); 错
    ArrayList<String> list = new ArrayList (); 对,可以一边没有
    ArrayList list = new ArrayList<String>(); 对

    3、自定义泛形——泛型方法

    Java程序中的普通方法、构造方法和静态方法中都可以使用泛型.方法使用泛形前,必须对泛形进行声明,语法:<T> ,T可以是任意字母,但通常必须要大写.<T>通常需放在方法的返回值声明之前.例如:
    public static <T> void doxx(T t);
    •编写一个泛形方法,接收一个任意数组,并颠倒数组中的所有元素.
    public class Demo1 {
        // 编写一个泛形方法,接收一个任意数组,并颠倒数组中的所有元素.
        public <T> void reverse(T arr[]) {
            int startindex = 0;
            int endindex = arr.length - 1;
            while (true) {
                if (startindex >= endindex)
                    break;
                T temp = arr[startindex];
                arr[startindex] = arr[endindex];
                arr[endindex] = temp;
                startindex++;
                endindex--;
            }
    
        }
    }
    注意:
    •只有对象类型才能作为泛型方法的实际参数.
    •在泛型中可以同时有多个类型,例如:
    public static <K,V> V getValue(K key) { return map.get(key);}
    4、自定义泛形——泛型类和反射泛形
    如果一个类多处都要用到同一个泛型,这时可以把泛形定义在类上(即类级别的泛型),语法格式如下:
    public class GenericDao<T> {
        private T field1;
        public void save(T obj) {}
        public T getId(int id) {}
    }
    注意,静态方法不能使用类定义的泛形,而应单独定义泛形.
    5、工厂中使用到泛型
    //单例
    public class ServiceFactory {
        
        private Properties serviceConfig = new Properties();
        //单例的构造函数也只执行一次
        private ServiceFactory(){
            InputStream in = DaoFactory.class.getClassLoader().getResourceAsStream("service.properties");
            try {
                serviceConfig.load(in);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        private static ServiceFactory instance = new ServiceFactory();
        public static ServiceFactory getInstance(){
            return instance;
        }
        public <T> T createService(Class<T> clazz){
            //clazz.getName()拿到的带包名
            String name = clazz.getSimpleName();
            String className = serviceConfig.getProperty(name);
            try {
                T service = (T) Class.forName(className).newInstance();
                return service;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    6、泛型的高级应用——通配符 略

    9、Annotation(注解)

    1、什么是Annotation,以及注解的作用?三个基本的 Annotation:
    •@Override: 限定重写父类方法, 该注解只能用于方法
    •@Deprecated: 用于表示某个程序元素(类, 方法等)已过时
    •@SuppressWarnings: 抑制编译器警告.
    2、Annotation 其实就是代码里的特殊标记, 它用于替代配置文件,也就是说,传统方式通过配置文件告诉类如何运行,有了注解技术后,开发人员可以通过注解告诉类如何运行.在Java技术里注解的典型应用是:可以通过反射技术去得到类里面的注解,以决定怎么去运行类.最重要的重要就是直观,替代了配置文件.
    3、掌握注解技术的要点:
    •如何定义注解
    •如何反射注解,并根据反射的注解信息,决定如何去运行类
    4、自定义 Annotation
    定义新的 Annotation 类型使用 @interface 关键字
    声明注解的属性
    •注解属性的作用:原来写在配置文件中的信息,可以通过注解的属性进行描述.
    •注解属性允许的类型only primitive type, String, Class, annotation, enumeration,一维数组are permitted(集合不允许)
    •Annotation 的属性声明方式:String name();
    •属性默认值声明方式:String name() default "xxx";
    •特殊属性value:如果注解中只有一个名称value的属性,那么使用注解时可以省略value=部分,如@MyAnnotation("xxx")
    5、JDK 的元 Annotation
    元 Annotation指修饰Annotation的Annotation.JDK中定义了如下元Annotation:
    @Retention: 只能用于修饰一个 Annotation 定义, 用于指定该 Annotation 可以保留的域, @Rentention 包含一个 RetentionPolicy 类型的成员变量, 通过这个变量指定域.
    •RetentionPolicy.CLASS: 编译器将把注解记录在 class 文件中. 当运行 Java 程序时, JVM 不会保留注解. 这是默认值
    •RetentionPolicy.RUNTIME:编译器将把注释记录在 class 文件中. 当运行 Java 程序时, JVM 会保留注解. 程序可以通过反射获取该注释
    •RetentionPolicy.SOURCE: 编译器直接丢弃这种策略的注释
    @Target:指定注解用于修饰类的哪个成员. @Target 包含了一个名为 value,类型为ElementType的成员变量.
    @Documented: 用于指定被该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档.
    @Inherited: 被它修饰的 Annotation 将具有继承性.如果某个类使用了被 @Inherited 修饰的 Annotation, 则其子类将自动具有该注解
    @Target(value={ElementType.METHOD,ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation1 {
        
        String name() default "zxx";
        String password() default "123";
        int age() default 12;
        Gender gender() default Gender.男;//枚举
        MyAnnotation2 my2() default @MyAnnotation2(name="llll");
        Class clazz() default String.class;
        String[] ss() default {"aa","bbb"};
        int[] i() default {1,2};
    }

    6、提取 Annotation 信息

    当一个 Annotation 类型被定义为运行时 Annotation 后, 该注释才是运行时可见, 当 class 文件被载入时保存在 class 文件中的 Annotation 才会被虚拟机读取,具体方法见api.
    如下是一个注解可以实现的目的,在一个方法上加个注解,即可自动创建数据源,具体解析过程略.
    public class CategoryDao {
        
        private ComboPooledDataSource combods;
    
        @Injectpublic void setCombods(ComboPooledDataSource combods) {
            this.combods = combods;
        }
    }
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Inject {
        String driverClass() default "com.mysql.jdbc.Driver";
        String jdbcUrl() default "jdbc:mysql://localhost:3306/bookstore";
        String user() default "root";
        String password() default "root";
    }

    7、注解在servlet 3.0中的使用案例,替代了在web.xml中的配置:

    @WebFilter(
            urlPatterns = { "/ServletDemo1" }, 
            initParams = { 
               @WebInitParam(name = "charset", value = "UTF-8", description = "编码")
            })
    public class FilterDemo1 implements Filter {
        FilterConfig fConfig=null;
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
            String charset = fConfig.getInitParameter("charset");
            HttpServletRequest req = (HttpServletRequest)request;
            req.setCharacterEncoding(charset);
            chain.doFilter(request, response);
        }
    
        public void init(FilterConfig fConfig) {
            this.fConfig = fConfig;
        }
        
        public void destroy() {
            System.out.println("FilterDemo1 destroy!");
        }
    }
  • 相关阅读:
    python基础篇 08 文件操作
    python基础篇 07set集合 深浅拷贝
    python 基础篇 06 编码 以及小知识点补充
    python基础篇 05字典
    钉钉中设置代码提交提醒--Github机器人(转)
    Spring Boot 之FilterRegistrationBean --支持web Filter 排序的使用(转)
    Spring Aop实例@Aspect、@Before、@AfterReturning@Around 注解方式配置(转)
    为什么添加了@Aspect 还要加@Component(转)
    Servlet 服务器 HTTP 响应
    Servlet 客户端 HTTP 请求
  • 原文地址:https://www.cnblogs.com/wangweiNB/p/5095588.html
Copyright © 2011-2022 走看看