WEB学习笔记

2012-01-21 00:00
包命名:
在编译java程序时,需要不时的建立包,这是每个包的命名就是一种规范。
一般包命名是以公司的域名倒着写,然后再加上包的实际名称。
例如现在是新浪公司员工,想建立一个GUI包,那么应该这样写:cn.com.sina.GUI
数据一定要先检查再使用!
*****************************************************************************************************************

2012-01-22 01:06

断点:
F5:step in 进入方法
F6:step pass 跳过语句并继续执行下一条语句
F7:step return 返回方法开始位置

dorp to frame :跳到当前方法第一行
resume:跳到下一个断点,如果没有下一个断点那么直接运行完整个程序
watch:监听变量或对象值
注:调试完成之后,要停止虚拟机运行,并在Brekpoints窗口中删除所有断点。

*****************************************************************************************************************

2012-01-22 01:33

常用快捷键:
内容提示:     Alt + /             补全代码
快速修复:    Ctrl + 1             修复代码错误
导包:        Ctrl + Shift + O         导入包
格式化代码块    Ctrl + Shift + F        使代码按照一定的规范格式化
前后跳转    Alt + 左右方向键        转到方法定义(按住Ctrl键,鼠标移动到要跳转的方法上面,点击即可)
注释        Ctrl + Shift + / 或者 \        添加和删除注释
查看方法说明    F2                可以查看工具提供的方法说明
重置透视图    Window 选项中的Reset Parspective
大小写转变    Ctrl + Shift + X 或 Y        把代码从小写变成大写
复制行        Ctrl + Alt + 上下方向键     复制一行代码
代码上下移动    Alt + 上下方向键
删除一行代码    Ctrl + D
查看继承类     Ctrl + T             鼠标移动到想查看的类名上后按快捷键方可查看
查看源代码    Ctrl + Shift + T        按完快捷键之后在弹出来的窗口上输入类名,找到之后点击进去方可查看
查看所有快捷键    Ctrl + Shift + L

*****************************************************************************************************************

2012-01-22 02:03

junit测试工具使用:
@Test        标识为测试方法
@Before        标识为测试方法初始化模块
@After        标志为测试方法释放模块
@BeforeClass    标识为测试类初始化模块
@AfterClass    标志为测试类释放模块

使用说明:
    首先先新建一个测试类,并导入junit包,在类中新建对应将要测试类的测试方法,在每个测试方法上面必须标明@Test标识符,在OutLine窗口上,点击要测试的类获方法名,选择Run As选项,执行即可。

Assert 断言:
    设置并判断测试后输出值是否与期望值相等。


*****************************************************************************************************************

2012-01-22 11:27

增强for循环只能应用在数组或者实现iterable接口的集合类上。
Map、Map.Entry、Set的运用
    @Test
    public void Test1()
    {
        int[] art = new int[]{1,2,4};
        for(int i : art)
        {
            System.out.println(i);
        }
    }
    @Test
    public void test2()
    {
        ArrayList array = new ArrayList();
        array.add(1);
        array.add(2);
        array.add(3);
        array.add(4);
        for(Object obj : array)
        {
            System.out.println((Integer)obj);
        }
    }
    @Test
    public void Test3()
    {
        Map map = new HashMap();
        map.put(1, "aa");
        map.put(2, "bb");
        map.put(3, "cc");
        Set set = map.keySet();
        Iterator ite = set.iterator();
        while(ite.hasNext())
        {
            int key =  (Integer) ite.next();
            String value = (String) map.get(key);
            System.out.println(key+"="+value);
        }
    }
    @Test
    public void Test4()
    {
        Map map = new LinkedHashMap();
        map.put("1", "aa");
        map.put("2", "bb");
        map.put("3", "vv");
        map.put("4", "cc");
        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+"="+value);
        }
    }
    @Test
    public void Test5()
    {
        Map map = new LinkedHashMap();
        map.put("1", "ff");
        map.put("2", "aa");
        map.put("3", "dd");
        map.put("4", "gg");
        Set set  = map.entrySet();
        Iterator it = set.iterator();
        while(it.hasNext())
        {
            Map.Entry entry = (Entry) it.next();
            String key = (String) entry.getKey();
            String value = (String) entry.getValue();
            System.out.println(key+"="+value);
            
        }
    }
    @Test
    public void Test6()
    {
        Map map = new LinkedHashMap();
        map.put("1", "ff");
        map.put("2", "aa");
        map.put("3", "dd");
        map.put("4", "gg");
        for(Object obj : map.keySet())
        {
            String key = (String) obj;
            String value = (String) map.get(key);
            System.out.println(key+"="+value);
        }
    }
    @Test
    public void Test7()
    {
        Map map = new HashMap();
        map.put("1", "ff");
        map.put("2", "aa");
        map.put("3", "dd");
        map.put("4", "gg");
        for(Object obj : map.entrySet())
        {
            Map.Entry entry = (Entry) obj;
            String key = (String) entry.getKey();
            String value = (String) entry.getValue();
            System.out.println(key+"="+value);
        }
    }


*****************************************************************************************************************

2012-01-24 10:00

枚举enum
枚举就是给程序设置常量值的类,是特殊的java类,里面可以含有普通方法,可继承接口和抽象方法。
举例!
public class EnumTest2 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(WeekendClass.TUE.getEnglishValue());
        System.out.println(WeekendClass.TUE.getChineseValue());
    }

}
/**
 * 普通枚举与抽象枚举
 * @author flame
 *
 */
enum WeekendClass
{
    //每个枚举都是对象
    //设置传输值,继承并实现抽象方法
    SUN("Sunday"){
        public String getChineseValue()
        {
            return "星期日";
        }
    }
    ,MON("monday"){
        public String getChineseValue()
        {
            return "星期一";
        }
    }
    ,TUE("tuesday"){
        public String getChineseValue()
        {
            return "星期二";
        }
    }
    ,WED("wednesday"){
        public String getChineseValue()
        {
            return "星期三";
        }
    }
    ,THU("thursday"){
        public String getChineseValue()
        {
            return "星期四";
        }
    }
    ,FRI("friday"){
        public String getChineseValue()
        {
            return "星期五";
        }
    }
    ,SAT("Saturday"){
        public String getChineseValue()
        {
            return "星期六";
        }
    }
    ;
    private String value;
    //构造函数传值
    private WeekendClass(String value)
    {
        this.value = value;
    }
    //普通方法,获取常量值
    public String getEnglishValue()
    {
        return this.value;
    }
    //抽象方法
    public abstract String getChineseValue();
}

*****************************************************************************************************************

2011-01-24 10:00

反射(reflect)
反射就是加载类并解剖出类中的各个组成部分。
1、加载类
        //用forname方法通过传入类的完全路径来加载类对象。
        Class clazz = Class.forName("/IODemo20120113/src/com/flame/Reflect/penson.java");
        //采用getClass方法来加载类对象。
        Class clazz1 = new penson().getClass();
        //用类的静态方法来加载对象。
        Class clazz2 = penson.class;
*****************************************************************************************************************

2012-02-09 22:26
反射(reflect)
反射构造函数
    public static void Test() throws Exception
    {
        //加载类
        Class clazz = Class.forName("/WebBestDemo/src/cn/flame/Refect/Person");
        //反射类的构造函数
        Constructor c = clazz.getConstructor(null);
        //实例化类
        Person p = (Person) c.newInstance(null);
        //访问Person中的参数
        System.out.println(p.name);
        
        //解剖出带参数函数
        Constructor c1 = clazz.getConstructor(String.class);
        Person p1 = (Person) c1.newInstance("aaaa");
        
        //解剖出私有构造函数
        Constructor c2 = clazz.getDeclaredConstructor(String.class,int.class);
        //暴力破解私有构造函数
        c2.setAccessible(true);
        //实例化
        Person p2 = (Person) c2.newInstance("aa",12);
    }

反射方法
    public void Test1() throws Exception
    {
        Class clazz = Class.forName("/WebBestDemo/src/cn/flame/Refect/Person");
        Person p = (Person) clazz.newInstance();
        
        //public void aaa1()
        Method method =  clazz.getMethod("aaa1", null);
        method.invoke(p, null);
        
        //public String aaa1(String str,int[] array)
        Method method1 = clazz.getMethod("aaa1", String.class,int[].class);
        String str = (String) method1.invoke(p, "prame",new int[]{1,2,3});
        
        //private void aaa1(String name)
        Method method2 = clazz.getDeclaredMethod("aaa1", String.class);
        method2.setAccessible(true);
        method2.invoke(p, "name");
        
        //public static void aaa1(int i)
        Method method3 = clazz.getMethod("aaa1", int.class);
        method3.invoke(null, 12);
        
        //public static void main(String[] args)
        Method method4 = clazz.getMethod("main", String[].class);
        method4.invoke(null, new Object[]{new String[]{"aa","bb"}});
        //method4.invoke(null, (Object)new String[]{"aa","bb"});
    }

反射字段
    public void test() throws Exception
    {
        Class clazz = Class.forName("/WebBestDemo/src/cn/flame/Refect/Person");
        Person p = (Person) clazz.newInstance();
        
        //public String name = "aaa";
        Field f = clazz.getField("name");
        Object obj = f.get(p);
        Class c = f.getType();
        if(c.equals(String.class))
        {
            String str = (String) obj;
        }
        
        //private int age = 12;
        Field f1 = clazz.getField("age");
        int i = (Integer) f1.get(p);
        
        //public static int age = 12;
        Field f2 = clazz.getField("age");
        int i2 = (Integer) f1.get(p);
        
    }
*****************************************************************************************************************

2012-02-10 12:15
内省操作javaBean
内省(Introspector):san公司开发的一套API,用于操作java对象的属性。
内省访问javaBean的方式有两种:
1、通过PropertyDescriptor类操作Bean
2、通过Introspector类获得Bean对象的BeanInfo,然后通过BeanInfo来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获得某个属性对应的getter/setter方法,然后通过反射机制来调用这些方法。
*****************************************************************************************************************

