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!");
        }
    }
  • 相关阅读:
    HDU Railroad (记忆化)
    HDU 1227 Fast Food
    HDU 3008 Warcraft
    asp vbscript 检测客户端浏览器和操作系统(也可以易于升级到ASP.NET)
    Csharp 讀取大文本文件數據到DataTable中,大批量插入到數據庫中
    csharp 在万年历中计算显示农历日子出错
    csharp create ICS file extension
    CSS DIV Shadow
    DataTable search keyword
    User select fontface/color/size/backgroundColor设置 字体,颜色,大小,背景色兼容主流浏览器
  • 原文地址:https://www.cnblogs.com/wangweiNB/p/5095588.html
Copyright © 2011-2022 走看看