2012-02-11 10:30
内省操作javaBean
    public void test1() throws Exception
    {
        BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);
        //去掉父级属性
        //BeanInfo beanInfo = Introspector.getBeanInfo(Person.class,Object.class);
        PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
        for(PropertyDescriptor pd : pds)
        {
            System.out.println(pd.getName());
        }
    }
    @Test
    public void test2() throws Exception
    {
        Person p = new Person();
        //获得JavaBean属性描述器中的age属性描述
        PropertyDescriptor pd = new PropertyDescriptor("age", Person.class);
        Method method = pd.getWriteMethod();
        method.invoke(p, 45);
        method = pd.getReadMethod();
        System.out.println(method.invoke(p,null));
        System.out.println(pd.getPropertyType());
    }
*****************************************************************************************************************

2012-02-11 11:23
使用BeanUtils框架操作JavaBean
BeanUtils是第三方架包
使用此程序需要在项目中装两个插件:commens-beanutils,commons-logging

    @Test
    public void Test1() throws IllegalAccessException, InvocationTargetException
    {
        
        //BeanUtils有自动转换类型功能,但是仅支持8大基本类型,故要是程序自动转换别的类型时,需要在程序开始时写明注册码
        /*
        ConvertUtils.register(new Converter() {
            @Override
            public Object convert(Class type, Object value) {
                // TODO Auto-generated method stub
                if(value == null)
                {
                    return null;
                }
                if(value instanceof String)
                {
                    //此处抛出类型在API文档里面有指定抛出那个异常,一边程序识别.
                    throw new ConversionException("此注册只支持String类型转换!");
                }
                String str = (String) value;
                if(str.trim().equals(""))
                {
                    return null;
                }
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                try {
                    return sdf.parse(str);
                } catch (ParseException e) {
                    // TODO Auto-generated catch block
                    throw new RuntimeException(e);//异常链不能断
                }
            }
        }, Date.class);
        */
        Person p = new Person();
        String name = "flame";
        String age = "12";
        String password = "adasfs";
        String brithday = "2012-02-11";
        BeanUtils.setProperty(p, "name", name);
        //BeanUtils.setProperty(p, "age", age);
        //BeanUtils.setProperty(p, "password", password);
        //BeanUtils.setProperty(p, "brithday", brithday);
        System.out.println(p.getName());
        System.out.println(p.getAge());
        System.out.println(p.getPassword());
        //System.out.println(p.getBrithday());
    }
    @Test
    public void Test2() throws IllegalAccessException, InvocationTargetException
    {
        Map map = new HashMap();
        map.put("name", "flame");
        map.put("age", "12");
        map.put("password", "addasff");
        map.put("birthday", "2012-02-11");
        ConvertUtils.register(new Converter() {
            @Override
            public Object convert(Class type, Object value) {
                // TODO Auto-generated method stub
                if(value == null)
                {
                    return null;
                }
                if(value instanceof String)
                {
                    //此处抛出类型在API文档里面有指定抛出那个异常,一边程序识别.
                    throw new ConversionException("此注册只支持String类型转换!");
                }
                String str = (String) value;
                if(str.trim().equals(""))
                {
                    return null;
                }
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                try {
                    return sdf.parse(str);
                } catch (ParseException e) {
                    // TODO Auto-generated catch block
                    throw new RuntimeException(e);//异常链不能断
                }
            }
        }, Date.class);
        Person p = new Person();
        BeanUtils.populate(p, map);
        System.out.println(p.getName());
        System.out.println(p.getAge());
        System.out.println(p.getPassword());
    }
*****************************************************************************************************************

2012-02-11 18:23
泛型:
声明方式:    ArrayList<String> list = new ArrayList<String>();
        ArrayList list = new ArrayList<String>();
        ArrayList<String> list = new ArrayList();
*****************************************************************************************************************

2012-02-11 18:25
XML
声明:        <?xml version="1.0" encoding="GB2312" standalone="yes" ?>
字段解析:    version      版本号
        encoding     编码
         standalone     是否独立
CDATA区域     <!CDATA[内容]>
样式指令    <?xml-stylesheet type="text/css" href="" ?>

XML约束
    一份XML约束另一方XML文本的写法。
XML DTD(Document Type Definition,文档类型定义)
    在XML文档上的声明语句<!DOCTYPE 书架 SYSTEM "book.dtd" >

IE编程校验XML
    IE根据约束文档校验XML文件需要经过脚本执行,执行语句为:
    //创建文档解析对象
    var xmldoc = new ActiveXObject("Microsoft.XMLDOM");    
    //开启XML检验
    xmldoc.validateOnParse = "true";
    //装在XML文档
    xmldoc.load("book.xml");
    //获取错误信息
    xmldoc.parseError.reason;
    xmldoc.parseError.line;
XML Schema    
*****************************************************************************************************************

2012-02-11 22:46
XML解析技术
概述:
dom:(Document Object Modle,即文档对象模型)是W3C组织推荐的解析XML的一种方式。
优点:适合对数据进行增删改查;缺点:占用内存比较大;
sax:(Simple API for XML)不是官方标准,但它是XML社区事实上的标准,几乎所有XML解析器都支持它。
优点:占用内存小,解析熟读快,适合读取数据;缺点:不能对数据进行增删改查;
XML解析开发包:Jaxp(sun)、Jdom、dom4j
*****************************************************************************************************************

2012-02-12 09:35
调整JVM(Java虚拟机)内存大小
    Java虚拟机默认使用内存大小为64M,当程序运行内存超过时会抛出异常。故当项目过大时需要更改虚拟机内存。-Xmx80m

*****************************************************************************************************************

2012-02-12 09:47
JAXP
    此开发包为J2EE的一部分,由SUN公司提供,由javax.xml、org.w3c.dom、org.xml.sax包及其子包组成。
使用方法:
    在javax.xml.parsers包中,定义了几个工厂类,程序员调用这些工厂类,可以的到XML的dom和sax解析器,从而实现对XML文档的解析。
/**
 * 此类讲述如何用JAXP解析XML
 * @author flame
 * @CreateTime 上午10:56:00
 */
public class XMLDemo1 {
    /**
     * 此方法讲述如何加载JAXP解析器
     * 1、创建解析器工程
     * 2、创建解析器
     * 3、加载XML文档
     * @throws Exception
     */
    @Test
    public void LoadXMLs() throws Exception
    {
        //获取 DocumentBuilderFactory 的新实例。
        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        // 使用当前配置的参数创建一个新的 DocumentBuilder 实例。
        DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
        //将给定文件的内容解析为一个 XML 文档,并且返回一个新的 DOM Document 对象。
        Document document = domBuilder.parse("src/cn/flame/XML/Book.xml");
        //接下来可以对XML文档进行所需要的操作
        
        Node node = document.getElementsByTagName("书名").item(0);
        String nodeStr = node.getTextContent();
        System.out.println(nodeStr);
        
    }
    /**
     * 实例化一个解析器
     * @return Document
     * @throws Exception
     */
    public Document LoadXML() throws Exception
    {
        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
        Document document = domBuilder.parse("src/cn/flame/XML/Book.xml");
        return document;
    }
    /**
     * 读取XML文档对象
     * @throws Exception
     */
    @Test
    public void readerXML() throws Exception
    {
        Document document = LoadXML();
        
        Node root = document.getElementsByTagName("书架").item(0);
        ListNode(root);
        
    }
    /**
     * 采用递归算法循环输出标签名
     * @param node
     */
    private void ListNode(Node node) {
        // TODO Auto-generated method stub
        if(node instanceof Element)
        {
            System.out.println(node.getNodeName());
        }
        NodeList list = node.getChildNodes();
        for(int i=0;i<list.getLength();i++)
        {
            Node child = list.item(i);
            ListNode(child);
        }
        
    }
}
*****************************************************************************************************************

2012-02-12 15:36
JAXP解析XML
增删查改:
/**
 * 此类讲述如何用JAXP解析XML
 * @author flame
 * @CreateTime 上午10:56:00
 */
public class XMLDemo1 {
    /**
     * 此方法讲述如何加载JAXP解析器
     * 1、创建解析器工程
     * 2、创建解析器
     * 3、加载XML文档
     * @throws Exception
     */
    @Test
    public void LoadXMLs() throws Exception
    {
        //获取 DocumentBuilderFactory 的新实例。
        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        // 使用当前配置的参数创建一个新的 DocumentBuilder 实例。
        DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
        //将给定文件的内容解析为一个 XML 文档,并且返回一个新的 DOM Document 对象。
        Document document = domBuilder.parse("src/cn/flame/XML/Book.xml");
        //接下来可以对XML文档进行所需要的操作
        
        Node node = document.getElementsByTagName("书名").item(0);
        String nodeStr = node.getTextContent();
        System.out.println(nodeStr);
        
    }
    /**
     * 实例化一个解析器
     * @return Document
     * @throws Exception
     */
    public Document LoadXML() throws Exception
    {
        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
        Document document = domBuilder.parse("src/cn/flame/XML/Book.xml");
        return document;
    }
    /**
     * 将节点从内存区上刷新到本地文本上
     * @param document
     * @throws Exception
     */
    public void WriterToXml(Document document) throws Exception
    {
        TransformerFactory tranfactory = TransformerFactory.newInstance();
        Transformer tf = tranfactory.newTransformer();
        tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/cn/flame/XML/Book.xml")));
    }
    /**
     * 读取XML文档对象
     * @throws Exception
     */
    @Test
    public void readerXML() throws Exception
    {
        Document document = LoadXML();
        
        Node root = document.getElementsByTagName("书架").item(0);
        ListNode(root);
        
    }
    /**
     * 采用递归算法循环输出标签名
     * @param node
     */
    private void ListNode(Node node) {
        // TODO Auto-generated method stub
        if(node instanceof Element)
        {
            System.out.println(node.getNodeName());
        }
        NodeList list = node.getChildNodes();
        for(int i=0;i<list.getLength();i++)
        {
            Node child = list.item(i);
            ListNode(child);
        }
        
    }
    /**
     * 增加节点
     * @throws Exception
     */
    @Test
    public void AddNode() throws Exception
    {
        Document document = LoadXML();
        Element Celement = document.createElement("价格");
        Celement.setTextContent("88");
        Element Felement = (Element) document.getElementsByTagName("书").item(0);
        Felement.appendChild(Celement);
        WriterToXml(document);
    }
    /**
     * 删除XML节点
     * @throws Exception
     */
    @Test
    public void delete() throws Exception
    {
        Document document = LoadXML();
        Element emt = (Element) document.getElementsByTagName("价格").item(0);
        emt.getParentNode().removeChild(emt);
        WriterToXml(document);
    }
    /**
     * 更新XML节点
     * @throws Exception
     */
    @Test
    public void update() throws Exception
    {
        Document document = LoadXML();
        Element emt = (Element) document.getElementsByTagName("价格").item(0);
        emt.setTextContent("0909");
        WriterToXml(document);
    }
}

*****************************************************************************************************************

2012-02-12 22:26
SAX解析
public class Demo1 {
    /**
     * 创建解析工厂
     * 创建解析器
     * 创建读取器
     * 设置注册事件处理器
     * 设置要解析的XML文档
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     */
    @Test
    public void Test1() throws ParserConfigurationException, SAXException, IOException{
        //创建解析工厂
        SAXParserFactory factory = SAXParserFactory.newInstance();
        //创建SAX解析器
        SAXParser saxParser = factory.newSAXParser();
        //得到读取器
        XMLReader xmlReader = saxParser.getXMLReader();
        BeanListContent beanlist = new BeanListContent();
        //设置应用程序注册内容事件处理器
        xmlReader.setContentHandler(beanlist);
        //设置要解析的XML文档
        xmlReader.parse("src/cn/flame/SAXXMLDemo/Book.xml");
        List<Book> list = beanlist.getList();
        Iterator<Book> iterator = list.iterator();
        while(iterator.hasNext())
        {
            String name = iterator.next().getName();
            String author = iterator.next().getAuthor();
            String price = iterator.next().getPrice();
            System.out.println("书名:"+name);
            System.out.println("作者:"+author);
            System.out.println("价格"+price);
        }
    }
    
    public class BeanListContent extends DefaultHandler{
        private List<Book> list =  new ArrayList<Book>();
        private String contentTag;
        private Book book;
        @Override
        public void startElement(String uri, String localName, String qName,
                Attributes attributes) throws SAXException {
            contentTag = qName;
            if("书".equals(contentTag))
            {
                book = new Book();
            }
        }
        @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            if("书名".equals(contentTag))
            {
                String name = new String(ch,start,length);
                book.setName(name);
            }
            if("作者".equals(contentTag))
            {
                String author = new String(ch,start,length);
                book.setAuthor(author);
            }
            if("价格".equals(contentTag))
            {
                String price = new String(ch,start,length);
                book.setPrice(price);
            }
            
        }

        @Override
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
            if("书名".equals(contentTag)){
                list.add(book);
                book = null;
            }
            contentTag = null;
        }
        public List<Book> getList() {
            return list;
        }

        
        
    }
}
*****************************************************************************************************************

2012-02-13 22:23
dom4j

内容可在配带文档里面找到
*****************************************************************************************************************

2012-02-15 20:43
跳过课程:dom4j-----02-15
        -
        -
        -
              02-20

*****************************************************************************************************************

2012-02-15 22:03
快速在屏幕上打印出一个M字
public class PrintM {

    /**
     * 在屏幕上快速打印一个M
     * 采用方法,用一个二位数组打印
     * 无论做平面开发还是做游戏开发,都可以把屏幕上的内容看成二位数组。
     * @param args
     */
    public static void main(String[] args) {
        //任意数字打印M
        int num = 90;
        //高度初始值
        int hight = num/4+1;
        //宽度初始值
        int width = num;
        int[][] arr = new int[hight][width];
        int x= hight-1;
        int y =0;
        boolean order = false;
        for(int i=1;i<=num;i++){
            arr[x][y] = i;
            y++;
            if(!order) x--;
            if(order)    x++;
                
            if(x<0){
                order = true;
                x +=2;
            }
            if(x>hight-1){
                order = false;
                x -=2;
            }
        }
        for(int i=0;i<arr.length;i++){
            for(int j=0;j<arr[i].length;j++){
                if(arr[i][j]==0){
                        System.out.print(" ");
                }else{
                    System.out.print("*");
                }
            }
            System.out.println();
        }
    }

}
*****************************************************************************************************************
WEB 开发=========================================================================================================
*****************************************************************************************************************

2012-02-15 23:06
Tomcat
配置一个WEB应用:
在Tomcat目录下的 conf =》server.xml 文件里面,在最下面标签</Host>之前配置这么一段标签
<Context path="你所设置的虚拟路径" docBase="web应用程序所在路径" />
这种配置的弊端在与,需要重启服务器,当服务器重启时,那么外界将无法访问到WEB应用程序.
*****************************************************************************************************************

2012-02-16 00:36
配置虚拟主机:
1、在Tomcat服务器中可以放置多个网站,所谓配置虚拟主机就是在tomcat服务器中配置一个网站。
2、如需在WEB服务器中配置一个网站,需使用Host元素进行配置,例:
    <Host name="site1" appBase="c:\app" ></Host>
    <Host name="www.google.com" appBase="c:\app">
        <Context path="" docBase="c:\app\mail" />
    </Host>
3、配置的主机(网站)要想呗全部访问,必须在DNS服务器或window中注册。
4、配置多个网站
5、缺省虚拟主机
6、在WEB.XML文件里面设置首页
    <welcome-file-list>
        <welocme-file>index.html</welcome-file>
    </welcome-file-list>

程序打包
1、把程序用jar命令打包成扩展名为war的文件,这样的文件服务器能自动解压
2、需要在web.xml中给context元素设定reloadable="true",这样能使程序自动更新原有包。
    例:
<Host name="www.google.com" appBase="c:\app">
    <Context path="" docBase="c:\app\mail" reloadable="true
" />
</Host>
3、上面第二条不建议配置
*****************************************************************************************************************

2012-02-17 21:34
加密
1、对称加密
2、非对称加密
3、数据证书
*****************************************************************************************************************

2012-02-17 22:10
Tomcat管理平台
步骤:
1、开启Tomcat服务器
2、登陆Tomcat,在做菜单上点击Tomcat Manager选项,这时会弹出一个登陆窗口
3、配置用户名和密码
    进入Tomcat服务器,在conf目录下有一个文件名为:tomcat-users.xml的配置文件,打开配置文件,里面会有已注释的用户和角色。
*****************************************************************************************************************

2012-02-17 22:31
HTTP协议:
方法一:
1、在服务器目录下的webapps目录下增加一个web程序
2、启动服务器
3、打开CMD 输入 telnet localhost(服务器) 8080(端口) 回车键
4、输入指令    GET /aa(应用程序名)/1.html HTTP/1.1 (协议版本)
5、输入Host: 回车键

方法二:安装IE插件HttpWatch插件
*****************************************************************************************************************

2012-02-18 10:02
HTTP请求解析
-------------------------------------------------------------------------------------------------------------
请求:
GET / HTTP/1.1
Accept: */*
Accept-Language: zh-CN
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; Tablet PC 2.0; BOIE9;ZHCN)
Accept-Encoding: gzip, deflate
Host: www.baidu.com
Connection: Keep-Alive
Cookie: viewSpFirstTipsc543cedec2b7d7dfc0b26c07=1; USERID=78973ad6e052f35601d62846; BDUSS=hMZzF0R2VsZThyfmZCT2JaZno3UEo1NnhlUnlvdFlyRnBZejc3dE8tNHZpMTFQQVFBQUFBJCQAAAAAAAAAAAouTQwHDIgMZG9yYW53aW4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADg-t-WKgAAAOD635YqAAAAuWZCAAAAAAAxMC42NS40NC~-NU8v~jVPTH; IK_LOVE=1; BAIDUID=DFD3C91BE3EE512DC2695DD8D19FE497:FG=1
------------------------------------------------------------------------------------------------------------
1、第一行为请求行,其余为请求头 ,请求行主要请求方式有GET POST两种
2、请求头含义:
Accept            告诉服务器,客户机所支持数据类型
Accept-Charset        告诉服务器,客户机采用的编码
Accept-Encoding        告诉服务器,客户机支持的压缩格式
Accept-Language        客户机的语言环境
Host            告诉服务器,客户机想访问的主机名
If-Modified-Since    告诉服务器,客户机资源的缓存时间
If-None-Match        缓存相关
Referer            告诉服务器,客户机是从哪个资源访问服务器的,防盗链用
User-Agent        告诉服务器,客户机的软件环境
Cookie            客户机通过这个头可以向服务器带点数据
Connection        告诉服务器,客户机访问请求后是否保持链接或者关闭连接,关闭连接为Close,请求为Keep-Alive
Date            告诉服务器,客户机当前的时间值

-----------------------------------------------------------------------------------------------------------------
响应:
HTTP/1.1 200 OK
Date: Sat, 18 Feb 2012 02:55:43 GMT
Server: BWS/1.0
Content-Length: 9517
Content-Type: text/html;charset=utf-8
Cache-Control: private
Content-Encoding: gzip
Vary: Accept-Encoding
Expires: Sat, 18 Feb 2012 02:55:43 GMT
Connection: Keep-Alive
---------------------------------------------------------------------------------------------------------------
1、第一行为状态行,响应协议、状态码、状态说明
2、除了第一行,其余为响应头,描述服务器的基本信息和信息的描述,告诉客户机如何处理返回数据。
3、响应头含义:
Location:这个头配合302状态使用(路径转移),用于告诉客户找谁
Server:告诉浏览器服务器的类型
Content-Encoding:告诉浏览器数据的压缩格式
Content-Length:告诉浏览器数据长度
Content-Language:回送的语言环境
Content-Type:服务器告诉浏览器回送数据的类型
Last-Modified:告诉浏览器当前资源的缓存时间
Refresh:告诉浏览器隔多长时间之后刷新一次
Content-Disposition:attachment;filename=....    告诉服务器以下载方式下载数据
Transfer-Encoding:告诉浏览器数据的传送格式
Set-Cookies:
ETag:缓存相关的头,可以做到实时更新。浏览第二次向服务器发请求时会带这么一个头,服务器会根据这个缓存头的时间和服务器    检测,如果时间不一致说明服务器内容更改,那么服务器会向客户端发送最新数据,如果一样时,服务器会让客户端去缓    存拿数据。
Expires:服务器通过这个头,告诉浏览器把回送的资源缓存多长时间,-1或0,-1是不缓存。
Cache-Control:no-cache
Pragma:no-cache
服务器通过以上两个头,也是控制浏览器不要缓存数据
Connection:保持连接和断开连接
Date:当前时间
4、状态码解说:
----------------|-----------------------------------------------------------------------------------------------|
 状态码        |            含义                                    |
----------------|-----------------------------------------------------------------------------------------------|
100~199        |表示成功接收请求,要求客户端继续提示下一次请求才能完成整个处理过程                |
----------------|-----------------------------------------------------------------------------------------------|
200~299        |表示成功接收请求并已完成整个处理过程,常用200                            |
----------------|-----------------------------------------------------------------------------------------------|
300~399        |为完成请求,客户需要进一步细化请求。例如,请求的资源已经移动一个新地址,常用302,307,和304。    |
----------------|-----------------------------------------------------------------------------------------------|
400~499        |客户端的请求有错误,常用404、403                                |
----------------|-----------------------------------------------------------------------------------------------|
500~599        |服务器端出现错误,常用500                                    |
----------------|-----------------------------------------------------------------------------------------------|    
*****************************************************************************************************************

2012-02-18 13:10
Servlet入门
手写步骤:
1、在tomcat中新建一个day04应用程序,在WEB应用程序中新建一个WEB-INF/CLASSES目录
2、在classes中新建一个firstservlet
package cn.flame.web
import java.io.*;
import javax.servlet;
public class FirstServlet extandx GenericServlet{
        public void service(ServletRequest req,ServletResponse res)throws ServletException,java.io.IOException
        {
            OutputStream out = reg.getOutputStream();
            out.write("hello servlet");
        }
}
3、set classpath=%classpath%;....servlet.jar 编译servlet()
4、在WEB-INF目录中新建一个WEB.XML文件,配置servlet对外访问路径。
    <servlet>
      <servlet-name>FirstServlet</servlet-name>
      <servlet-class>cn.flame.web</servlet-class>
   </servlet>
   <servlet-mapping>
       <servlet-name>FirstServlet</servlet-name>
       <url-pattern>/FirstServlet</url-pattern>
   </servlet-mapping>
5、启动服务器访问。
*****************************************************************************************************************

2012-02-18 14:13
servlet的调用过程和生命周期:
1、servlet 使用户第一次访问时调用Servlet实例创建对象,这个对象创建之后就驻留在内存中响应后续请求。
2、servlet 一被创建那么init方法会被执行,客户端的每次请求会导致servlet方法被执行
3、servlet被摧毁时destroy方法会被执行
4、当WEB服务器关闭或者WEB应用程序被移除服务器时Servlet被摧毁

*****************************************************************************************************************

2012-02-18 18:00
Servlet线程安全

*****************************************************************************************************************

2012-02-18 19:00
ServletConfig对象
用于配置数据,例如数据库连接语句、编码表、。。。
ServletContext
相当于当前应用, 当服务器启用时,会针对每一个WEB工程设定一个ServletContext,当服务器停掉或者WEB程序被移除时ServletContext被摧毁。
*****************************************************************************************************************

2012-02-19 00:08
ServletContext读取资源文件
    public void Test1() throws IOException {
        InputStream in = this.getServletContext().getResourceAsStream(
                "/WEB-INF/classes/conn.properties");
        Properties props = new Properties();
        //Properties 本身继承MAP,故其值为键值存在
        props.load(in);
        String url = props.getProperty("url");
        String username = props.getProperty("username");
        String password = props.getProperty("password");
        System.out.println(url);
        System.out.println(username);
        System.out.println(password);
    }
    public void Test2() throws IOException {
        //根据ServletContext获取绝对路径
        String path = this.getServletContext().getRealPath("/conn.properties");
        FileInputStream fInputStream = new FileInputStream(path);
        Properties props = new Properties();
        //Properties 本身继承MAP,故其值为键值存在
        props.load(fInputStream);
        String url = props.getProperty("url");
        String username = props.getProperty("username");
        String password = props.getProperty("password");
        System.out.println(url);
        System.out.println(username);
        System.out.println(password);
    }
*****************************************************************************************************************

2012-02-20 20:14
HttpServletResponse
1、输出数据时,注意字节表问题,需标明字节表类型。
*****************************************************************************************************************

2012-02-20 22:45
HttpServletResponse实现下载功能
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获得文件绝对路径
        String pathString = getServletContext().getRealPath("/download/1.JPG");
        //根据文件绝对路径获取文件名
        String filename = pathString.substring(pathString.lastIndexOf("\\"+1));
        //在响应头表明输出数据类型为下载类型,并声明下载文件名,文件名需要用URLEncoder格式化为指定编码格式,以防乱码
        response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(filename, "UTF-8"));
        OutputStream outputStream = null;
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(pathString);
            outputStream = response.getOutputStream();
            int len = 0;
            byte[] by = new byte[1024];
            while((len = inputStream.read(by))>0){
                outputStream.write(by, 0, len);
            }
        } catch (Exception e) {
        }finally{
            try {
                outputStream.close();
            } catch (Exception e2) {
            }
            try {
                inputStream.close();
            } catch (Exception e2) {
            }
        }
        
    }
//注意编码问题,以防乱码。在java中编码很重要.
*****************************************************************************************************************

20:26 2012/2/23
实现随机验证码图片验证
public class DrowImage extends HttpServlet {
    public static final int WIDTH = 80;
    public static final int HEIGHT = 35;
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //实例化一个BufferedImage实例
        BufferedImage buffimg = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        //获取一个Graphics画图实例
        Graphics g = buffimg.getGraphics();
        //设置背景颜色
        setBackGround(g);
        //设置边框
        setBorder(g);
        //设置随机干扰线
        drawRandomLine(g);
        //设置随机数字
        drawRandomNum((Graphics2D) g);
        //响应 声明输出数据类型
        response.setContentType("image/jpeg");
        //响应 告诉浏览器不缓存图片  三个加载一起支持所有浏览器
        response.addDateHeader("Expires", -1);
        response.addHeader("Cache-Control", "no-cache");
        response.addHeader("Pragma", "no-cache");
        //调用ImageIO类将图片写到输出流里面
        ImageIO.write(buffimg, "jpeg", response.getOutputStream());
    }
    private void setBackGround(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, WIDTH, HEIGHT);
    }
    private void setBorder(Graphics g) {
        g.setColor(Color.BLUE);
        g.drawRect(1, 1, WIDTH-2, HEIGHT-2);
    }
    private void drawRandomLine(Graphics g) {
        g.setColor(Color.GREEN);
        for(int i=0;i<8;i++){
            int x1 = new Random().nextInt(WIDTH);
            int y1 = new Random().nextInt(HEIGHT);
            
            int x2 = new Random().nextInt(WIDTH);
            int y2 = new Random().nextInt(HEIGHT);
            g.drawLine(x1, y1, x2, y2);
        }
    }
    private void drawRandomNum(Graphics2D g) {
        g.setColor(Color.RED);
        g.setFont(new Font("宋体", Font.BOLD, 30));
        int x = 10;
        for(int i=0;i<4;i++){
            int degree = new Random().nextInt()%30;
            int num = new Random().nextInt(9);
            g.rotate(degree*Math.PI/180,x,20);
            g.drawString(num+"", x, 30);
            g.rotate(-degree*Math.PI/180, x, 20);
            x +=15;
        }
    }

}
*****************************************************************************************************************

20:27 2012/2/23
用refresh控制浏览器定时刷新
    /**
     * 控制页面自动刷新跳转
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String mesString = "<meta http-equiv='refresh' content='3;url=index.jsp'>恭喜您登陆成功,页面将在3秒后跳转至首页,如果没有跳转请点击<a href=''>超链接</a>";
        this.getServletContext().setAttribute("message", mesString);
        this.getServletContext().getRequestDispatcher("/message.jsp").forward(request, response);
    }
*****************************************************************************************************************

21:11 2012/2/23
用Expires头控制浏览器缓存
在响应头输出缓存截止时间,也就是expires对应的值
*****************************************************************************************************************

21:42 2012/2/23
response实现请求重定向和response的一些细节
1、转发,跳转到指定页面后,浏览器地址栏地址不变。
response.setStatus(302);
response.setHeader("location","URL");
2、重定向,浏览器会向服务器发送两次,意味着就有2个request\response;且跳转到指定地址之后,浏览器地址栏地址为该指定地址。
response.sendRedirect("URL");

response注意事项 :
1、getOutputStream()用来输出二进制流数据;getWrite()用来输出字符流。
2、上面所述两个方法不能同时在一个servlet文件写,否则会抛出异常。
3、Servlet程序想ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再结合响应状态和各响应头组合后输出到客户端。
4、Servlet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象。
*****************************************************************************************************************

22:23 2012/2/23
request简介
在http://www.baidu.com/news/1.html中:
1、URI :/news/1.html    URI用来标识网站内容,URI是URL的父级。
2、URL :http://www.baidu.com/news/1.html  URL用来标识访问对象。

常用方法:
getRequestURL     方法返回客户端发出请求时的完整URL
getRequestURI    方法返回请求行中的资源名部分
getQueryString    方法返回请求行中的参数部分
getRemoteAddr    方法返回发出请求的客户机的IP地址
getRemoteHost    方法返回发出请求的客户机的完整主机名
getRemotePort    方法返回客户机所使用的网络端口号
getLocalAddr    方法返回WEB服务器的IP地址
getLocalName    方法返回WEB服务器的主机名
getMethod    得到客户机请求方式
getParameter    获得参数
getParameterNames获得同名参数枚举集合
getParameterValues 获得同名值数组
*****************************************************************************************************************

13:53 2012/2/26
request乱码问题
1、当表单提交为post方式时,用request.setCharacterEncoding("UTF-8")这种方法来指定提交数据的码表类型。
2、当表单提交为get方式时,用new String(username.getBytes("iso8859-1","UTF-8"))这种方法来制定提交数据去查哪个码表来并转换为指定数据。
*****************************************************************************************************************

20:21 2012/2/27
MVC
m-model(javabean)
v-view(jsp)
c-cotrolter(servlet)
*****************************************************************************************************************

20:44 2012/2/27
request转发到页面及包含到页面

1、转发:request.getRequestDispatcher(URL).forward(request,response);用来转发数据到jsp,jsp再请求servlet时不再产生新的request和response
2、包含:request.getRequestDispatcher(URL).include(request,response);用来把页面包含并发送出去,用于jsp架构排版。
*****************************************************************************************************************

21:17 2012/2/27
WEB工程中的各类地址写法
用到地址的地方:
1、request.getRequestDispatcher(URL).forward(request,response)服务器用

2、response.sendRedirect(RUL)浏览器用

3、this.getServletContext().getRealPath(URL)服务器用

4、this.getServletContext().getResourceAsStream(RUL)服务器用

5、<a href="URL"></a>浏览器用

6、<from action="URL" ></from>浏览器用

方法,以斜杆开头,如果给服务器用的说明地址为当前WEB应用,如果地址给浏览器用的说明地址代表网站。
如果当前地址为服务器所用,那只需斜杆加包名加页面名称;
如果当前服务器为浏览器用,那需要斜杆加上项目名再加上包名,最后才加上页面名;
当访问WEB程序资源时用“/”斜杆;
当访问本地磁盘程序时,用“\”反斜杠
*****************************************************************************************************************

21:36 2012/2/27
利用referer防盗链
String referer = request.getHeader("referer");
if(referer == null || !referer.startWith("http://localhost")){
    response.sendirect("RUL");
    return;
}
*****************************************************************************************************************

22:51 2012/2/27
cookies
public Cookie(String name,String value)-构造方法
setValue与getValue方法-获得值
setMaxAge与getMaxAge方法-存储时间
setPath与getPath方法-访问目录
setDomain与getDomain方法-访问域
getNames方法



protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter printWriter = response.getWriter();
        printWriter.print("上次访问时间是:");
        Cookie cookies[] = request.getCookies();
        for(int i=0;cookies != null && i<cookies.length;i++){
            if(cookies[i].getName().equals("lastacctiontime")){
                long lastacctiontime = Long.parseLong(cookies[i].getValue());
                Date date = new Date(lastacctiontime);
                printWriter.print(date.toLocaleString());
            }
        }
        Cookie cookie = new Cookie("lastacctiontime", System.currentTimeMillis()+"");
        cookie.setPath("/WebDemoProject1");
        cookie.setMaxAge(1*30*24*3600);
        response.addCookie(cookie);
        
    }
}
*****************************************************************************************************************

0:07 2012/2/28
cookie细节
一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
注意:删除cookie时,path必须一致,否则不会被删除。
*****************************************************************************************************************

21:28 2012/2/28
显示商品浏览历史纪录--案例
CookieDemo2代码:
package cn.flame.Cookie;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.print.attribute.ResolutionSyntax;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sun.org.apache.bcel.internal.generic.NEW;

/**
 * Servlet implementation class CookieDemo2
 */
public class CookieDemo2 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter pWriter = response.getWriter();
        pWriter.write("本网站现卖书籍有:<br/>");
        Map<String, Book> map = DB.getAll();
        for (Map.Entry<String, Book> entry : map.entrySet()) {
            Book book = entry.getValue();
            pWriter.write("<a href='/WebDemoProject1/CookieDemo3?id="+book.getBid()+"' taget='_blank' >"+book.getBname()+"</a> <br/>");
        }
        
        pWriter.write("你浏览过的书籍:<br/>");
        Cookie cookie[] = request.getCookies();
        Book book = null;
        for (int i = 0;cookie != null && i < cookie.length; i++) {
            if (cookie[i].getName().equals("bookhistory")) {
                String bulidString[] = cookie[i].getValue().split("\\,");
                for (int j = 0;bulidString != null && j < bulidString.length; j++) {
                    book = DB.getAll().get(bulidString[j]);
                    pWriter.write("<a href='/WebDemoProject1/CookieDemo3?id="+book.getBid()+"' target='_blank'>"+book.getBname()+"</a><br/>");
                }
            }
        }
    }
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}
class DB{
    private static Map<String, Book> map = new LinkedHashMap<String, Book>();
    static{
        map.put("1", new Book("1","j2ee真经","疯啦","440"));
        map.put("2", new Book("2","C#真经","打发","405"));
        map.put("3", new Book("3","SQL真经","爱的发声","603"));
        map.put("4", new Book("4","ORALER真经","发大水","460"));
    }
    public static Map<String, Book> getAll() {
        return map;
    }
}
class Book{
    private String bid;
    private String bname;
    private String authour;
    private String price;
    
    public Book() {
        super();
    }
    public Book(String bid, String bname, String authour, String price) {
        super();
        this.bid = bid;
        this.bname = bname;
        this.authour = authour;
        this.price = price;
    }
    public String getBid() {
        return bid;
    }
    public void setBid(String bid) {
        this.bid = bid;
    }
    public String getBname() {
        return bname;
    }
    public void setBname(String bname) {
        this.bname = bname;
    }
    public String getAuthour() {
        return authour;
    }
    public void setAuthour(String authour) {
        this.authour = authour;
    }
    public String getPrice() {
        return price;
    }
    public void setPrice(String price) {
        this.price = price;
    }
}
-------------------------------------------------------------------------------
CookieDemo3代码:
package cn.flame.Cookie;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.connector.Request;

import com.sun.org.apache.xml.internal.serialize.Printer;

/**
 * Servlet implementation class CookieDemo3
 */
public class CookieDemo3 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter pWriter = response.getWriter();
        String idString = request.getParameter("id");
        if (idString == null) {
            pWriter.write("非法入侵!");
            return;
        }
        //接收书的编码,并把该书打印到页面
        pWriter.write("你所查看的书的简介:<br/>");
        Book book = DB.getAll().get(idString);
        System.out.println(idString);
        if (book == null) {
            System.out.println("ddd");
            return;
        }
        pWriter.write("书编号:"+book.getBid()+"<br/>");
        pWriter.write("书名:"+book.getBname()+"<br/>");
        pWriter.write("作者:"+book.getAuthour()+"<br/>");
        pWriter.write("价格:"+book.getPrice()+"<br/>");
        //把编码存储到Cook中
        String cookieValue = bulidCookie(idString,request);
        Cookie cookie = new Cookie("bookhistory", cookieValue);
        cookie.setPath("/WebDemoProject1");
        cookie.setMaxAge(1*30*12*60*60);
        response.addCookie(cookie);
    }
    

    


    private String bulidCookie(String idString, HttpServletRequest request) {
        String bookhistory = null;
        Cookie cookie[] = request.getCookies();
        for (int i = 0;cookie != null && i < cookie.length; i++) {
            if (cookie[i].getName().equals("bookhistory")) {
                bookhistory = cookie[i].getValue();
            }
        }
        if (bookhistory == null) {
            return idString;
        }
        LinkedList<String> list = new LinkedList<String>( Arrays.asList(bookhistory.split("\\,")));
        if (list.contains(idString)) {
            list.remove(idString);
        }else {
            if (list.size()>=3) {
                list.removeLast();
            }
        }
        list.addFirst(idString);
        StringBuilder sbBuilder = new StringBuilder();
        for (String bidString : list) {
            sbBuilder.append(bidString+",");
        }
        return sbBuilder.deleteCharAt(sbBuilder.length()-1).toString();
    }





    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

*****************************************************************************************************************

19:20 2012/2/29
session
1、创建session代码request.getSession();--解析:当当前WEB程序没有session时,创建session,当存在时获取session;
2、只创建不获取session代码:request.getSession(false);--只创建session,根据构造参数决定是否获取session;
3、当浏览器访问WEB服务时,该服务有应用到session时,session启用,当客户端超过30分钟没有动该浏览器时,session自动删除
4、可以在web.xml配置文件里面配置session超时时间:
<session-config>
    <session-timeout>10</session-timeout>
</session-config>
5、在程序中用代码设置session超时时间:
session.invalidate();
6、session原理:session是基于cookie创建的,当发现当前不存在session时,服务器会基于cookie创建一个session,并将创建的cookie发送给浏览器,当浏览器继续访问WEB服务时,浏览器会带着这个cookie来,所以可以获取同一个session。
注:因为该cookie设置时没有创建有效期,所以当浏览器关闭时,将不再获取同一个session。
7、设置该session基于cookie的有效期(该功能引用于商城系统中):
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        //获得session
        HttpSession session = request.getSession();
        //获得sessionID
        String sessionid = session.getId();
        //创建一个cookie,名字为JSESSIONID,已覆盖session自动创建的cookie,且该cookie值为session的ID
        Cookie cookie = new Cookie("JSESSIONID", sessionid);
        //设置cookie的路径
        cookie.setPath("/WebDemoProject1");
        //设置cookie三十分钟后过期,因为session是30分钟后过期的
        cookie.setMaxAge(30*60);
        //把cookie加入都响应中
        response.addCookie(cookie);
        session.setAttribute("book", "java");
    }
*****************************************************************************************************************

21:06 2012/2/29
session使用细节
1、当浏览器禁用cookie时,就无法使用session了,所以需要用到一个技术叫做url重写。
String urlstr = response.encodeURL("URL");
当服务器没有发现浏览器所带的cookie时,会将URL重写,并在后面加上session基于cookie的ID;当服务器发现浏览器所携带的cookie时,服务器不会重写URL。
*****************************************************************************************************************

22:51 2012/2/29
客户端防表单重复提交和服务器端session防表单提交
当用户提交表单的时候,因为网络延迟,又点击了一次提交,导致了重复提交表单。
解决方案:

1、客户端用javascript,弊端,代码易被修改,容易遭攻击。优点,可增加用户体验。
2、用服务器,用程序输出表单,给每个表单配置一个随机数,通过随机数来辨别表单是否提交过。

/**
 *
 * @author flame
 * 随机数据(令牌)
 * 单例模式
 *
 */
class TokenProcessor{

    public TokenProcessor() {
        super();
    }
    private static final TokenProcessor instance = new TokenProcessor();
    public String generateToken() {
        //随机数
        String token = System.currentTimeMillis() + new Random().nextInt()+"";
        try {
            //将随机数以MD5加密
            MessageDigest md = MessageDigest.getInstance("md5");
            byte[] by = md.digest(token.getBytes());
            /*
             * 因为随机数解析出来的字符可能为乱码,所以用base64加密成键盘上的可见字符。
             * 原理:将字符位数中的每3位重新合成一个新字符
             * 原先字符,每个字符为8位
             * 0110 1010  0010 1001  0101 0011   这样三个字符
             * base64加密成每三位重组一个字符
             * 00011010 00100010 00100101 00010011
             * 这样的四个字符在base64码表中分别对应的指定的字符,该字符为键盘上可见字符
             */
            BASE64Encoder encoder = new BASE64Encoder();
            return encoder.encode(by);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        
    }
}
*****************************************************************************************************************

22:18 2012/3/1
三个域对象的总结:request 、session 、ServletContext
1、当程序产生数据后,显示完就不用了的话,那么用request作为数据容器
2、当程序产生数据后,显示完后还要用,那么可以用session
3、当程序产生数据后,可能别人也需要用,所以用ServletContext
*****************************************************************************************************************

22:57 2012/3/1
jsp
全称:java server page
jsp最佳实践
servlet主控制;jsp主显示;
*****************************************************************************************************************

23:51 2012/3/1
jsp语法
1、jsp模板元素
    jsp页面中的HTML内容称之为jsp模板元素;
    jsp模板元素定义了网页的基本骨架,即定义了页面的结构和外观;
2、jsp脚本表达式
    jsp表达式(expression)用于将程序数据输出到客户端语法<%=变量或表达式 %>
        举例:当前时间<%=new java.util.Date() %>
    jsp引擎在翻译脚本表达式时,会将程序数据转换成字符串,然后在相应位置用out.print(...)将数据输给客户端;
    jsp脚本表达式中的变量或表达式后面不能有分号(;)
3、脚本片段
    jsp脚本片段(scriptlet)用于在jsp页面中编写多行java代码。语法:
        <% 多行代码 %>
    注意:jsp脚本片段中只能出现java代码,不能出现其它模板元素,jsp引擎在翻译jsp页面中,会将jsp脚本片段中的java代码将被原封不动的放到servlet的_jspServlet方法中。
    jsp脚本片段中的java代码必须严格遵循java语法,例如,每执行语句后面必须用分号(;)结束;
    在一个jsp页面中可以有多个脚本片段,在两个或多个脚本片段之间可以嵌入文本、html标记和其他jsp元素。
    多个脚本片段中的代码可以互相访问,犹如将所有的代码放在一对<%%>之中的情况。如:out.println(x);
    单个脚本片段中的java语法可以使不完整的,但是,多个脚本片段组合后的结果必须是完整的java语句。
4、注释
    jsp注释格式:<%-- 注释信息 --%>
    jsp引擎在将jsp页面翻译成Servlet程序时,忽略jsp页面中被注释的内容。
5、jsp指令
    jsp指令(directive)是为jsp引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理jsp页面中的其余部分。
    指令的基本语法格式 <%@ 指令 属性名="值" %>
    举例:<$@ page contentType="text/html;charset=UTF-8"$>
    如果指令有多个属性,可以用多列写,也可以写在一起,如:
    <$@ page contentType="text/html;charset=UTF-8" import="java.util.Date" $>

    在jsp2.0规范中共定义了三种指令:
    (1)、page指令:用于定义jsp页面的各种属性,无论page指令出现在jsp页面中的什么地方,它作用的都是整个jsp页面,为了保持程序的可读性和遵循良好的编程习惯,page指令最好是放在整个页面的起始位置。
    [language="java"]——指定页面嵌入java代码
    [extends="package.class"]——指定页面继承于谁
    [import="package.class"]——指定页面导入那个包,可以在一条page指令的import属性中引入多个类包,其中每个包或类之间用逗号分隔。
    注:jsp引擎自动导入下面包:
        java.lang.*;
        javax.servlet.*;
        javax.servlet.jsp.*;
        javax.servlet.http.*;
    [session="true|false"]——指定是否在翻译为servlet时是否创建session对象,默认为true。
    [buffer="none | 8kb | sizekb"]——指定页面是否缓冲,默认8kb。
    [autoFlush="true|false"]——指定缓冲满了是否自动刷新。
    [isThreadSafe="true|false"]——指定jsp线程是否安全。
    [info="text"]——指定代理信息。
    [errorPage="relative_url"]——指定jsp错误处理页面。
    注:errorPage属性的设置必须使用相对路径,如果也"/"开头,表示相对于当前WEB应用程序的根目录(注意不是站点根目录),否则,表示相对于当前页面。
    可以在web.xml文件中使用<error-page>元素为整个web应用程序设置错误页面,其中的<exception-type>子元素指定异常类的完全限定名,<location>元素指定以"/"开头的错误处理页面的路径。
    <error-type>
        <exception-type>异常名字</exception-type>
        <location>错误页路径</location>
    </error-type>
    <error-type>
        <error-code>状态码</error-code>
        <location>错误页路径</location>
    </error-type>
    如果页面设置了errorPage属性指令,wen.xml文件配置的错误处理将不会对该页面起作用。
    [isErrorPage="true|false"]——指定当前页面是否为指定错误页,默认值为false。
    [contentType="text/html;charset=UTF-8"]——指定页面类型及编码。
    [pageEncoding="UTF-8"]——指定页面编码。
    [isElIgnored="true|false"]——指定jsp引擎是否忽略ELI表达式。
    (2)、include指令
    (3)、taglib指令
    
6、标签
7、内置对象
8、jsp声明
    jsp页面中编写的所有代码,默认会被翻译到servlet的service方法中,而jsp声明中的java代码会被翻译到_jspService方法的外面。语法:
    <%!
    java代码
    %>
    所以,jsp声明可用于定义jsp页面转换成的servlet程序的静态代码块、成员变量和方法。
    多个静态代码块、成员变量和函数可以定义在一个jsp声明中,也可以分别单独定义在多个jsp声明中。
    jsp隐式对象的作用范围仅限于servlet的_jspService方法,所以在jsp声明中不能使用这些隐式对象。
9、查找jsp页面中的错误
10、jsp乱码

*****************************************************************************************************************

21:52 2012/3/3
include指令:包含
1、语法
静态包含,在jsp编译时包含,将所有jsp编译成一个servlet。效率比较高。
<%include file="URL" %>
2、注意:
注意被包含页的标签;
include被称为静态包含,它所包含的jsp会被编译成一个servlet;
3、动态包含:jsp编译时将包含的jsp生成为servlet,等页面加载的时候再把servlet包含进去。性能比静态包含差;
<$
request.getRequestDispatcher("URL").include(request,response);
$>
*****************************************************************************************************************

22:02 2012/3/3
jsp运行原理:
1、每一个jsp页面在第一次被访问时,WEB容器都会把请求交给jsp引擎(即一个java程序)去处理。jsp引擎先将jsp翻译成一个_jspServlet(实际上是一个servlet),然后按照servlet的调用方式进行调用。
2、由于jsp第一次访问时会翻译成servlet,所以第一次访问通常会比较慢,但第二次访问,jsp引擎如果发现jsp没有变化,就不再翻译,而是直接调用,所以程序的执行效率不会受到影响。
3、jsp引擎在调用jsp对应的_jspServlet是,会传递或创建9个与web开发相关的对象供_jspServlet使用。jsp技术的设计者为便于开发人员在编写jsp页面时获得这些web对象的引用,特意定义了9个相对于大的变量,开发人员在jsp页面中通过这些变量就可以快速获得这9大对象的引用。
4、这9个对象分别是:request response session application config page out exception pageContext
*****************************************************************************************************************

22:14 2012/3/3
9大隐式对象——out对象:
1、用于向客户端发送文本数据
2、out对象是通过调用pagecontext对象的getout方法返回的,起作用和用法与servletResponse.getWriter方法返回的PrintWriter对象非常相似。
3、jsp页面的out隐式对象的类型为JspWriter,JspWrite相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,设置关闭它的缓存。
4、在out对象写入内容后,当满足一下任意条件时out对象才会去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓存区中的内容写入到Servlet引擎提供的缓存区中:
    设置page指令的buffer属性关闭了out对象的缓存功能;
    out对象的缓冲区已满;
    整个jsp也页面结束;
*****************************************************************************************************************

23:04 2012/3/3
9大隐式对象——pageContext对象:
pageContext对象是jsp技术中最重要的一个对象,它代表jsp页面的运行环境。
1、这个对象不仅封装了对其它8大隐式对象的引用。
2、它自身还是一个域对象,可以用来保存数据。
3、并且,这个对象还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其它资源、检索其它域对象中的属性等。
4、用于自定义标签。
*****************************************************************************************************************

0:15 2012/3/4
jsp标签
jsp标签页称之为Jsp Action(JSP动作)元素,它用于在jsp页面中提供逻辑业务功能,避免在jsp页面中直接写java代码,造成jsp页面难以维护。
jsp常用标签:
<jsp:include>
<jsp:forward>
<jsp:param>
*****************************************************************************************************************

12:44 2012/3/4
jsp映射
<servlet>
<servlet-name>随便给jsp起的servlet名称</servlet-name>
<jsp-file>要映射的jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>servlet名称</servlet-name>
<url-pattern>映射成的路径</url-pattern>
</servlet-mapping>
*****************************************************************************************************************

12:49 2012/3/4
jsp错误查找处理
1、jsp页面中的jsp语法格式有问题,导致其不能被翻译成servlet源文件,jsp引擎将提示这类错误发生在jsp页面中的位置(行和列)以及相关信息。
2、jsp页面中的语法格式没有问题,但被翻译成的servlet源文件中出现了java语法问题,导致jsp页面翻译成的servlet源文件不能通过编译,jsp引擎也将提示这类错误发生在jsp页面中的位置(行和列)以及相关信息。
3、jsp页面翻译成的servlet程序在运行时出现异常,这与普通java程序的运行时错误完全一样,java虚拟机将提示错误发生在servlet源文件中的位置(行和列)以及相关信息。
*****************************************************************************************************************

13:04 2012/3/4
盒子模型
1、网页时又块组成的,这样就形成一个盒子模型。
*****************************************************************************************************************

15:04 2012/3/4
页面帧排版
<html
    <head>
        <title>企业调度系统</title>
    </head>
    <frameset rows="100,*" frameborder="0" border="1" framespacing="0">
        <frame src="head.html" name="head" scrolling="no" noresize="noresize" />
        <frameset cols="180px,*" framesetborder="1" border="0" framespacing="0">
            <frame src="left.html" name="left" scrolling="no" noresize="noresize" />
            <frame src="main.html" name="main" scrolling="no" noresize="noresize" />
        </frameset>
    </frameset>
</html>

*****************************************************************************************************************

15:05 2012/3/4
jsp与javabean
一、什么事javabean
1、javabean是一个遵循特定写法的java类,它通常具备如下特点:
a、这个java类必须具有一个无参的构造函数
b、属性必须私有化
c、私有化的属性必须通过public类型的方法暴露给其他程序,并且方法的命名也必须遵循一定的命名规范。
二、javabean在J2EE开发中,通常用于封装数据,对于遵循以上写法的javabean组件,其他程序可以通过反射技术实例化javabean对象,并且通过反射那些遵循命名规范的方法,从而获知javab的属性,进而调用其属性保护数据。
三、javabean的属性
    a、javabean的属性可以是任意类型,并且一个javabean可以有多个属性,每个属性通常都需要具有相应的setter、getter方法,setter方法称为属性修改器,getter方法称为属性访问器
    b、属性修改器必须以小写的set前缀开始,后跟其属性名,且属性名的第一个字母要求大写,例如,那么属性的修改器名称为setName,password属性的修改器名称为setPassword。
    c、属性访问器通常以小写的get前缀开始,后跟其属性名,且属性名的第一个字母也要求大写,例如,name属性访问器名称为getName,password属性的访问器名称为getPassword。
    d、一个javabean的某个属性也可以只有set方法或get方法,这样的属性通常也称之为只写、只读属性。
四,jsp中使用javabean的标签
    a、<jsp:useBean>标签:用于在jsp页面中查找或实例化一个javabean组件。
        用于在指定的域范围内查找指定名称的javabean对象:
        1、如果存在则直接返回该javabean对象的引用
        2、如果不存在则实例化一个新的javabean对象并将它以指定的名称存储到指定的域范围中。
        常用语法:
        <jsp:useBean id="beanName" class="package.class" scope="page|request|session|application" />
    b、<jsp:setProperty>标签:用于在jsp页面中设置一个javabean组件的属性。
        语法格式:
        <jsp:setProperty name="beanName"
        {
            property="propertyName" value="{string | <%=expression%>}" |
            property="propertyName"[param="parameterName"] |
            property="*"
        }
        />
    c、<jsp:getProperty>标签:用于在jsp页面中获取一个javabean组件的属性。
        语法:
        <jsp:getProperty name="beanInstanceName" property="PropertyName" />
        注意:
        1、如果一个javabean实例对象的某个属性的值为null,那么使用<jsp:getProperty>标签输出该属性的结果将是        一个内容为“null”的字符串。
*****************************************************************************************************************

18:50 2012/3/4
jsp开发模式
一、jsp+javabean模式:
jsp+javabean模式适合开发业务逻辑不太复杂的web应用程序,这种模式下,javabean用于封装业务数据,jsp即负责处理用户请求,又显示数据。
二、servlet+jsp+javabea模式:
servlet+jsp+javabean(MVC)模式适合开发复杂的web应用程序,在这种模式下,servlet负责处理用户请求,jsp负责数据显示,javabean负责封装数据。
*****************************************************************************************************************

23:00 2012/3/4
EL表达式和JSTL标签快速入门
1、EL表达式用于获取数据,在jsp页面中可使用${标示符}的形式,通知jsp引擎调用pageContext.findAttribute()方法,以便是符为关键字从各个域对象中获取对象。如果域对象中不存在标识符所对应的对象,则返回结果为“”(注意,不是null)。
2、EL表达式中也可以使用${customerBean.address}的形式来访问javabean对象的属性。
3、结合jsp标签,EL表达式也可以轻松获取各种集合中的元素。
4、EL表达式也可使用类如${1==1}的形式进行简单的逻辑判断。
5、在用EL表达式去数据时,通常用‘.’号,如果'.'号取不出来,就用‘[]’号取值。

*****************************************************************************************************************

20:01 2012/3/5
JSTL标签库
1、JSTL是SUN公司开发的一套标签库,使用JSTL可以在页面中实现一些简单的逻辑,从而替换页面中的脚本代码。
2、在页面中使用JSTL标签需完成一下2个步骤:
    a、导入jstl.jar和standerd.jar这两个JSTL的jar文件。
    b、在JSP页面中使用<$@tablib url="" prifix=""$>元素导入标签库。
3、JSTL标签库中常用标签:
    <c:foreach var="" items="">
    <c:if test="">
*****************************************************************************************************************

21:52 2012/3/5
开发步骤4步曲:
1、搭建开发环境
1.1、导入开发包
    dom4j开发包
    jstl开发包
    beanUtils开发包
    log4j开发包
    
1.2、创建组织程序的包
    cn.flame.domain
    cn.flame.dao
    cn.flame.dao.impl
    cn.flame.service
    cn.flame.service.impl
    cn.flame.web.controller(处理请求的servlet)
    cn.flame.web.ui(给用户提供用户界面)
    cn.flame.utils
    cn.flame.junit.test
    WEB-INF/jsp    保存网站所有jsp
1.3、创建数据库

*****************************************************************************************************************

0:51 2012/3/7
java中时间格式转换
1、string类型转换成Date类型
    SimpleDateFormat sfDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    sfDateFormat.parse(dateString);
2、Date类型转换成string类型
    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
    sf.format(date);
*****************************************************************************************************************

16:09 2012/3/14
去掉超链接默认行为
<a href="javascript:void(0)" οnclick="deleteitem()" >删除</a>
*****************************************************************************************************************
16:53 2012/3/14
自定义标签
1、自定义标签主要用于移除jsp页面中的java代码。
2、要使用自定义标签移除jsp页面中的java代码,只需要完成以下两个步骤:
    a、编写一个实现Tag接口的java类,把页面java代码移到这个java类中(标签处理器类)。
    b、编写一个标签描述符(tld)文件,在tld文件中对标签处理器类描述成一个标签。

*****************************************************************************************************************

22:33 2012/3/14
自定义标签----输出IP
1、创建一个类继承Tag接口的实现类TagSupper,并重写该类的doStartTag方法。
public class ViewIPTag extends TagSupport {

    @Override
    public int doStartTag() throws JspException {
        HttpServletRequest request =(HttpServletRequest) this.pageContext.getRequest();
        JspWriter out = this.pageContext.getOut();
        String ip = request.getRemoteAddr();
        try {
            out.write(ip);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return super.doStartTag();
    }
    
}
2、在WEB-INF目录下新建一个flame.tld文件,并在tomcat目录下找到类似tld文件,抄袭,路径为一下路径:
F:\eclipse-jee-indigo-SR1-win32\eclipse\pluginsNew\apache-tomcat-6.0.30\webapps\examples\WEB-INF\jsp2


<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
    <description>A tag library exercising SimpleTag handlers.</description>
    <tlib-version>1.0</tlib-version>
    <short-name>flame</short-name>
    <uri>http://www.flame.com</uri>
    <tag>
        <name>viewIP</name>
    <tag-class>cn.flame.web.tag.ViewIPTag</tag-class>
    <body-content>empty</body-content>
    </tag>
</taglib>
3、在jsp页面导入标签并使用标签
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://www.flame.com" prefix="flame" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    您的IP为:<flame:viewIP/>
</body>
</html>
*****************************************************************************************************************

22:46 2012/3/14
jsp自定义标签原理;
1、jsp代码遇到自定义标签,先实例化标签对应的标签处理器
2、调用pagecontext方法,把页面的pagecontext对象传递给标签处理器
3、看标签是否有父标签,有则把父标签作为一个对象,调用setparent方法传递给标签处理器,没有则传递null
4、完成以上初始化后,服务器开始执行标签,这是遇到标签的开始标签,调用dostarttag方法
5、如果有标签体时,服务器会执行标签体
6、服务器遇到jsp页面借宿标签,则调用标签处理器类的都doendtag方法
7、如果程序没有规定释放资源,服务器会把标签资源存于缓存中以便下次访问。    
*****************************************************************************************************************

1:16 2012/3/15
Tag接口的执行流程
jsp引擎将遇到自定义标签时,首先创建标签处理器类的实例对象,然后按照jsp规范定义的通信规则依次调用它的方法。
1、public void setPageContext(PageContext pc),jsp引擎实例化标签处理器后,将调用setPageContext方法将jsp页面的pageContext对象传递给标签处理器,标签处理器以后可以通过这个pageContext对象与jsp页面进行通信。
2、public void setParent(Tag t),setPageContext方法执行完后,WEB容器接着调用setParent方法将当前标签的父标签传递给当前标签处理器,如果当前标签没有父标签,则传递给setParent方法的参数值为null
3、public iint doStartTag(),调用了setPageContext方法和setParent方法之后,web容器执行到自定义标签的开始标记时,就会调用标签处理器的doStartTag方法。
4、public int doEndTag(),WEB容器执行完自定义标签的标签体后,就会接着去执行自定义标签的借宿标记,此时,web容器就会去调用标签处理器的doEndTag方法。
5、public void release(),通常web容器执行完自定义标签后,标签处理器会驻留在内存中,为其它请求服务器,直至停止web应用时,web容器才回调用release方法释放资源。
*****************************************************************************************************************

1:25 2012/3/15
自定义标签扩展功能
1、控制jsp页面某一部分内容是否执行——用于权限
2、控制整个jsp页面是否执行——用于权限
3、控制jsp页面内容重复执行——用于循环
4、修改jsp页面内容输出——用于修改内容
*****************************************************************************************************************

10:55 2012/3/15
四种标签体类型
empty——不执行标签体
jsp——执行jsp标签体
scriptless——执行脚本片段
tagdepentend——表示,该标签体是给标签用的。不是个整个页面用的
*****************************************************************************************************************

11:13 2012/3/15
带属性标签
1、自定义标签可以定义一个或多个属性,这样,在jsp页面中应用自定义标签时就可以设置这些属性的值,通过这些标签属性为标签处理器传递参数信息,从而提高标签的灵活性和复用性。
2、想要让一个自定义标签具有属性,通常需要完成两个任务:
    a、在标签处理器中编写每个属性对应的setter方法
    b、在TLD文件中描述标签的属性
3、为自定义标签定义属性时,每个属性都必须按照javabean的属性命名方式,在标签处理器中定义属性名对应的setter方法,用来接收jsp页面调用自定义标签时传递进来的属性值。例如属性url,在标签处理器类中就要定义相应的setUrl(String url)方法。
4、在标签处理器中定义相应的set方法后,jsp引擎在解析执行开始标签前,也就是调用doStartTag方法前,会调用set属性方法为标签设置属性。
例子:
jsp代码
------------------------------------------
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://www.flame.com" prefix="flame" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <flame:demo1 count="9" date="<%=new Date() %>">
        aaaaa
    </flame:demo1>
</body>
</html>
------------------------------------------
tld代码
------------------------------------------
<tag>
        <name>demo1</name>
        <tag-class>cn.flame.web.simpttag.demo1</tag-class>
        <body-content>scriptless</body-content>
        <attribute>
            <name>count</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>date</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
------------------------------------------
java代码
------------------------------------------
package cn.flame.web.simpttag;

import java.io.IOException;
import java.util.Date;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class demo1 extends SimpleTagSupport {
    private int count;
    private Date date;
    
    public void setCount(int count) {
        this.count = count;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    @Override
    public void doTag() throws JspException, IOException {
        JspFragment jf = this.getJspBody();
        this.getJspContext().getOut().write(date.toLocaleString()+"<br/>");
        for(int i=0;i<count;i++){
            jf.invoke(null);
        }
        
    }
    
}

*****************************************************************************************************************

14:05 2012/3/15
自定义标签案例——防盗链
java代码
---------------------------------
/**
 * @author flame
 * 防盗链
 */
public class RefererTag extends SimpleTagSupport {
    private String site;
    private String page;
    
    public void setSite(String site) {
        this.site = site;
    }

    public void setPage(String page) {
        this.page = page;
    }

    @Override
    public void doTag() throws JspException, IOException {
        PageContext pageContext = (PageContext) this.getJspContext();
        HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
        HttpServletResponse response = (HttpServletResponse) pageContext.getResponse();
        String referer = request.getHeader("referer");
        if(referer == null || referer.startsWith(site)){
            if(page.startsWith(request.getContextPath())){
                response.sendRedirect(page);
            }else if(page.startsWith("/")){
                response.sendRedirect(request.getContextPath()+page);
            }else {
                response.sendRedirect(request.getContextPath()+"/"+page);
            }
            throw new SkipPageException();
        }
    }
    
}
-----------------------------------------
jsp代码
-----------------------------------------
<%@taglib uri="http://www.flame.com/example" prefix="e" %>
<e:referer site="http://localhost" page="index.jsp"/>
-----------------------------------------
tld代码
----------------------------------------
<uri>http://www.flame.com/example</uri>
    <tag>
        <name>referer</name>
        <tag-class>cn.flame.web.example.RefererTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>site</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>page</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
*****************************************************************************************************************

22:00 2012/3/15
foreach自定义标签
源码:
/**
 *
 */
package cn.flame.web.example;

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;


/**
 * foreach标签
 * @author flame
 *
 */
public class ForeachTag extends SimpleTagSupport {
    private Object items;
    private String var;
    private Collection collection;
    
    public void setCollection(Collection collection) {
        this.collection = collection;
    }
    public void setItems(Object items) {
        this.items = items;
        if(items instanceof Collection){
            this.collection = (Collection) items;
        }
        if(items instanceof Map){
            Map map = (Map) items;
            collection = map.entrySet();
        }
        if(items instanceof Object[]){
            Object obj[] = (Object[]) items;
            collection = Arrays.asList(obj);
        }
        if(items.getClass().isArray()){
            this.collection = new ArrayList();
            int leng = Array.getLength(items);
            for (int i = 0; i < leng; i++) {
                Object value = Array.get(items, i);
                this.collection.add(value);
            }
        }
    }
    public void setVar(String var) {
        this.var = var;
    }
    @Override
    public void doTag() throws JspException, IOException {
        Iterator it = this.collection.iterator();
        while (it.hasNext()) {
            Object value = it.next();
            this.getJspContext().setAttribute(var, value);
            this.getJspBody().invoke(null);
        }
    }
    
}

*****************************************************************************************************************

22:01 2012/3/15
html转义标签
1、把html标签符号转换为实体符号再输出给浏览器
字符转换方法可以在tomcat目录中找到,路径为apache-tomcat-6.0.30\webapps\examples\WEB-INF\classes\util
方法为:
--------------------------------------------------
public static String filter(String message) {


        if (message == null)

            return (null);


        char content[] = new char[message.length()];

        message.getChars(0, message.length(), content, 0);

        StringBuffer result = new StringBuffer(content.length + 50);

        for (int i = 0; i < content.length; i++) {

            switch (content[i]) {

            case '<':

                result.append("&lt;");

                break;

            case '>':

                result.append("&gt;");

                break;

            case '&':

                result.append("&amp;");

                break;

            case '"':

                result.append("&quot;");

                break;

            default:

                result.append(content[i]);

            }

        }

        return (result.toString());

}
*****************************************************************************************************************

23:00 2012/3/15
打包自己标签库
1、创建一个java工程
2、把已经编译成功通过的标签java文件拷贝到新创建的目录下
3、在java工程根目录下新建文件名为META-INF的文件
4、把标签的tld文件拷贝到该文件里面
5、右键工程名,选择导出
6、在弹出的窗口中选择java类中的"JAR file"选项
7、在弹出的选择源窗口中去掉.classpath和.project选项
8、指定输出路径及jar文件名
9、需要用到时直接导入包即可
*****************************************************************************************************************

23:11 2012/3/15
jstl标签库
1、核心标签
2、国际化标签
3、数据库标签(不会用到)
4、XML标签(不会用到)
5、JSTL函数(EL函数)
*****************************************************************************************************************

23:19 2012/3/15
jstl标签详解
-----------------------------------------------------------------------------------------------------------------
1、<c:out>标签
用于输出一段文本内容到pageContext对象当前保存的"out"对象中。
a、Value(true,Object):指定要输出的内容
b、escapeXml(true.Boolean):指定是否将>、/、《、&、‘、“等特殊字符进行HTML编码转换后再进行输出,默认值为true
c、default(true,Object):指定如果value属性的值为null时所输出的默认值

-----------------------------------------------------------------------------------------------------------------
2、<c:set>标签
用于 把某一个对象存在指定的域范围内,或者设置web域中的java.util.Map类型的属性对象或javabean类型的属性对象的属性。
a、value(true,Object):用于指定属性值
b、var(false,String):用于指定要设置的web域对象的名称
c、scope(false,String):用于指定属性所在的web域
d、target(true,Object):用于指定要设置属性的对象,这个对象必须是javabean对象或java.util.Map对象
e、property(true,String):用于指定当前要为对象设置的属性名称

-----------------------------------------------------------------------------------------------------------------
3、<c:catch>标签
用于捕获嵌套在标签体中的内容抛出的异常,其语法格式如下:
<c:catch [var="varName"]>nested actions</c:catch>
var属性用于标识<c:catch>标签捕获的异常对象,它将保存在page这个web域中
-----------------------------------------------------------------------------------------------------------------
4、<c:url>标签
用于在jsp页面中构造一个url地址,其主要目的是实现url重写。url重写就是将会话标识以参数形式附加在url地址后面

*****************************************************************************************************************


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值