JAVA开发全集

2020年05月19日 阅读数:1828
这篇文章主要向大家介绍JAVA开发全集,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

soap消息的分析和消息的建立和传递和处理


@WebService
public interface IMyService {
 @WebResult(name="addResult")
 public int add(@WebParam(name="a")int a,@WebParam(name="b")int b);
 
 @WebResult(name="user")
 public User addUser(@WebParam(name="user")User user);
 
 @WebResult(name="user")
 public User login(@WebParam(name="username")String username,
       @WebParam(name="password")String password)throws UserException;
 
 @WebResult(name="user")
 public List<User> list(@WebParam(header=true,name="authInfo")String authInfo);
}
javascript

@XmlRootElement
public class User {
 private int id;
 private String username;
 private String nickname;
 private String password;
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getUsername() {
  return username;
 }
 public void setUsername(String username) {
  this.username = username;
 }
 public String getNickname() {
  return nickname;
 }
 public void setNickname(String nickname) {
  this.nickname = nickname;
 }
 public String getPassword() {
  return password;
 }
 public void setPassword(String password) {
  this.password = password;
 }
 public User(int id, String username, String nickname, String password) {
  super();
  this.id = id;
  this.username = username;
  this.nickname = nickname;
  this.password = password;
 }
 public User() {
  super();
 }
 
 
 
}
css

public class MyServer {html

 public static void main(String[] args) {
  Endpoint.publish("http://localhost:8989/ms", new MyServiceImpl());
 }前端

}
java



--

 

@WebService(endpointInterface="org.soap.service.IMyService")
@HandlerChain(file="handler-chain.xml")
public class MyServiceImpl implements IMyService {
 private static List<User> users = new ArrayList<User>();
 
 public MyServiceImpl() {
  users.add(new User(1,"admin","","111111"));
 }node

 @Override
 public int add(int a, int b) {
  System.out.println("a+b="+(a+b));
  return a+b;
 }python

 @Override
 public User addUser(User user) {
  users.add(user);
  return user;
 }mysql

 @Override
 public User login(String username, String password) throws UserException{
  for(User user:users) {
   if(username.equals(user.getUsername())&&password.equals(user.getPassword()))
    return user;
  }
  throw new UserException("");
 }jquery

 @Override
 public List<User> list(String authInfo) {
  System.out.println(authInfo);
  return users;
 }linux

}

public class TestSoap {
 
 private static String ns = "http://service.soap.org/";
 private static String wsdlUrl = "http://localhost:8989/ms?wsdl";
        
        public static void main(String[] args){
            TestSoap.test03();
        }

 @Test
 public static void test01() {
  try {
   //1�������建立消息工厂���
   MessageFactory factory = MessageFactory.newInstance();
   //2����根据消息工厂建立SoapMessage
   SOAPMessage message = factory.createMessage();
   //3�����建立SOAPPart
   SOAPPart part = message.getSOAPPart();
   //4��获取SOAPENvelope
   SOAPEnvelope envelope = part.getEnvelope();
   //5��能够经过SoapEnvelope有效的获取相应的Body和Header等信息
   SOAPBody body = envelope.getBody();
   //6���根据Qname建立相应的节点(QName就是一个带有命名空间的节点)���������ռ��)
   QName qname = new QName("http://java.zttc.edu.cn/webservice", 
     "add","ns");//<ns:add xmlns="http://java.zttc.edu.cn/webservice"/>
   //�若是使用如下方式进行设置,会见<>转换为&lt;和&gt
   //body.addBodyElement(qname).setValue("<a>1</a><b>2</b>");
   SOAPBodyElement ele = body.addBodyElement(qname);
   ele.addChildElement("a").setValue("22");
   ele.addChildElement("b").setValue("33");
   //打印消息信息
   message.writeTo(System.out);
  } catch (SOAPException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
 
 @Test//基于soap的消息传递
 public static void test02() {
  try {
   //1���建立服务(Service)
   URL url = new URL(wsdlUrl);
   QName sname = new QName(ns,"MyServiceImplService");
   Service service = Service.create(url,sname);
   
   //2����建立Dispatch
   Dispatch<SOAPMessage> dispatch = service.createDispatch(new QName(ns,"MyServiceImplPort"),
      SOAPMessage.class, Service.Mode.MESSAGE);
   
   //3����建立SOAPMessage
   SOAPMessage msg = MessageFactory.newInstance().createMessage();
   SOAPEnvelope envelope = msg.getSOAPPart().getEnvelope();
   SOAPBody body = envelope.getBody();
   
   //4���建立QName来指定消息中传递数据����
   QName ename = new QName(ns,"add","nn");//<nn:add xmlns="xx"/>
   SOAPBodyElement ele = body.addBodyElement(ename);
   ele.addChildElement("a").setValue("22");
   ele.addChildElement("b").setValue("33");
   msg.writeTo(System.out);
   System.out.println("\n invoking.....");
   
   
   //5�经过Dispatch传递消息,会返回响应消息
   SOAPMessage response = dispatch.invoke(msg);
   response.writeTo(System.out);
   System.out.println("\n----------------------------------------");
   
   //��将响应的消息转换为dom对象��
   Document doc = response.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
   String str = doc.getElementsByTagName("addResult").item(0).getTextContent();
   System.out.println(str);
  } catch (SOAPException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
 
 @Test
 public static void test03() {
  try {
   //1�����建立服务(Service)
   URL url = new URL(wsdlUrl);
   QName sname = new QName(ns,"MyServiceImplService");
   Service service = Service.create(url,sname);
   
   //2���建立Dispatch(经过源数据的方式传递)
   Dispatch<Source> dispatch = service.createDispatch(new QName(ns,"MyServiceImplPort"),
      Source.class, Service.Mode.PAYLOAD);
   //3���根据用户对象建立相应的xml
   User user = new User(3,"zs","张三","11111");
                        //编排user对象
   JAXBContext ctx = JAXBContext.newInstance(User.class);
   Marshaller mar = ctx.createMarshaller();
                        //不会再建立xml的头信息
   mar.setProperty(Marshaller.JAXB_FRAGMENT, true);
   StringWriter writer= new StringWriter();
   mar.marshal(user, writer);
   System.out.println("writer====="+writer);
   //四、封装相应的part addUser
   String payload = "<xs:addUser xmlns:xs=\""+ns+"\">"+writer.toString()+"</xs:addUser>";
   System.out.println("payload====="+payload);
   StreamSource rs = new StreamSource(new StringReader(payload));
   
   //5�经过dispatch传递payload
   Source response = (Source)dispatch.invoke(rs);
   
   //6�将Source转化为DOM进行操做,使用Transform对象转换
   Transformer tran = TransformerFactory.newInstance().newTransformer();
   DOMResult result = new DOMResult();
   tran.transform(response, result);
   
   //7���处理相应信息(经过xpath处理)
   XPath xpath = XPathFactory.newInstance().newXPath();
   NodeList nl = (NodeList)xpath.evaluate("//user", result.getNode(),XPathConstants.NODESET);
   User ru = (User)ctx.createUnmarshaller().unmarshal(nl.item(0));
   System.out.println(ru.getNickname());
  } catch (IOException e) {
   e.printStackTrace();
  } catch (JAXBException e) {
   e.printStackTrace();
  } catch (TransformerConfigurationException e) {
   e.printStackTrace();
  } catch (TransformerFactoryConfigurationError e) {
   e.printStackTrace();
  } catch (TransformerException e) {
   e.printStackTrace();
  } catch (XPathExpressionException e) {
   e.printStackTrace();
  }
 }

 

schema的笔记


schema文件:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns=" http://www.w3.org/2001/XMLSchema
  targetNamespace=" http://www.example.org/01"
  xmlns:tns=" http://www.example.org/01
  elementFormDefault="qualified">
 <element name="user">
  <complexType>
   <sequence>
    <element name="id" type="int"/>
    <element name="username" type="string"/>
    <element name="born" type="date"/>
   </sequence>
  </complexType>
 </element>
</schema>

xml文件1:
<?xml version="1.0" encoding="UTF-8"?>
<user xmlns=" http://www.example.org/01"
   xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation=" http://www.example.org/01">
 <id>1</id>
 <username>zhangsan</username>
 <born>1989-12-22</born>
</user>

xml文件2:
<?xml version="1.0" encoding="UTF-8"?>
<user xmlns=" http://www.example.org/01"
   xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="01.xsd">
  <id>11</id>
  <username>lisi</username>
  <born>1988-11-11</born>
</user>

schema文件2:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/02"
 xmlns:tns="http://www.example.org/02" elementFormDefault="qualified">

 <element name="books">
  <complexType>
  <!-- maxOccurs表示最大出现次数 -->
   <sequence maxOccurs="unbounded">
    <element name="book">
     <complexType>
      <sequence minOccurs="1" maxOccurs="unbounded">
       <element name="title" type="string" />
       <element name="content" type="string" />
       <choice>
        <element name="author" type="string" />
        <element name="authors">
         <complexType>
          <all><!-- 每一个元素只能出现一次 -->
           <element name="author" type="string"/>
          </all>
         </complexType>
        </element>
       </choice>
      </sequence>
      <attribute name="id" type="int" use="required"/>
     </complexType>
    </element>
   </sequence>
  </complexType>
 </element>

</schema>


xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<book:books xmlns:book=" http://www.example.org/02"
   xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="02.xsd">
 <book:book id="1">
  <book:title>Java in action</book:title>
  <book:content>Java is good</book:content>
  <book:author>Bruce</book:author>
 </book:book>
 <book:book id="2">
  <book:title>SOA in action</book:title>
  <book:content>soa is difficult</book:content>
  <book:authors>
   <book:author>Jike</book:author>
  </book:authors>
 </book:book>
</book:books>

schema文件3:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns=" http://www.w3.org/2001/XMLSchema
  targetNamespace=" http://www.example.org/04
  xmlns:tns=" http://www.example.org/04
  elementFormDefault="qualified">
  
 <element name="person" type="tns:personType"/>
 
 <complexType name="personType">
  <sequence>
   <element name="name" type="string"/>
   <element name="age" type="tns:ageType"/>
   <element name="email" type="tns:emailType"/>
  </sequence>
  <attribute name="sex" type="tns:sexType"/>
 </complexType>
 
 <simpleType name="emailType">
  <restriction base="string">
   <pattern value="(\w+\.*)*\w+@\w+\.[A-Za-z]{2,6}"/>
   <minLength value="6"/>
   <maxLength value="255"/>
  </restriction>
 </simpleType>
 
 <simpleType name="ageType">
  <restriction base="int">
   <minInclusive value="1"/>
   <maxExclusive value="150"/>
  </restriction>
 </simpleType>
 
 <simpleType name="sexType">
  <restriction base="string">
   <enumeration value="男"/>
   <enumeration value="女"/>
  </restriction>
 </simpleType>
</schema>

xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<person xmlns=" http://www.example.org/04"
   xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation=" http://www.example.org/04" sex="男">
  <name>搜索</name>
  <age>149</age>
  <email>sadf@sdf.css</email>
</person>

schema文件4:

dtd讲解

classroom.dtd文件:<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT classroom (claName,grade,students)>
<!ATTLIST classroom id ID #REQUIRED>
<!ELEMENT claName (#PCDATA)>
<!ELEMENT grade (#PCDATA)>
<!ELEMENT students (student+)>
<!ELEMENT student (id,stuName,age)>
<!ELEMENT id (#PCDATA)>
<!ELEMENT stuName (#PCDATA)>
<!ELEMENT age (#PCDATA)>

classroom.xml文件:<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE classroom SYSTEM "classroom.dtd">
<classroom id="c1">
 <claName>10计算机应用技术</claName>
 <grade>2010</grade>
 <students>
  <student>
   <id>1</id>
   <stuName>zhangsan</stuName>
   <age>12</age>
  </student>
  <student>
   <id>2</id>
   <stuName>lisi</stuName>
   <age>122</age>
  </student>
 </students>
</classroom>
 

使用soap协议用java语言创建服务发送xml文件,接收xml文件



private static String ns = " http://service.soap.org/";
 private static String wsdlUrl = " http://localhost:8989/ms?wsdl";public static void test02() {
  try {
   //1���建立服务(Service)
   URL url = new URL(wsdlUrl);
   QName sname = new QName(ns,"MyServiceImplService");
   Service service = Service.create(url,sname);
   
   //2����建立Dispatch
   Dispatch<SOAPMessage> dispatch = service.createDispatch(new QName(ns,"MyServiceImplPort"),
      SOAPMessage.class, Service.Mode.MESSAGE);
   
   //3����建立SOAPMessage
   SOAPMessage msg = MessageFactory.newInstance().createMessage();
   SOAPEnvelope envelope = msg.getSOAPPart().getEnvelope();
   SOAPBody body = envelope.getBody();
   
   //4���建立QName来指定消息中传递数据����
   QName ename = new QName(ns,"add","nn");//<nn:add xmlns="xx"/>
   SOAPBodyElement ele = body.addBodyElement(ename);
   ele.addChildElement("a").setValue("22");
   ele.addChildElement("b").setValue("33");
   msg.writeTo(System.out);
   System.out.println("\n invoking.....");
   
   
   //5�经过Dispatch传递消息,会返回响应消息
   SOAPMessage response = dispatch.invoke(msg);
   response.writeTo(System.out);
   System.out.println("\n----------------------------------------");
   
   //��将响应的消息转换为dom对象��
   Document doc = response.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
   String str = doc.getElementsByTagName("addResult").item(0).getTextContent();
   System.out.println(str);
  } catch (SOAPException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

XPath解析,写入,修改xml文件

public static void test06() {
  InputStream is = null;
  try {
   is = TestStax.class.getClassLoader().getResourceAsStream("books.xml");
   //建立文档处理对象
   DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
   //经过DocumentBuilder建立doc的文档对象
   Document doc = db.parse(is);
   //建立XPath
   XPath xpath = XPathFactory.newInstance().newXPath();
   //第一个参数就是xpath,第二参数就是文档
   NodeList list = (NodeList)xpath.evaluate("//book[@category='WEB']", doc,XPathConstants.NODESET);
   for(int i=0;i<list.getLength();i++) {
    //遍历输出相应的结果
    Element e = (Element)list.item(i);
    System.out.println(e.getElementsByTagName("title").item(0).getTextContent());
   }
  } catch (ParserConfigurationException e) {
   e.printStackTrace();
  } catch (SAXException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } catch (XPathExpressionException e) {
   e.printStackTrace();
  } finally {
   try {
    if(is!=null) is.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }
 
 @Test
 public static void test07() {
  try {
   XMLStreamWriter xsw = XMLOutputFactory.newInstance().createXMLStreamWriter(System.out);
   xsw.writeStartDocument("UTF-8","1.0");
   xsw.writeEndDocument();
   String ns = " http://11:dd";
   xsw.writeStartElement("nsadfsadf","person",ns);
   xsw.writeStartElement(ns,"id");
   xsw.writeCharacters("1");
   xsw.writeEndElement();
   xsw.writeEndElement();
   xsw.flush();
   xsw.close();
  } catch (XMLStreamException e) {
   e.printStackTrace();
  } catch (FactoryConfigurationError e) {
   e.printStackTrace();
  }
 }
 
 @Test
 public static void test08() {
  InputStream is = null;
  try {
   is = TestStax.class.getClassLoader().getResourceAsStream("books.xml");
   //建立文档处理对象
   DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
   //经过DocumentBuilder建立doc的文档对象
   Document doc = db.parse(is);
   //建立XPath
   XPath xpath = XPathFactory.newInstance().newXPath();
   Transformer tran = TransformerFactory.newInstance().newTransformer();
   tran.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
   tran.setOutputProperty(OutputKeys.INDENT, "yes");
   //第一个参数就是xpath,第二参数就是文档
   NodeList list = (NodeList)xpath.evaluate("//book[title='Learning XML']", doc,XPathConstants.NODESET);
   //获取price节点
   Element be = (Element)list.item(0);
   Element e = (Element)(be.getElementsByTagName("price").item(0));
   e.setTextContent("333.9");
   Result result = new StreamResult(System.out);
   //经过tranformer修改节点
   tran.transform(new DOMSource(doc), result);
  } catch (ParserConfigurationException e) {
   e.printStackTrace();
  } catch (SAXException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } catch (XPathExpressionException e) {
   e.printStackTrace();
  } catch (TransformerConfigurationException e) {
   e.printStackTrace();
  } catch (TransformerFactoryConfigurationError e) {
   e.printStackTrace();
  } catch (TransformerException e) {
   e.printStackTrace();
  } finally {
   try {
    if(is!=null) is.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

XMLEventReader的基于Filter的过滤方式解析xml文件

public static void test05() {
  XMLInputFactory factory = XMLInputFactory.newInstance();
  InputStream is = null;
  try {
   is = TestStax.class.getClassLoader().getResourceAsStream("books.xml");
   //基于Filter的过滤方式,能够有效的过滤掉不用进行操做的节点,效率会高一些
   XMLEventReader reader = factory.createFilteredReader(factory.createXMLEventReader(is),
     new EventFilter() {
      @Override
      public boolean accept(XMLEvent event) {
       //返回true表示会显示,返回false表示不显示
       if(event.isStartElement()) {
        String name = event.asStartElement().getName().toString();
        if(name.equals("title")||name.equals("price"))
         return true;
       }
       return false;
      }
     });
   int num = 0;
   while(reader.hasNext()) {
    //经过XMLEvent来获取是不是某种节点类型
    XMLEvent event = reader.nextEvent();
    if(event.isStartElement()) {
     //经过event.asxxx转换节点
     String name = event.asStartElement().getName().toString();
     if(name.equals("title")) {
      System.out.print(reader.getElementText()+":");
     }
     if(name.equals("price")) {
      System.out.print(reader.getElementText()+"\n");
     }
    }
    num++;
   }
   System.out.println(num);
  } catch (XMLStreamException e) {
   e.printStackTrace();
  } finally {
   try {
    if(is!=null) is.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

XMLEventReader迭代解析xml文件

public static void test04() {
  XMLInputFactory factory = XMLInputFactory.newInstance();
  InputStream is = null;
  try {
   is = TestStax.class.getClassLoader().getResourceAsStream("books.xml");
   //基于迭代模型的操做方式
   XMLEventReader reader = factory.createXMLEventReader(is);
   int num = 0;
   while(reader.hasNext()) {
    //经过XMLEvent来获取是不是某种节点类型
    XMLEvent event = reader.nextEvent();
    if(event.isStartElement()) {
     //经过event.asxxx转换节点
     String name = event.asStartElement().getName().toString();
     if(name.equals("title")) {
      System.out.print(reader.getElementText()+":");
     }
     if(name.equals("price")) {
      System.out.print(reader.getElementText()+"\n");
     }
    }
    num++;
   }
   System.out.println(num);
  } catch (XMLStreamException e) {
   e.printStackTrace();
  } finally {
   try {
    if(is!=null) is.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }
 

XMLStreamReader光标解析xml文件

public static void test01() {
  XMLInputFactory factory = XMLInputFactory.newInstance();
  InputStream is = null;
  try {
   is = TestStax.class.getClassLoader().getResourceAsStream("books.xml");
   XMLStreamReader reader = factory.createXMLStreamReader(is);
   while(reader.hasNext()) {
                        //    System.out.println("------------------------------------------------");
    int type = reader.next();
                                 System.out.println("type---"+type);
    //判断节点类型是不是开始或者结束或者文本节点,以后根据状况及进行处理
    if(type==XMLStreamConstants.START_ELEMENT) {//==1,指示事件是一个开始元素
     System.out.println(reader.getName());
                                        String name = reader.getName().toString();
                                        if("book".equals(name)){
                                             System.out.println(reader.getAttributeName(0)+":"+reader.getAttributeValue(0));
                                        }else if("title".equals(name)){
                                             System.out.println(reader.getAttributeName(0)+":"+reader.getAttributeValue(0));
                                        }
                                        
                                        //  System.out.println("==1,指示事件是一个开始元素");
    } else if(type==XMLStreamConstants.CHARACTERS) {//==4指示事件是一些字符
     System.out.println(reader.getText().trim());
                                    // System.out.println("==4指示事件是一些字符");
    } else if(type==XMLStreamConstants.END_ELEMENT) {//==2,指示事件是一个结束元素
     System.out.println("/"+reader.getName());
                                     //  System.out.println("==2,指示事件是一个结束元素");
    }
                                //else if(type==XMLStreamConstants.ATTRIBUTE){
//                                   int count = reader.getAttributeCount();
//                                   System.out.println("count========"+count);
//                                 if(count>0){
//                                     int i=0;
//                                     int[] arr = new int[count];
//                                     while(i<count){
//                                         arr[i]=i;
//                                         i++;
//                                     }
//                                     for(int a : arr){
//                                         System.out.println(reader.getAttributeValue(a));
//                                     }
//                                 }
//                                }
   }
  } catch (XMLStreamException e) {
   e.printStackTrace();
  } finally {
   try {
    if(is!=null) is.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

使用jaxb完成对象和xml的转换

学生类

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Student {
 private int id;
 private String name;
 private int age;
 private Classroom classroom;
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 public Classroom getClassroom() {
  return classroom;
 }
 public void setClassroom(Classroom classroom) {
  this.classroom = classroom;
 }
 public Student(int id, String name, int age, Classroom classroom) {
  super();
  this.id = id;
  this.name = name;
  this.age = age;
  this.classroom = classroom;
 }
 public Student() {
  super();
 }
 
 
}

教室类
public class Classroom {
 private int id;
 private String name;
 private int grade;
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getGrade() {
  return grade;
 }
 public void setGrade(int grade) {
  this.grade = grade;
 }
 public Classroom(int id, String name, int grade) {
  super();
  this.id = id;
  this.name = name;
  this.grade = grade;
 }
 public Classroom() {
  super();
  // TODO Auto-generated constructor stub
 }
 
 
}

测试类:

public class TestJaxb {

    public static void main(String[] args){
        TestJaxb.test02();
    }
 @Test
 public static void test01() {//测试对象转换xml字符串
  try {
   JAXBContext ctx = JAXBContext.newInstance(Student.class);
   Marshaller marshaller = ctx.createMarshaller();
   Student stu = new Student(1,"张三",21,new Classroom(1,"10计算机应用技术",2010));
   marshaller.marshal(stu, System.out);
  } catch (JAXBException e) {
   e.printStackTrace();
  }
 }
 
 @Test
 public static void test02() {//测试xml字符串转换对象
  try {
   String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><student><age>21</age><classroom><grade>2010</grade><id>1</id><name>10计算机应用技术</name></classroom><id>1</id><name>张三</name></student>";
   JAXBContext ctx = JAXBContext.newInstance(Student.class);
   Unmarshaller um = ctx.createUnmarshaller();
   Student stu = (Student)um.unmarshal(new StringReader(xml));
   System.out.println(stu.getName()+","+stu.getClassroom().getName());
  } catch (JAXBException e) {
   e.printStackTrace();
  }
  
 }
}


webservice的笔记



1简历webservice服务的步骤:



(1)服务器的创建:1:建立接口SEI(Service Endpoint Interface)



@WebService()



public interface IMyService
{



  



   @WebResult(name="addResult")



   public int add(@WebParam(name="a")int
a,@WebParam(name="b")int b);



  



   @WebResult(name="minusResult")



   public int minus(@WebParam(name="a")int
a,@WebParam(name="b")int b);



  



   @WebResult(name="loginUser")



   public User login(@WebParam(name="username")String
username,@WebParam(name="password")String password);



 



}



2:建立实现类SIB(Service inplemention Bean)



@WebService(endpointInterface="org.zttc.service.IMyService")



public class MyServiceImpl
implements IMyService {



 



   @Override



   public int add(int a, int b) {



       System.out.println(a+"+"+b+"="+(a+b));



       return a+b;



   }



 



   @Override



   public int minus(int a, int b) {



       System.out.println(a+"-"+b+"="+(a-b));



       return a-b;



   }



 



   @Override



   public User login(String username, String password) {



       System.out.println(username+" is logining");



       User user = new User();



       user.setId(1);



       user.setUsername(username);



       user.setPassword(password);



       return user;



   }



 



}



3:开启服务



public class MyServer {



 



      public
static void main(String[] args) {



           String
address = "http://localhost:8888/ns";



           Endpoint.publish(address,
new MyServiceImpl());



      }



 



}



在浏览器地址栏中输入; http://localhost:8888/ns?wsdl,看到页面上出现xml文件。



(2)客户端的创建:



public class TestClient {



      public
static void main(String[] args) {



           try
{



建立访问wsdl服务地址的url



                 URL
url = new URL("http://localhost:8888/ns?wsdl");



      经过qname指明服务的具体信息



                 QName
sname = new QName("http://service.zttc.org/",
"MyServiceImplService");



      建立服务



                 Service
service = Service.create(url,sname);



                                                 实现接口



                 IMyService
ms = service.getPort(IMyService.class);



                 System.out.println(ms.add(12,33));



          



           }
catch (MalformedURLException e) {



                 e.printStackTrace();



           }



      }



}



3.wsdl的有关参数:



types:用来定义访问的类型



message:SOAP



portType:指明服务器的接口,而且经过operation绑定相应的in和out的消息:其中in表示参数,out表示返回值



binding:指定传递消息所使用的格式



service:指定服务所发布的名称



4:dtd的例子:



classroom.dtd



<?xml version="1.0"
encoding="UTF-8"?>



<!ELEMENT classroom
(claName,grade,students)>



<!ATTLIST classroom id ID #REQUIRED>



<!ELEMENT claName (#PCDATA)>



<!ELEMENT grade (#PCDATA)>



<!ELEMENT students (student+)>



<!ELEMENT student (id,stuName,age)>



<!ELEMENT id (#PCDATA)>



<!ELEMENT stuName (#PCDATA)>



<!ELEMENT age (#PCDATA)>



classroom.xml



<?xml version="1.0"
encoding="UTF-8"?>



<!DOCTYPE classroom SYSTEM
"classroom.dtd">



<classroom id="c1">



      <claName>10计算机应用技术</claName>



      <grade>2010</grade>



      <students>



           <student>



                 <id>1</id>



                 <stuName>zhangsan</stuName>



                 <age>12</age>



           </student>



           <student>



                 <id>2</id>



                 <stuName>lisi</stuName>



                 <age>122</age>



           </student>



      </students>



</classroom>

js笔记

1.获得访问的文件地址

 <script type="text/javascript">
    
        with(location){
            var qs = search.substring(1);
            var hostName = hostname;      //unavailable when viewing from a local file
            var url = href;
        }

        alert(qs);
        alert(hostName);
        alert(url);

 

    </script>

<script type="text/javascript">
          //  == 表示两个对象的toString相等
//===表示两个对象的类型相等且值相等。
        alert(null == undefined);    //true
        alert(null === undefined);   //false
        
        alert("NaN" == NaN);        //false
        alert("NaN" === NaN);       //false
        alert(NaN == NaN);          //false
        alert(NaN === NaN);         //false
        alert(NaN != NaN);          //true
        alert(NaN !== NaN);         //true
        
        alert(false == 0);          //true
        alert(false === 0);         //false
        alert(true == 1);           //true
        alert(true === 1);          //false
        
        alert(null == 0);           //false
        alert(undefined == 0);      //false
        
        alert(5 == "5");            //true
        alert(5 === "5");           //false               
    </script>

 

--

<script type="text/javascript">
            
        alert(null == undefined);    //true
        alert(null === undefined);   //false
        
        alert("NaN" == NaN);        //false
        alert("NaN" === NaN);       //false
        alert(NaN == NaN);          //false
        alert(NaN === NaN);         //false
        alert(NaN != NaN);          //true
        alert(NaN !== NaN);         //true
        
        alert(false == 0);          //true
        alert(false === 0);         //false
        alert(true == 1);           //true
        alert(true === 1);          //false
        
        alert(null == 0);           //false
        alert(undefined == 0);      //false
        
        alert(5 == "5");            //true
        alert(5 === "5");           //false               

    </script>

<script type="text/javascript">
            
        var result1 = ("55" != 55);    //false ?equal because of conversion
        var result2 = ("55" !== 55);   //true ?not equal because different data types
        alert(result1);
        alert(result2);       

 var result1 = ("55" == 55);    //true ?equal because of conversion
        var result2 = ("55" === 55);   //false ?not equal because different data types           

    </script>
获得window中全部的事件

 

 <script type="text/javascript">
        for (var propName in window) {
             document.write(propName);
             document.write("<br />");
        }


    </script>


 <script type="text/javascript">
        for (var propName in window) {
             document.write(propName);
             document.write("<br />");
        }


    </script>

方法参数数组

 

<script type="text/javascript">
        function sayHi() {
            alert("Hello " + arguments[0] + ", " + arguments[1]);
        }

        sayHi("Nicholas", "how are you today?");


 function howManyArgs() {
            alert(arguments.length);
        }
        
        howManyArgs("string", 45);    //2
        howManyArgs();                //0
        howManyArgs(12);              //1    </script>


<script type="text/javascript">
        function sayHi() {
            alert("Hello " + arguments[0] + ", " + arguments[1]);
        }

        sayHi("Nicholas", "how are you today?");
    </script>

null的类型

<script type="text/javascript">
          
        var car = null;
        alert(typeof car);   //"object"
             


 alert(null == undefined);   //true    </script>

--

<script type="text/javascript">
          
        var car = null;
        alert(typeof car);   //"object"
              
    </script>

javascript技巧

1  Javascript数组转换为CSV格式


首先考虑以下的应用场景,有一个Javscript的字符型(或者数值型)数组,如今须要转换为以逗号分割的CSV格式文件。则咱们能够使用以下的小技巧,代码以下:

   
   
  1. var fruits = ['apple', 'peaches', 'oranges', 'mangoes'];
  2.  var str = fruits.valueOf();

 


输出:apple,peaches,oranges,mangoes


其中,valueOf()方法会将Javascript数组转变为逗号隔开的字符串。要注意的是,若是想不使用逗号分割,好比用|号分割,则请使用join方法,以下:

   
   
  1. var fruits = ['apple', 'peaches', 'oranges', 'mangoes'];
  2. var str = fruits.join("|");

输出: apple|peaches|oranges|mangoes


2 将CSV格式从新转换回Javscript数组


那么如何将一个CSV格式的字符串转变回Javascript数组呢?能够使用split()方法,就能够使用任何指定的字符去分隔,代码以下:

   
   
  1. var str = "apple, peaches, oranges, mangoes";
  2.  var fruitsArray = str.split(",");

 


输出 fruitsArray[0]: apple


3 根据索引移除数组中的某个元素


假如须要从Javascript数组中移除某个元素,能够使用splice方法,该方法将根据传入参数n,移除数组中移除第n个元素(Javascript数组中从第0位开始计算)。

   
   
  1. function removeByIndex(arr, index) {
  2. arr.splice(index, 1);
  3. }
  4. test = new Array();
  5. test[0] = 'Apple';
  6. test[1] = 'Ball';
  7. test[2] = 'Cat';
  8. test[3] = 'Dog';
  9. alert("Array before removing elements: "+test);
  10. removeByIndex(test, 2);
  11. alert("Array after removing elements: "+test);

 


则最后输出的为Apple,Ball,Dog


 


4 根据元素的值移除数组元素中的值


下面这个技巧是很实用的,是根据给定的值去删除数组中的元素,代码以下:

   
   
  1. function removeByValue(arr, val) {
  2. for(var i=0; i<arr.length; i++) {
  3. if(arr[i] == val) {
  4. arr.splice(i, 1);
  5. break;
  6. }
  7. }
  8. }
  9. var somearray = ["mon", "tue", "wed", "thur"]
  10. removeByValue(somearray, "tue");
  11. //somearray 将会有的元素是 "mon", "wed", "thur"

 


固然,更好的方式是使用prototype的方法去实现,以下代码:

   
   
  1. Array.prototype.removeByValue = function(val) {
  2. for(var i=0; i<this.length; i++) {
  3. if(this[i] == val) {
  4. this.splice(i, 1);
  5. break;
  6. }
  7. }
  8. }
  9. //..
  10. var somearray = ["mon", "tue", "wed", "thur"]
  11. somearray.removeByValue("tue");

 


5 经过字符串指定的方式动态调用某个方法


有的时候,须要在运行时,动态调用某个已经存在的方法,并为其传入参数。这个如何实现呢?下面的代码能够:

   
   
  1. var strFun = "someFunction"; //someFunction 为已经定义的方法名
  2. var strParam = "this is the parameter"; //要传入方法的参数
  3. var fn = window[strFun];
  4. //调用方法传入参数
  5. fn(strParam);

 


6 产生1到N的随机数

   
   
  1. var random = Math.floor(Math.random() * N + 1);
  2. //产生1到10之间的随机数
  3. var random = Math.floor(Math.random() * 10 + 1);
  4. //产生1到100之间的随机数
  5. var random = Math.floor(Math.random() * 100 + 1);

 


7 捕捉浏览器关闭的事件


咱们常常但愿在用户关闭浏览器的时候,提示用户要保存还没有保存的东西,则下面的这个Javascript技巧是十分有用的,代码以下:

   
   
  1.  <script language="javascript">
  2. function fnUnloadHandler() {
  3. alert("Unload event.. Do something to invalidate users session..");
  4. }
  5. </script>
  6. <body οnbefοreunlοad="fnUnloadHandler()">
  7. ………
  8. </body>

--

 


就是编写onbeforeunload()事件的代码便可

8  检查是否按了回退键


一样,能够检查用户是否按了回退键,代码以下:

   
   
  1. window.onbeforeunload = function() {
  2. return "You work will be lost.";
  3. };

 


9  检查表单数据是否改变


有的时候,须要检查用户是否修改了一个表单中的内容,则能够使用下面的技巧,其中若是修改了表单的内容则返回true,没修改表单的内容则返回false。代码以下:

   
   
  1. function formIsDirty(form) {
  2. for (var i = 0; i < form.elements.length; i++) {
  3. var element = form.elements[i];
  4. var type = element.type;
  5. if (type == "checkbox" || type == "radio") {
  6. if (element.checked != element.defaultChecked) {
  7. return true;
  8. }
  9. }
  10. else if (type == "hidden" || type == "password" ||
  11. type == "text" || type == "textarea") {
  12. if (element.value != element.defaultValue) {
  13. return true;
  14. }
  15. }
  16. else if (type == "select-one" || type == "select-multiple") {
  17. for (var j = 0; j < element.options.length; j++) {
  18. if (element.options[j].selected !=
  19. element.options[j].defaultSelected) {
  20. return true;
  21. }
  22. }
  23. }
  24. }
  25. return false;
  26. }
  27. window.onbeforeunload = function(e) {
  28. e = e || window.event;
  29. if (formIsDirty(document.forms["someForm"])) {
  30. // IE 和 Firefox
  31. if (e) {
  32. e.returnValue = "You have unsaved changes.";
  33. }
  34. // Safari浏览器
  35. return "You have unsaved changes.";
  36. }
  37. };

10  彻底禁止使用后退键


下面的技巧放在页面中,则能够防止用户点后退键,这在一些状况下是须要的。代码以下:

   
   
  1. <SCRIPT type="text/javascript">
  2. window.history.forward();
  3. function noBack() { window.history.forward(); }
  4. </SCRIPT>
  5. </HEAD>
  6. <BODY οnlοad="noBack();"
  7. οnpageshοw="if (event.persisted) noBack();" οnunlοad="">

 


11 删除用户多选框中选择的项目


下面提供的技巧,是当用户在下拉框多选项目的时候,当点删除的时候,能够一次删除它们,代码以下:

   
   
  1. function selectBoxRemove(sourceID) {
  2. //得到listbox的id
  3. var src = document.getElementById(sourceID);
  4. //循环listbox
  5. for(var count= src.options.length-1; count >= 0; count--) {
  6. //若是找到要删除的选项,则删除
  7. if(src.options[count].selected == true) {
  8. try {
  9. src.remove(count, null);
  10. } catch(error) {
  11. src.remove(count);
  12. }
  13. }
  14. }
  15. }

 


12  Listbox中的全选和非全选


若是对于指定的listbox,下面的方法能够根据用户的须要,传入true或false,分别表明是全选listbox中的全部项目仍是非全选全部项目,代码以下:

   
   
  1. function listboxSelectDeselect(listID, isSelect) {
  2. var listbox = document.getElementById(listID);
  3. for(var count=0; count < listbox.options.length; count++) {
  4. listbox.options[count].selected = isSelect;
  5. }
  6. }

13 在Listbox中项目的上下移动

下面的代码,给出了在一个listbox中如何上下移动项目

   
   
  1. unction listbox_move(listID, direction) {
  2. var listbox = document.getElementById(listID);
  3. var selIndex = listbox.selectedIndex;
  4. if(-1 == selIndex) {
  5. alert("Please select an option to move.");
  6. return;
  7. }
  8. var increment = -1;
  9. if(direction == 'up')
  10. increment = -1;
  11. else
  12. increment = 1;
  13. if((selIndex + increment) < 0 ||
  14. (selIndex + increment) > (listbox.options.length-1)) {
  15. return;
  16. }
  17. var selValue = listbox.options[selIndex].value;
  18. var selText = listbox.options[selIndex].text;
  19. listbox.options[selIndex].value = listbox.options[selIndex + increment].value
  20. listbox.options[selIndex].text = listbox.options[selIndex + increment].text
  21. listbox.options[selIndex + increment].value = selValue;
  22. listbox.options[selIndex + increment].text = selText;
  23. listbox.selectedIndex = selIndex + increment;
  24. }
  25. //..
  26. //..
  27. listbox_move('countryList', 'up'); //move up the selected option
  28. listbox_move('countryList', 'down'); //move down the selected option

 

14 在两个不一样的Listbox中移动项目

若是在两个不一样的Listbox中,常常须要在左边的一个Listbox中移动项目到另一个Listbox中去,下面是相关代码:

   
   
  1. function listbox_moveacross(sourceID, destID) {
  2. var src = document.getElementById(sourceID);
  3. var dest = document.getElementById(destID);
  4. for(var count=0; count < src.options.length; count++) {
  5. if(src.options[count].selected == true) {
  6. var option = src.options[count];
  7. var newOption = document.createElement("option");
  8. newOption.value = option.value;
  9. newOption.text = option.text;
  10. newOption.selected = true;
  11. try {
  12. dest.add(newOption, null); //Standard
  13. src.remove(count, null);
  14. }catch(error) {
  15. dest.add(newOption); // IE only
  16. src.remove(count);
  17. }
  18. count--;
  19. }
  20. }
  21. }
  22. //..
  23. //..
  24. listbox_moveacross('countryList', 'selectedCountryList');

 

15 快速初始化Javscript数组

下面的方法,给出了一种快速初始化Javscript数组的方法,代码以下:

   
   
  1. var numbers = [];
  2. for(var i=1; numbers.push(i++)<100;);
  3. //numbers = [0,1,2,3 ... 100]
  4. 使用的是数组的push方法

 

16 截取指定位数的小数

若是要截取小数后的指定位数,能够使用toFixed方法,好比:

   
   
  1. var num = 2.443242342;
  2.  alert(num.toFixed(2)); // 2.44
  3. 而使用toPrecision(x)则提供指定位数的精度,这里的x是所有的位数,如:
  4. num = 500.2349;
  5.  result = num.toPrecision(4);//输出500.2

 

17 检查字符串中是否包含其余字符串

下面的代码中,能够实现检查某个字符串中是否包含其余字符串。代码以下:

   
   
  1. if (!Array.prototype.indexOf) {
  2. Array.prototype.indexOf = function(obj, start) {
  3. for (var i = (start || 0), j = this.length; i < j; i++) {
  4. if (this[i] === obj) { return i; }
  5. }
  6. return -1;
  7. }
  8. }
  9. if (!String.prototype.contains) {
  10. String.prototype.contains = function (arg) {
  11. return !!~this.indexOf(arg);
  12. };
  13. }

 

在上面的代码中重写了indexOf方法并定义了contains方法,使用的方法以下:

   
   
  1. var hay = "a quick brown fox jumps over lazy dog";
  2. var needle = "jumps";
  3. alert(hay.contains(needle));

 

18 去掉Javscript数组中的重复元素

下面的代码能够去掉Javascript数组中的重复元素,以下:

   
   
  1. function removeDuplicates(arr) {
  2. var temp = {};
  3. for (var i = 0; i < arr.length; i++)
  4. temp[arr[i]] = true;
  5. var r = [];
  6. for (var k in temp)
  7. r.push(k);
  8. return r;
  9. }
  10. //用法
  11. var fruits = ['apple', 'orange', 'peach', 'apple', 'strawberry', 'orange'];
  12. var uniquefruits = removeDuplicates(fruits);
  13. //输出的 uniquefruits ['apple', 'orange', 'peach', 'strawberry'];

 

19 去掉String中的多余空格

下面的代码会为String增长一个trim()方法,代码以下:

   
   
  1. if (!String.prototype.trim) {
  2. String.prototype.trim=function() {
  3. return this.replace(/^\s+|\s+$/g, '');
  4. };
  5. }
  6. //用法
  7. var str = " some string ";
  8. str.trim();
  9. //输出 str = "some string"

 

20 Javascript中的重定向

在Javascript中,能够实现重定向,方法以下:

   
   
  1. window.location.href = "http://viralpatel.net";

 

21 对URL进行编码

有的时候,须要对URL中的传递的进行编码,方法以下:

   
   
  1. var myOtherUrl =
  2. "http://example.com/index.html?url=" + encodeURIComponent(myUrl);

jquery获得radio单选框的值

<html>
 <head>
  <script src="jquery.js" type="text/javascript"></script>
 </head>
 <body>
       <input type="radio" name="riskLib" value="yjw1">name1<br/> 
  <input type="radio" name="riskLib" value="yjw2">name2<br/>        
      <input type="button" id="Btn_riskLib"  />
 <script  type="text/javascript">
   $(document).ready(function(){
    $("#Btn_riskLib").bind("click",function(){      
                    var id =$(":radio:checked").val();
                    if(id==null){
                        alert("请选择一个!");
                      
                    }else {
      alert(id);
     }
  })
   });
 </script>
 </body>
</html>

jpa 多对多查询hql语句

任务和联系人是多对多关系,如今由联系人id查询出全部相关的任务
"SELECT t from Task t join t.contacters c where c.id = ?1"

好比:

一个老师教许多学生,一个学生被许多老师教,一个学生有好多书,同一种书被许多同窗拥有. 
要查询教拥有书"a"的学生的老师!

Hql语句:

SELECT t FROM Teacher t join t.students s join s.books b where b.name = 'a' 

解释:t.students s中s并非集合的意思,而是t的students对象的表别名,join t.students s这个hql,hibernate会翻译成两个表的内链接关系

错误写法:

SELECT t FROM teacher t where t.students.books.name = 'a' 

其实道理是很显然的,t.students是一个Set,那么这个Set怎么可能有books这样的属性呢?同理books.name也不对,因此 使用表间链接并给出别名t.students s,此时的对象s才有books属性,因此能够写s.books b,最后使用b.name限制查询b.name = 'a'. 

另一种写法:

SELECT t FROM Teacher t,Student s,Book b where s.id in elements(t.students) and b.id in elements(s.books)
这种方法没有出错!不过这种方式要用子查询!

 

java--dom读取xml文件

 public Map readXml() {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dbf.newDocumentBuilder();
            Document doc;
            InputStream stream = this.getClass().getResourceAsStream("/dictionaries.xml");
            doc = builder.parse(stream);
            Element root = doc.getDocumentElement();
            NodeList list = root.getElementsByTagName("dictionary");
            Map map = new LinkedHashMap();
            ArrayList<String> types = new ArrayList<String>();
            for (int i = 0; i < list.getLength(); i++) {
                String key = list.item(i).getAttributes().getNamedItem("name").getNodeValue();
                String value = list.item(i).getAttributes().getNamedItem("value").getNodeValue();
                map.put(key, value);
            }
            return map;
        } catch (Exception ex) {
            return null;
        }

    }

dictionaries.xml文件以下:

<?xml version="1.0" encoding="UTF-8"?>
<dictionaries>
    <dictionary name="项目类型" value="project.types" />
    <dictionary name="项目状态" value="project.statuses" />
    <dictionary name="任务阶段" value="task.stages" />
    <dictionary name="任务状态" value="task.statuses" />
    <dictionary name="发生概率" value="risk.probability" />
    <dictionary name="危险程度" value="risk.harm" />
    <dictionary name="风险状态" value="risk.status" />
    <dictionary name="预案类别" value="risk.type" />
    <dictionary name="合同类型" value="contract.type" />
    <dictionary name="合同状态" value="contract.status" />
</dictionaries>

jquery添加节点和删除节点例子

<html>
<body>
<input type="button" value="add row" id="addrow"/>
<table>
 <tr>
  <td width="20"><input type="checkbox" /><td>
  <td>dddddddd</td>
 </tr>
</table>

</body>
<script type="text/javascript" src="jquery-1.5.1.min.js"></script>
<script type="text/javascript" >
 $(document).ready(function(){
  $('input[type="checkbox"]').live('click',function(){//live给新添加的节点添加事件
   $(this).parent().parent().remove();
  });
  $('addrow').mouseover(function(){
   $(this).css('color','red');
  });
    $('addrow').mouseout(function(){
   $(this).css('color','red');
  });

  $('#addrow').click(function(){
  
   var tr = $('<tr>');
   var td1 = $('<td>');
   td1.attr('width','20');
   var input = $('<input>');
   input.attr('type','checkbox');
   var td2 = $('<td>');
   td2.text('aaaa');
   td1.append(input);
   tr.append(td1);
   tr.append(td2);
   //$('table').append(tr);
   $('tbody tr:first').before(tr);
  });
 });
</script>
</html>

jquery建立节点元素

<html>
<body>
<input type="button" value="add row" id="addrow"/>
<table>
 <tr>
  <td width="20"><input type="checkbox" /><td>
  <td>dddddddd</td>
 </tr>
</table>

</body>
<script type="text/javascript" src="jquery-1.5.1.min.js"></script>
<script type="text/javascript" >
 $(document).ready(function(){
  $('input[type="checkbox"]').click(function(){
   $(this).parent().parent().remove();
  });
  $('#addrow').click(function(){
  
   var tr = $('<tr>');
   var td1 = $('<td>');
   td1.attr('width','20');
   var input = $('<input>');
   input.attr('type','checkbox');
   var td2 = $('<td>');
   td2.text('aaaa');
   td1.append(input);
   tr.append(td1);
   tr.append(td2);
   $('table').append(tr);
  });
 });
</script>
</html>

javascript取得表单对象的几种方法

<html>
 <head></head>
 <body>
  <form name="fm1" id="fm1">
   name:<input type="text" name="name" id="name1" />
   <input type="submit"  id="s1"/>
  </form>
  <form name="fm2" id="fm2">
   name:<input type="text" name="name" id="name2" />
   <input type="submit" id="s2" />
  </form>
  <script type="text/javascript">
  //var form = document.getElementById('fm2');
  //var formarray = document.forms[1];//获得页面中因此表单的数组
  //var form = document.forms['fm1'];//根据表单name属性获得数组
  var form = document.fm1;//根据表单name属性获得数组
  alert(form);
  </script>
 </body>
</html>

javascript鼠标和键盘事件和关闭浏览器时的提示语

<html>
 <head></head>
 <body>
  <input type="text" id="mytext" />
  <span id="myspan"></span>
  <script type="text/javascript">
  var mytext=document.getElementById('mytext');
  var myspan=document.getElementById('myspan');
  mytext.onfocus = function(){
   myspan.innerHTML = '获得焦点';
  }
  mytext.onblur = function(){
      myspan.innerHTML = '失去焦点';

  }
  window.οnbefοreunlοad=function(){
   var v = mytext.value;
   alert(v);
   if(v){
    return '444';
   }
  }
  </script>
 </body>
</html>

javascript获得事件和元素的跨浏览器方法

<html>
 <head></head>
 <body>
  <div id="div1">1111111111
   <div id="div2">2222222222</div>
  </div>
  <input type="button"  id="btn"  />
  <a href="http://www.baidu.com" id="mya">163</a>
  <a href="javascript:;" >普通按钮,不跳转</a>
  <script type="text/javascript">
  var eventUtil = {
   addHandler:function(element,type,handler){
     if(element.addEventListener){
      element.addEventListener(type,handler,false);
     }else if(element.attachEvent){
      element.attachEvent('on'+type,handler);
     }else {
      element['on'+type]=handler;
     }
    },

   getEvent:function(event){
    return event ? event : window.event;
   },
   getElement: function(e){
    if(e.target){
     return e.target;
    }else {
     return e.srcElement;
    }
   },
   preventDefault:function(e){
    if(e.preventDefault){
     e.preventDefault();
    }else {
     e.returnValue=false;
    }
   },
   stopPropagation : function(e){
    if(e.stopPropagation){
     e.stopPropagation();
    }else {
     e.cancelBubble=true;
    }
   }
  };
  function test(event){
   var e = eventUtil.getEvent(event);
   alert("1="+e);
   var element = eventUtil.getElement(e);
   element.value = '33333333';
   alert("2="+element);
  }
  var btn = document.getElementById('btn');
  eventUtil.addHandler(btn,'click',test);
  </script>
 </body>
</html>

javascript事件对象event

在非ie中
<html>
 <head></head>
 <body>
  <div id="div1">1111111111
   <div id="div2">2222222222</div>
  </div>
  <input type="button"  id="btn"  />
  <a href=" http://www.baidu.com" id="mya">163</a>
  <a href="javascript:;" >普通按钮,不跳转</a>
  <script type="text/javascript">
    document.getElementById('btn').onclick = function(event){
    //在非ie中
    alert(event.type);
    alert(event.target);
    }
    document.getElementById('mya').onclick = function(event){
    alert(event.cancelable);
    if(event.cancelable){
     event.preventDefault();//阻止事件的发生
    }
    }
    document.getElementById('btn').onclick = function(event){
    //alert(1);
    event.stopPropagation();//阻止事件的传播
    
    }
    document.body.οnclick=function(){
    //alert(2);
    }
  </script>
 </body>
</html>
在ie中
<html>
 <head></head>
 <body>
  <div id="div1">1111111111
   <div id="div2">2222222222</div>
  </div>
  <input type="button"  id="btn"  />
  <a href=" http://www.baidu.com" id="mya">163</a>
  <a href="javascript:;" >普通按钮,不跳转</a>
  <script type="text/javascript">
  var event;
  function getEvent(){
   event=window.event;
  }
    document.getElementById('btn').onclick = function(event){
   getEvent();
   alert(event.type);
   alert(event.srcElement);//获得目标元素
   event.cancelBubble = true;//取消事件冒泡
   event.returnValue = false;//取消默认行为
    }
   //使用下面的方法能够在参数中获得event
   document.getElementById('btn').attachEvent('onclick',function(event){
    
   });
  </script>
 </body>
</html>

javascript跨浏览器事件

<html>
 <head></head>
 <body>
  <div id="div1">1111111111
   <div id="div2">2222222222</div>
  </div>
  <script type="text/javascript">
     var EventUtil = {
    addHandler:function(element,type,handler){
     if(element.addEventListener){
      element.addEventListener(type,handler,false);
     }else if(element.attachEvent){
      element.attachEvent('on'+type,handler);
     }else {
      element['on'+type]=handler;
     }
    },
    removeHandler:function(element,type,handler){
     if(element.addEventListener){
      element.removeEventListener(type,handler,false);
     }else if(element.attachEvent){
      element.detachEvent('on'+type,handler);
     }else {
      element['on'+type]=null;
     }
    }
     }
  
   function alertid(){
    alert(this.id);
   }
   var div1 = document.getElementById('div1');
   var div2 = document.getElementById('div2');
   EventUtil.addHandler(div2,'click',alertid);
   //EventUtil.removeHandler(div2,'click',alertid);
   //ie
   //div1.attachEvent('onclick',alertid);
   //div2.attachEvent('onclick',alertid);
   
   //非ie
   //div1.addEventListener('click',alertid,true);
   //div2.addEventListener('click',alertid,true);
  </script>
 </body>
</html>

javascript冒泡事件和捕获事件

JavaScript 的事件是以一种流的形式存在的,一个事件会有多个元素同时响应。有时候这不是咱们想要的,咱们只须要某个特定的元素响应咱们的绑定事件就能够了。 

事件分类
捕获型事件(非IE)、冒泡型事件(全部浏览器都支持)
捕获型事件是自上而下的,而冒泡型事件是自下而上的。下面我用一个图来直观表示:



冒泡型事件咱们在工做中可能会比较多遇到,但捕获型事件怎样才会执行到呢,若是咱们想要在非 IE 浏览器中要建立捕获型事件,只需将 addEventListener 的第三个参数设为true就行了。


第三个参数false表明在冒泡时运行,true表明在捕获时运行。

IDdiv1div2的两个元素都被绑定了捕捉阶段的事件处理函数,这样:

当点击#div1(蓝色区域)时,应该会alert”div1″ 当点击#div2(黄色区域)时,应该会先alert”div1″,再alert”div2″,由于在事件捕捉阶段,事件是从根元素向下传播的,#div1#div2的父元素,天然绑定在#div1上的click事件也会先于#div2上的click事件被执行。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>冒泡事件</title> <script type="text/javascript">   var i = 1;   function Add(sText,objText)   {        document.getElementById("Console").innerHTML +=sText + "执行顺序:" + i + "<br />" + "<hr />";        i = i + 1;        //window.event.cancelBubble = true;    }   </script>   </head>      <body οnclick="Add('body事件触发<br />','body')"> <div οnclick="Add('div事件触发<br />','div')"> <p οnclick="Add('p事件触发<br />','p')" style="background:#c00;">点击</p> </div> <div id="Console" style="border:solid 1px #ee0; background:#ffc;"></div> </body>

从这个例子咱们能够很清楚的看到事件冒泡是从目标元素 一直上升到 body 元素。
例子:
<html>
 <head></head>
 <body>
  <div id="div1">1111111111
   <div id="div2">2222222222</div>
  </div>
  <script type="text/javascript">
   function alertid(){
    alert(0);
   }
   var div1 = document.getElementById('div1');
   var div2 = document.getElementById('div2');
   
   //ie
   div1.attachEvent('onclick',alertid);
   div2.attachEvent('onclick',alertid);
   
   //非ie
   //div1.addEventListener('click',alertid,true);
   //div2.addEventListener('click',alertid,true);
  </script>
 </body>
</html>

javascript操做css

javascript操做css中,若是css的属性是好比background-color中间有横线的,在javascript操做是要遵照驼峰命名法,如mydiv.style.backgroundColor='blue';

在点击让图片显示和隐藏时cssstyle.visibility=’hidden’,让图片隐藏可是不释放空间,style.display=’none’,图片隐藏而且释放空间,style.display=’block’,图片显示,style.visibility=’visible’,图片显示。
一个定时不断改变颜色的例子:
<html>
 <head>
  <style type="text/css" >
   #mydiv{
    width:100px;
    height:100px;
   }
  </style>
  
 </head>
 <body>
 
  <div id="mydiv" ></div>
  <input id="start" type="button"  value="start" οnclick="start()"/>
  <input id="end" type="button"  value="end" οnclick="end()"/>
  <script type="text/javascript">
   
   var count = 4;
   var now = 1;
   function changea(){
    var mydiv = document.getElementById('mydiv');
    if(now==1){
     mydiv.style.backgroundColor='blue';
    }
    if(now==2){
     mydiv.style.backgroundColor='red';
    }
    if(now==3){
     mydiv.style.backgroundColor='black';
    }
    if(now==4){
     mydiv.style.backgroundColor='yellow';
    }
    now++;
   // alert(now);
    if(now>=5){
     now=1;
    }
    var a =setTimeout(changea,1000);
    
   }
   changea();
  </script>
 </body>
</html>

 
 

java排序

package com.test.yjw;

public class Sort {

 //冒泡
 /**
  * 
  */
 public static void bubbleSort(int a[]) {
  int len = a.length;
  for (int i = 0; i < len - 1; i++) {
   for (int j = 0; j < len - 1 - i; j++) {
    if (a[j] > a[j + 1]) {
    int temp = a[j];
    a[j] = a[j + 1];
    a[j + 1] = temp;
    }
   }
  }
  for(int t : a){
   System.out.println(t);
  }
 }
 //选择排序
 public static void selectSort(int a[]) {
  int temp = 0;
  int len = a.length;
  for (int i = 0; i < len - 1; i++) {
   int min = a[i];
   int index = i;
   for (int j = i + 1; j < len; j++) {
    if (min > a[j]) {
     min = a[j];
     index = j;
    }
   }
   temp = a[i];
   a[i] = a[index];
   a[index] = temp;
  }
  for(int t : a){
   System.out.println(t);
  }
 }
// 插入排序{9,5,1,3,7,8,6,2,0,4}
 public static void insertSort(int a[]) {
  int len = a.length;
  for (int i = 1; i < len; i++) {
   int temp = a[i];// 待插入的值
   int index = i;// 待插入的位置
   while (index > 0 && a[index - 1] > temp) {
    a[index] = a[index - 1];// 待插入的位置从新赋更大的值
    index--;// 位置往前移
   }
   a[index] = temp;
  }
  for(int t : a){
   System.out.println(t);
  }
 }
 //快速排序
 public static void quickSort(int a[], int low, int height) {
  if (low < height) {
   int result = partition(a, low, height);
   quickSort(a, low, result - 1);
   quickSort(a, result + 1, height);
  }
  
 }
 public static int partition(int a[], int low, int height) {
  int key = a[low];
  while (low < height) {
   while (low < height && a[height] >= key)
   height--;
   a[low] = a[height];
   while (low < height && a[low] <= key)
   low++;
   a[height] = a[low];
  }
  a[low] = key;
  return low;
 }
  public static void swap(int a[], int i, int j) {              // 经过临时变量,交换数据
      int tmp = a[i];
      a[i] = a[j];
      a[j] = tmp;
    }                                                                  // 第一次交换分析
    public static void quicksort(int a[], int low, int high) {   // 假设传入low=0; high=a.length-1;
      if (low < high) {                                          // 条件判断
       int pivot, p_pos, i;                                    // 声明变量
          p_pos = low;                                         // p_pos指向low,即位索引为0位置 ;
          pivot = a[p_pos];                                   // 将0位置上的数值赋给pivot;
          for (i = low + 1; i <= high; i++) {             // 循环次数, i=1;
           if (a[i]>pivot) {                                      // 1位置的数与0位置数做比较: a[1]>a[0]
             p_pos++;                                           // 2位与1位比较,3位与2位比较......
             swap(a, p_pos, i);                              // 传参并调用swap     
            }
          }
        swap(a, low, p_pos);                              // 将p_pos设为high再次调用swap
        quicksort(a, low, p_pos - 1);                  // 递归调用,排序左半区
        quicksort(a, p_pos + 1, high);                // 递归调用,排序右半区
      }
     
    }
  
 public static void main(String[] args) {
  int[] a =new  int[]{9,5,1,3,7,8,6,2,0,4};
  //Sort.bubbleSort(a);
  //Sort.selectSort(a);
  //Sort.insertSort(a);
  Sort.quickSort(a, 0, a.length-1);
   for(int t : a){
    System.out.println(t);
   }
 }
}

 

java io

在java语言 I/O库的设计中,使用了两个结构模式,即装饰模式和适配器模式。
      在任何一种计算机语言中,输入/输出都是一个很重要的部分。与通常的计算机语言相比,java将输入/输出的功能和使用范畴作了很大的扩充。所以输入输出在java语言中占有极为重要的位置。
      java语言采用流的机制来实现输入/输出。所谓流,就是数据的有序排列,流能够是从某个源(称为流源,或者 Source of Stream)出来,到某个目的(Sink of Stream)地去。根据流的方向能够将流分红输出流和输入流。程序经过输入流读取数据,想输出流写出数据。
     例如:一个java程序能够使用FileInputStream类从一个磁盘文件读取数据,以下图:

                                      
      像FileInputStream这样的处理器叫流处理器。一个流处理器就像一个流的管道同样,从一个流源吸入某种类型的数据,并输出某种类型的数据。上面的示意图叫流的管道图。

     相似地,也能够用FileOutputStream类向一个磁盘文件写数据,以下图:

                                           

     在实际的应用当中,这样简单的机制并无太大的用处。程序须要写出的每每是很是结构话的信息,所以这些Byte类型的数据其实是一些数字、文字、源代码等。java的I/O库提供了一个称做连接(Chaining)的机制,能够将一个流处理器与另外一个流处理器首尾相接,以其中之一的输出为输入,造成一个流管道的连接。

      例如,DateInputStream流处理器能够把FileInputStream流对象的输出当作输入,将Byte类型的数据转换成java的原始数据类型和String数据类型,以下图:

                              

       相似地,向一个文件中写入Byte类型的数据也不是一个简单的过程。一个程序须要向一个文件里写入的数据每每是结构化的,而Byte类型则是原始的类型,所以,在写入的时候必须首先通过转换。DateOutputStream流处理器提供了接受原始数据类型和String数据类型的方法,而这个流处理器的输出数据则是Byte类型。换而言之,DateOutputStream能够将源数据转换成Byte类型的数据,在输出出来。

      这样一来,就能够将DateOutputStream与FileOutputStream连接起来。这样作的结果就是,程序能够将原始数据类型和String数据类型的源数据写到这个连接好的双重管道里面,达到将结构话数据写到磁盘文件里的目的,以下图所示:

                        

      这是连接的威力。

      流处理器所处理的流一定都有流源,若是将流类所处理的流源分类的话,那么基本能够分红两大类:

   (1)数组、String、File等,这一种叫原始流源。

   (2)一样类型的流用作连接流类的流源,就叫作连接流源。





java I/O库的设计原则


      
java语言的I/O库是对各类常见的流源、流汇以及处理过程的抽象化。客户端的java 程序没必要知道最终的的流源、流汇是磁盘上的文件仍是一个数组,或者是一个线程;也不比插手到诸如数据是否缓存、能否按照行号读取等处理的细节中去。

     要理解java I/O 这个庞大而复杂的库,关键是掌握两个对称性和两个设计模式。



java I/O库的两个对称性


     
 java I/O库具备两个对称性,它们分别是:

     (1)输入-输出对称:好比InputStream 和OutputStream 各自占据Byte流的输入和输出的两个平行的等级结构的根部;而Reader和Writer各自占据Char流的输入和输出的两个平行的等级结构的根部。

     (2)byte-char对称:InputStream和Reader的子类分别负责byte和插入流的输入;OutputStream和Writer的子类分别负责byte和Char流的输出,它们分别造成平行的等级结构。



java I/O库的两个设计模式


      ava I/O库的整体设计是符合装饰模式和适配器模式的。如前所述,这个库中处理流的类叫流类。

      装饰模式:在由InputStream、OutputStream、Reader和Writer表明的等级结构内部,有一些流处理器能够对另外一些流处理器起到装饰做用,造成新的、具备改善了的功能的流处理器。

     适配器模式:在由InputStream、OutputStream、Reader和Writer表明的等级结构内部,有一些流处理器是对其余类型的流处理器的适配。这就是适配器的应用。



装饰模式的应用


      装饰模式在java中的最著名的应用莫过于java I/O标准库的设计了。

      因为java I/O库须要不少性能的各类组合,若是这些性能都是用继承来实现,那么每一种组合都须要一个类,这样就会形成大量行重复的类出现。若是采用装饰模式,那么类的数目就会大大减小,性能的重复也能够减至最少。所以装饰模式是java I/O库基本模式。

      装饰模式的引进,形成灵活性和复杂性的提升。所以在使用 java I/O 库时,必须理解java I/O库是由一些基本的原始流处理器和围绕它们的装饰流处理器所组成的。

InputStream类型中的装饰模式

       InputStream有七个直接的具体子类,有四个属于FilterInputStream的具体子类,以下图所示:

               

      上图中全部的类都叫作流处理器,这个图叫作(InputStream类型)流处理器图。根据输入流的源的类型,能够将这些流分为两种,即原始流类和连接流处理器。

原始流处理器


      原始流处理器接收一个Byte数组对象、String对象、FileDescriptor对象或者不一样类型的流源对象(就是前面所说的原始流源),并生成一个InputStream类型的流对象。在InputStream类型的流处理器中,原始流处理器包括如下四种:
    (1)ByteArrayInputStream:为多线程的通信提供缓冲区操做工做,接受一个Byte数组做为流的源。
    (2)FileInputStream:创建一个与文件有关的输入流。接受一个File对象做为流的源。
    (3)PipedInputStream:能够和PipedOutputStream配合使用,用于读入一个数据管道的数据。接受一个PipedOutputStream做为源。
    (4)StringBufferInputStream:将一个字符串缓冲区抓换为一个输入流。接受一个String对象做为流的源。
      与原始流处理器相对应的是连接流处理器。

连接流处理器


       
所谓连接流处理器就是能够接受另外一个(同种类的)流对象(就是连接流源)做为流源,并对之进行功能扩展的类。InputStream类型的连接流处理器包括如下几种,它们接受另外一个InputStream对象做为流源。

     (1)FilterInputStream称为过滤输入流,它将另外一个输入流做为流源。这个类的子类包括如下几种:
         BufferInputStream:用来从硬盘将数据读入到一个内存缓冲区中,并今后缓冲区提供数据。
         DateInputStream:提供基于多字节的读取方法,能够读取原始数据类型的数据。
         LineNumberInputStream:提供带有行计算功能的过滤输入流。       
         PushbackInputStream: 提供特殊的功能,能够将已读取的直接“推回”输入流中。
     (2)ObjectInputStream 能够将使用ObjectInputStream串行化的原始数据类型和对象从新并行化。
     (3)SequenceInputStream能够将两个已有的输入流链接起来,造成一个输入流,从而将多个输入流排列构成一个输入流序列。
     必须注意的是,虽然PipedInuptStream接受一个流对象PipedOutputStream做为流的源,可是PipedOutputStream流对象的类型不是InputStream,所以PipedInputStream流处理器仍属于原始流处理器。 


抽象结构图

          


     上面流处理器图与装饰模式的结构图有明显的相同之处。实际上InputStream类型的流处理器结构确实符合装饰模式,而这能够从它们在结构中所扮演的角色中分辩出来。



装饰模式的各个角色


      在全部InputStream类型的连接流处理其中,使用频率最大的就是FilterInputStream类,以这个类为抽象装饰角色的装饰模式结构很是明显和典型。以这个类为核心说明装饰模式的各个角色是由哪些流处理器扮演:
       抽象构件(Component)角色:由InputStream扮演。这是一个抽象类,为各类子类型处理器提供统一的接口。
       具体构建(Concrete Component)角色:由ByteArrayInputStream、FileInputStream、PipedInputStream以及StringBufferInputStream等原始流处理器扮演。它们实现了抽象构建角色所规定的接口,能够被连接流处理器所装饰。
       抽象装饰(Decorator)角色:由FilterInputStream扮演。它实现了InputStream所规定的接口。
       具体装饰(Concrete Decorator)角色:由几个类扮演,分别是DateInputStream、BufferedInputStream 以及两个不经常使用到的类LineNumberInputStream和PushbackInputStream。
      连接流其实就是装饰角色,原始流就是具体构建角色,以下图所示:
            
      一方面,连接流对象接受一个(同类型的)原始流对象或者另外一个(同类型的)连接流对象做为流源;另外一方面,它们都对流源对象的内部工做方法作了相应的改变,这种改变是装饰模式所要达到的目的。好比:
     (1)BufferedInputStream “装饰” 了InputStream的内部工做方式,使得流的读入操做使用缓冲机制。在使用了缓冲机制后,不会对每一次的流读入操做都产生一个物理的读盘动做,从而提升了程序的效率。在涉及到物理流的读入时,都应当使用这个装饰流类。
     (2)LineNumberInputStream和PushbackInputStream也一样“装饰”了InputStream的内部工做方式,前者使得程序可以按照行号读入数据;后者能使程序在读入的过程当中退后一个字符。后两个装饰类可能在实际的编程工做中不多用到,由于它们是为了支持用java语言作编译器而准备的。
     (3)DateInputStream子类读入各类不一样的原始数据类型以及String类型的数据,这一点能够从它提供的各类read()方法看出来: readByte()、readUnsignedByte()、readShort()、readUnsignedShort()、readChar()、readInt()、readLong()、readFloat()、readDouble()、readUTF()。使用这个流处理器以及它的搭档DateOutputStream,能够将原始数据经过流从一个地方移到另外一个地方。   

OutputStream 类型中的装饰模式   

      outputStream是一个用于输出的抽象类,它的接口、子类的等级结构、子类的功能都和InputStream有很好的对称性。在OutputStream给出的接口里,将write换成read就获得了InputStream的接口,而其具体子类则在功能上面是平行的。
     (1)针对byte数字流源的连接流类,以ByteArrayInputStream描述输入流,以ByteArrayOutputStream描述输出流。
     (2)针对String流源的连接流类,以StringBufferInputStream描述输入流,以StringBufferOutputStream描述输出流。
     (3)针对文件流源的连接流类,以FileInputStream描述输入流,以FileOutputStream描述输出流。
     (4)针对数据管道流源的连接流类,以PipedInputStream描述输入流,以PipedOutputStream描述输出流。
     (5)针对以多个流组成的序列,以SequenceInputStream描述输入流,以SequenceOutputStream描述输出流。

OutputStream类型有哪些子类

      outputStream有5个直接的具体子类,加上三个属于FilterInputStream的具体子类,一共有8个具体子类,以下图:
       

      原始流处理器

      在OutputStream类型的流处理器中,原始流处理器包括如下三种:
       ByteArrayOutputStream:为多线程的通讯提供缓冲区操做功能。输出流的聚集是一个byte数组。
       FileOutputStream:创建一个与文件有关的输出流。输出流的聚集是一个文件对象。
      PipedOutputStream: 能够与PipedInputStream配合使用,用于向一个数据管道输出数据。

      连接流处理器

      OutputStream类型的连接流处理器包括如下几种:
     (1)FilterOutputStream:称为过滤输出流,它将另外一个输出流做为流汇。这个类的子类有以下几种:
      BufferedOutputStream:用来向一个内存缓冲区中写数据,并将此缓冲区的数据输入到硬盘中。
      DataOutputStream:提供基于多字节的写出方法,能够写出原始数据类型的数据。
      PrintStream:用于产生格式化输出。System.out 静态对象就是一个PrintStream。
     (2)ObjectOutputStream 能够将原始数据类型和对象串行化。

      装饰模式的各个角色
      

      在全部的连接流处理器中,最多见的就是FilterOutputStream类。以这个类为核心的装饰模式结构很是明显和典型,以下图:
         
      装饰模式所涉及的各个角色:
       抽象构件(Component)角色:由OutputStream扮演,这是一个抽象类,为各类的子类型流处理器提供统一的接口。      
       具体构件(Concrete Component)角色:由ByteArrayOutputStream、FileOutputStream、PipedOutputStream等扮演,它们均实现了OutputStream所声明的接口。
       抽象装饰(Decorator)角色:由FilterOutputStream扮演,它与OutputStream有相同的接口,而这正是装饰类的关键。
       具体装饰(Concrete Decorator)角色:由几个类扮演,分别是BufferedOutputStream、DateOutputStream、以及PrintStream。
       所谓连接流,就是装饰模式中的装饰角色,原始流就是具体构件角色。
      
与DateInputStream相对应的是DataOutputStream,后者负责将由原始数据类型和String对象组成的数据格式化,并输出到一个流中,使得任何机器上的任何DataInputStream类型的对象均可以读入这些数据。全部的方法都是以write开始。
      若是须要对数据进行真正的格式化,以便输出到像控制台显示那样,那就须要使用PrintStream。
PrintStream能够对由原始数据类型和String对象组成的数据进行格式化,以造成能够阅读的格式;而DataOutputStream则不一样,它将数据输出到一个流中,以便DataInputStream能够在任何机器然后操做系统中均可以从新将数据读入,并进行结构重建。
      PrintStream对象最重要的两个方法是print() 和println(),这两个方法都是重载的,以即可以打印出全部使用类型的数据。这两个方法之间的区别是后者每行结束时多打印出一个换行符号。
      BufferedOutputStream对一个输出流进行装饰,使得流的写出操做使用缓冲机制。在使用缓冲机制后,不会对每一次的流的写入操做都产生一个物理的写动做,从而提升的程序的效率。在涉及到物理流的地方,好比控制台I/O、文件I/O等,都应当使用这个装饰流处理器。
     

 Reader类型中的装饰模式

     在Reader类型的流处理器中, 原始流处理器包括如下四种:
    (1)CharArrayReader:为多线程的通讯提供缓冲区操做功能。
    (2)InputStreamReader:这个类有一个子类--FileReader。
    (3)PipedReader:能够与PipedOutputStream配合使用,用于读入一个数据管道的数据。 
    (4)StringReader:创建一个与文件有关的输入流。
      连接流处理器包括如下:
    (1)BufferedReader:用来从硬盘将数据读入到一个内存缓冲区,并今后缓冲区提供数据,这个类的子类为LineNumberReader。
    (2)FilterReader:成为过滤输入流,它将另外一个输入流做为流的来源。这个类的子类有PushbackReader,提供基于多字节的读取方法,能够读取原始数据类型的数据,Reader类型的类图以下所示:
   
      Reader类型中,装饰模式所涉及的各个角色:
     (1)抽象构建(Component)角色:有Reader扮演。这是一个抽象类,为各类的子类型流处理器提供统一的接口。
     (2)具体构建(Concrete Component)角色:由CharArrayReader、InputStreamReader、PiPedReader、StringReader等扮演,他们均实现了Reader所声明的接口。
     (3)抽象装饰(Decorator)角色:由BufferedReader和FilterReader扮演。这二者有着与Reader相同的接口,它们分别给出两个装饰角色的等级结构,第一个给出LineNumberReader做为具体装饰角色,另外一个给出PushbackReader 做为具体装饰角色。
     (4)具体装饰(Concrete Decorator)角色:LineNumberReader做为BufferedReader的具体装饰角色,BufferedReader做为FilterReader的具体装饰角色。
       以下图所示,标有聚合连线的就是抽象装饰角色:
      
   

Writer类型中的装饰模式

       Writer类型是一个与Reader类型平行的等级结构,并且Writer类型的等级结构几乎与Reader的等级结构关于输入/输出是对称的。如图所示:
              
      在Writer类型的流处理器中,原始流处理器包括如下四种:
     (1)CharArrayWriter:为多线程的通讯提供缓冲区的操做功能。
     (2)OutputStreamWriter:创建一个与文件有关的输出流。含有一个具体子类FileWrite,为Write类型的输出流提供文件输出功能。
     (3)PipedWriter:能够和PipedOutputStream配合使用,用于读若是一个数据管道的数据。
     (4)StringWriter:想一个StringBuffer写出数据。
       连接流处理器包括如下三种:
     (1)BufferedWriter:为Writer类型的流处理器提供缓冲区功能。
     (2)FilterWriter:称为过滤输入流,它将另外一个输入流做为流的来源。这是一个没有子类的抽象类。
     (3)PrintWriter:支持格式化的文字输出。
      Writer类型中,装饰模式所涉及的各个角色:
     (1)抽象构建(Component)角色:由Write扮演。这是一个抽象类,为为各类子类型的流处理器提供统一的接口。
     (2)具体构建(Concrete Component):角色由CharArrayWriter、OutputStreamWriter、
PipedWriter、StringWriter扮演,它们实现了Writer所声明的接口。    
     (3)抽象装饰(Decorator)角色:由BufferedWriter、FilterWriter、PrintWriter扮演,它们有着与Write
相同的接口。
     (4)具体装饰(Concrete Decorator)角色:与抽象装饰角色合并。
      以下图所示,标出了从抽象装饰角色到抽象构件角色的聚合连线,更易于与装饰模式的结构图比较。
             

      适配器模式的应用

      适配器模式是java I/O库中第二个最重要的设计模式。

     InputStream原始流处理器中的适配器模式     

      InputStream类型的原始流处理器是适配器模式的应用。

      ByteArrayInputStream是一个适配器类

      ByteArrayInputStream继承了InputStream的接口,而封装了一个byte数组。换而言之,它将一个byte数组的接口适配成了InputStream流处理器的接口。 
      java语言支持四种类型:java类、java接口、java数组和原始类型。前三章是引用类型,类和数组的实例都是对象,原始类型的值很多对象。java语言的数组是像全部其余对象同样的对象,而无论数组中所存放的元素的类型是什么。这样一来,ByteArrayInputStream就符合适配器模式的描述,并且是一个对象形式的适配器类。以下图所示:
            

       StringBufferInputStream是一个适配器类

      StringBufferInputStream继承了InputStream类型,同时持有一个对String类型的引用。这是将String对象适配成InputStream类型的对象形式的适配器模式,以下图:
        
        

      OutputStream原始流处理器中的适配器模式

      在OutputStream类型中,全部的原始流处理器都是适配器类。
      ByteArrayOutputStream是一个适配器类
      ByteArrayOutputStream继承了OutputStream类型,同事持有一个对byte数组的引用。它把一个byte数组的接口适配成OutputStream类型的接口,所以也是一个对象类型的适配器模式的应用。以下图:
                                        
       FileOutputStream是一个适配器类
       FileOutputStream继承OutputStream,同时持有一个对FileDescriptor对象的引用。这是一个将FileDescriptor适配成OutputStream接口的对象形式的适配器模式,以下图所示:
                                              
       PipedOutputStream是一个适配器类
       PipedOutputStream老是和PipedInputStream一块儿使用,它接收一个类型为PipedInputStream的输入类型,并将之转换成OutputStream类型的输出流,这是一个对象形式的适配器模式应用。以下图:
                                               
      Reader原始流处理器中的适配器模式
      Reader 类型的原始流处理器都是适配器模式的应用。
      CharArrayReader是一个适配器类。
      CharArrayReader将一个Char数组适配成Reader类型的输入流,所以它是一个对象形式的适配器应用,以下图所示:
                              
      StringReader是一个适配器类
      StringReader 继承了Reader类型,持有一个对String类型的引用。它将String的接口适配成Reader类型的接口,以下图所示:
                        
        
      Writer类型中的适配器模式
      Writer类型中的原始流处理器就是适配器模式的具体应用。
      CharArrayWriter是一个适配器类。
      CharArrayWriter将一个Char数组适配成Writer 接口,以下图所示:
                                            
      PipedWriter是一个适配器类
      PipedWriter老是与PiPedReader一同使用,它将一个PipedReader对象的接口适配成一个Writer类型的接口,以下图所示:
                             
       StringWriter是一个适配器类
       StringWriter继承Writer类型,同时持有一个StringBuffer对象,它将StringBuffer对象的接口适配成为了
Writer类型的接口,是一个对象形式的适配器 模式的应用,以下图所示:
                                    
       

      从byte流到char流的适配

      在java语言的标准库 java I/O 里面,有一个InputStreamReader类叫作桥梁(bridge)类。InputStreamReader是从byte流到char流的一个桥梁,它读入byte数据并根据指定的编码将之翻译成char数据。
InputStreamReader虽然叫“桥梁”,但它不爽桥梁模式,是适配器模式的应用。

     InputStreamReader

     InputStreamReader是从byte输入流到char输入流的一个适配器。下图所示就是InputStreamReader 的结构图:
                   
     为了说明适配器类InputStreamReader是如何使用,请看下面例子。Echo类能够将控制台输入的任何字符串重新打印出来,源代码以下:
  Echo.java
  
01 package com.think.cla;
02   
03 import java.io.BufferedReader;
04 import java.io.IOException;
05 import java.io.InputStreamReader;
06   
07 public class Echo {
08       
09     public static  void main(String [] args)throws IOException{
10         String line;
11         InputStreamReader input = new InputStreamReader(System.in);
12         System.out.println("Enter data and push enter:");
13         BufferedReader reader = new BufferedReader(input);
14         line = reader.readLine();
15         System.out.println("Data entered :"+line);
16     }
17   
18 }
      能够看出,这个类接受一个类型为inputStream的System.in对象,将之适配成Reader类型,而后再使用 
BufferedReader类“装饰”它,将缓冲功能加上去。这样一来,就能够使用BufferedReader对象的readerLine() 
方法读入整行的输入数据,数据类型是String。 
      在获得这个数据以后,程序又将它写出到System.out 中去,完成了所有的流操做,下图所示为其管道图: 
                       
      本系统使用了BufferedReader来为流的读入提供缓冲功能,这样作的直接效果是能够使用readLine()方法按行读入数据。可是因为Reader接口并不提供readLine()方法,因此这样一来,系统就必须声明一个BufferedReader类型的流处理器,而不是一个Reader类型的流处理器,这意味着装饰模式的退化。 
     在上面的管道链接过程当中,InputStreamReader 起到了适配器的做用,它将一个byte类型的输入流适配成为一个char类型的输入流。在这以后,BufferedReader则起到了装饰模式的做用,将缓冲机制引入到流的读入中。所以这个例子涉及到了两个设计模式。      

poi读取excel

package com.scpii.ent.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.scpii.ent.mode.bean.DataSet;

public class ExcelOperClass {
 private static String EXCEL_2003 = ".xls";
 private static String EXCEL_2007 = ".xlsx";

 public static void readExcelJXL() {

 }

 /**
  * 经过POI方式读取Excel
  * 
  * @param excelFile
  */
 public static DataSet readExcelPOI(String filePath, Integer cons) throws Exception {
  File excelFile = new File(filePath);
  if (excelFile != null) {
   String fileName = excelFile.getName();
   fileName = fileName.toLowerCase();
   if (fileName.toLowerCase().endsWith(EXCEL_2003)) {
    DataSet dataSet = readExcelPOI2003(excelFile, cons);
    return dataSet;
   }
   if (fileName.toLowerCase().endsWith(EXCEL_2007)) {
    DataSet dataSet = readExcelPOI2007(excelFile, cons);
    return dataSet;
   }
  }
  return null;
 }

 /**
  * 读取Excel2003的表单
  * 
  * @param excelFile
  * @return
  * @throws Exception
  */
 private static DataSet readExcelPOI2003(File excelFile, Integer rCons)
   throws Exception {
  List<String[]> datasList = new ArrayList<String[]>();
  Set<String> colsSet = new HashSet<String>();
  InputStream input = new FileInputStream(excelFile);
  HSSFWorkbook workBook = new HSSFWorkbook(input);
  // 获取Excel的sheet数量
  Integer sheetNum = workBook.getNumberOfSheets();
  // 循环Sheet表单
  for (int i = 0; i < sheetNum; i++) {
   HSSFSheet sheet = workBook.getSheetAt(i);
   if (sheet == null) {
    continue;
   }
   // 获取Sheet里面的Row数量
   Integer rowNum = sheet.getLastRowNum() + 1;
   for (int j = 0; j < rowNum; j++) {
     if (j>rCons) {
     System.out.println("===========");
     HSSFRow row = sheet.getRow(j);
     if (row == null) {
      continue;
     }

     Integer cellNum = row.getLastCellNum() + 1;
     String[] datas = new String[cellNum];
     for (int k = 0; k < cellNum; k++) {
      HSSFCell cell = row.getCell(k);
      if (cell == null) {
       continue;
      }
      if (cell != null) {
       cell.setCellType(HSSFCell.CELL_TYPE_STRING);
       String cellValue = "";
       int cellValueType = cell.getCellType();
       if (cellValueType == cell.CELL_TYPE_STRING) {
        cellValue = cell.getStringCellValue();
       }
       if (cellValueType == cell.CELL_TYPE_NUMERIC) {
        Double number = cell.getNumericCellValue();
        
        System.out.println("字符串+++=========="+number.intValue());
        cellValue = cell.getNumericCellValue() + "";
       }

       if (rCons==k) {
        colsSet.add(cellValue);
       }

       System.out.println(cellValue);
       datas[k] = cellValue;
      }
     }
     datasList.add(datas);
    }
   }
  }
  DataSet dataSet = new DataSet(null, null, datasList, colsSet);
  return dataSet;
 }

 /**
  * 读取Excel2007的表单
  * 
  * @param excelFile
  * @return
  * @throws Exception
  */
 private static DataSet readExcelPOI2007(File excelFile, Integer rCons) throws Exception {
  List<String[]> datasList = new ArrayList<String[]>();
  Set<String> cosSet = new HashSet<String>();
  InputStream input = new FileInputStream(excelFile);
  XSSFWorkbook workBook = new XSSFWorkbook(input);
  // 获取Sheet数量
  Integer sheetNum = workBook.getNumberOfSheets();
  for (int i = 0; i < sheetNum; i++) {
   XSSFSheet sheet = workBook.getSheetAt(i);
   if (sheet == null) {
    continue;
   }
   // 获取行值
   Integer rowNum = sheet.getLastRowNum() + 1;
   for (int j = 0; j < rowNum; j++) {
    if (j > rCons) {
     System.out.println("=============");
     XSSFRow row = sheet.getRow(j);
     if (row == null) {
      continue;
     }
     Integer cellNum = row.getLastCellNum() + 1;
     String[] datas = new String[cellNum];
     for (int k = 0; k < cellNum; k++) {
      XSSFCell cell = row.getCell(k);
      if (cell==null) {
       continue;
      }
      if (cell != null) {
       cell.setCellType(XSSFCell.CELL_TYPE_STRING);
       String cellValue = "";
       int cellValueType = cell.getCellType();
       if (cellValueType == cell.CELL_TYPE_STRING) {
        cellValue = cell.getStringCellValue();
       }
       if (cellValueType == cell.CELL_TYPE_NUMERIC) {
        Double number = cell.getNumericCellValue();
        System.out.println("字符串+++=========="+number.toString());
        cellValue = cell.getNumericCellValue() + "";
       }
       System.out.println(cellValue);
       if (rCons == k) {
        cosSet.add(cellValue);
       }
       datas[k] = cellValue;
      }
     }
     datasList.add(datas);
    }
   }
  }
  DataSet dataSet = new DataSet(null, null, datasList,cosSet);
  return dataSet;
 }

 public static void main(String[] args) {
//  try {
//   DataSet dataSet = readExcelPOI("D:\\部门员工资料.xls", 0);
//   System.out.println("================================");
//   Set<String> datas = dataSet.getConStrctSet();
//   String[] datastr = new String[datas.size()];
//   datastr = datas.toArray(datastr);
//   for (int i = 0; i < datastr.length; i++) {
//    System.out.println(datastr[i]);
//   }
//  } catch (Exception e) {
//   e.printStackTrace();
//  }
  
  System.out.println(52%4);
 }
}


package com.scpii.ent.mode.bean;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class DataSet {
 private String[] headers;
 private String[] rowHeaders;
 private List<String[]> datasList = new ArrayList<String[]>();
 private Set<String> conStrctSet;

 public DataSet(String[] headers, String[] rowHeaders,
   List<String[]> datasList, Set<String> conStrctSet) {
  this.headers = headers;
  this.rowHeaders = rowHeaders;
  this.datasList = datasList;
  this.conStrctSet = conStrctSet;
 }

 public DataSet(String[] header, String[] rowsHeader,
   List<String[]> datasList2) {
  this.headers = header;
  this.rowHeaders = rowsHeader;
  this.datasList = datasList2;
 }

 public String[] getHeaders() {
  return headers;
 }

 public void setHeaders(String[] headers) {
  this.headers = headers;
 }

 public String[] getRowHeaders() {
  return rowHeaders;
 }

 public void setRowHeaders(String[] rowHeaders) {
  this.rowHeaders = rowHeaders;
 }

 public List<String[]> getDatasList() {
  return datasList;
 }

 public void setDatasList(List<String[]> datasList) {
  this.datasList = datasList;
 }

 public Set<String> getConStrctSet() {
  return conStrctSet;
 }

 public void setConStrctSet(Set<String> conStrctSet) {
  this.conStrctSet = conStrctSet;
 }
}

 

jquery对象和javascript的dom对象转换

Jquery框架为jquery对象定义了独立使用的方法和属性,它没法直接调用dom对象的方法,dom对象也没法直接调用jquery对象的方法和属性。

Jquery对象和dom对象是能够相互转换的,由于他们所操做的对象都是dom元素,只不过jquery对象包含了多个dom元素,而dom对象自己就是一个dom元素,简单地说,jquery对象是dom元素的数组,称为类数组,而dom对象就是单个的dom元素。

1.把jquery对象转换成dom对象

(1)借助数组下标来读取jquery对象集合中的某个dom元素对象。

Var $li = $(‘li’);//jquery对象

Var li = $li[0];//dom对象

(2)借助jquery对象的get()方法

Var $li = $(‘li’);//jquery对象

Var li = $li.get(0);//dom对象

2.dom对象转换为jquery对象

Var li = document.getElementsByTagName(‘div’);

Var $li = $(li[o]);//把第一个div元素封装为jquery对象

Var li = document.getElementsByTagName(‘div’);

Var $li = $(li);//把因此的div元素封装为jquery对象

Load事件必须等到网页中因此内容所有加载完毕后才执行。

当网页中内容不少时,load事件就会延迟

Jqueryready事件是在dom结构绘制完毕后就执行,也就是说它在外部文件加载以前就执行了,ready事件先于load事件。

Load事件只能被编写一次,可是ready事件能够在同一个文档中屡次定义。

<html>

<head>

</head>

<body>

<div class="panel"/>wlecome</div>

<script type="text/javascript" src="jquery-1.5.1.min.js"></script>

<script type="text/javascript">

$(document).ready(function(){

$('<input type="button" value="click me" /><input type="button" value="triggle click me" /><input type="button" value="detach handler" /><input type="button" value="show/hide text" />').appendTo($('body'));

$('input[type="button"]')

.eq(0).click(function(){

$(this).val("红色").addClass('red'); }).end().eq(1).click(function(){

alert(1);

}).end().eq(2).click(function(){

alert(2);

}).end().eq(3).toggle(function(){

$('.panel').hide('slow');

},function(){

$('.panel').show('slow');

}

);

});

</script>

</body>

<html/>

 

javascript建立新节点方法

<tbody>
    <tr>
        <td width="20"><input type="checkbox" /></td>
        <td>第二行</td>
    </tr>
</tbody>
建立tbody中的内容
var tr = document.createElement('tr');
var ck_td = document.createElement('td');
var txt_td = document.createElement('td');
var ck = document.createElement('input');
var todo = document.createTextNode('第二行');
ck_td.setAttribute('width','20');
ck.setAttribute('type','checkbox');
ck_td.appendChild(ck);
txt_td.appendChild(todo);
tr.appendChild(ck_td);
tr.appendChild(txt_td);
document.getElementsByTagName('tbody')[0].appendChild(tr);


其余方法
tr.parentNode;//获得tr的父节点
        tr.removeChild(td);//删除tr节点的子节点td
        tr.nextElementSibling;//tr的下一个同级元素
            tr.nextSibling;//tr的下一个同级元素//

javascript面向对象中继承的几种方式

<html>
    <head>
    
    </head>
    <body>
        <script type="text/javascript">
        //继承之对象冒充方式,能够继承多个父类
            function user(name){
                this.name = name;
                this.sayname = function(){
                    alert(this.name);
                }
            }
            function student(name,score){
                //user(name);
                this.temp = user;
                this.temp(name);
                delete this.temp;
                this.score = score;
                this.sayscore = function(){
                    alert(this.score);
                }
            }
            var s = new student('tom',33);
            //s.sayname();
            //s.sayscore();
            
            //用call()函数实现继承
            function user(name){
                this.name = name;
                this.sayname = function(){
                    alert(this.name);
                }
            }
            function student(name,score){
                user.call(this,name);
                this.score = score;
                this.sayscore = function(){
                    alert(this.score);
                }
            }
            var s = new student('tom',33);
            //s.sayname();
            //s.sayscore();
            
            //用apply()函数实现继承
            function user(name){
                this.name = name;
                this.sayname = function(){
                    alert(this.name);
                }
            }
            function student(name,score){
                user.apply(this,[name]);
                this.score = score;
                this.sayscore = function(){
                    alert(this.score);
                }
            }
            var s = new student('tom',33);
            //s.sayname();
            //s.sayscore();
            
            
            //原型链方式实现继承
            //1.将父类中所用经过prototype设置的属性或方法放到子类中
            //2.并覆盖子类中因此的prototype的设置
            //3.因此子类本身的因此的prototype的设置要放在继承父类的下面
            //4.缺点是不支持多个继承,构造函数不能有参数
            
            function user(){}            
            user.prototype.name = '';
            user.prototype.say = function(){
                alert(this.name);
            }
            function student(){}
                student.prototype =new user();
                student.prototype.age = 0;
                student.prototype.show = function(){
                    alert(this.age);
                }
            
            var s = new student();
            s.name = 'tom';
            s.age = 44;
            //s.say();
            //s.show();
            //alert(s instanceof user);
            //alert(s instanceof student);
            
            
            //混合模式实现继承
            function user(name){
                this.name = name;
            }
            user.prototype.sayname = function(){
                alert(this.name);
            }
            function student(name){
                user.call(this.name);
            }
            //将user中全部经过prototype设置的方法放到student中
            student.prototype = new user();
            student.prototype.age = 0;
            student.prototype.sayage = function(){
                alert(this.age);
            }
            var s = new student();
            s.name = 'tom';
            s.age = 44;
            s.sayname();
            s.sayage();
            alert(s instanceof user);
            alert(s instanceof student);
            
        </script>
    </body>
<html/>
 

javascript模拟java中的StringBuffer链接字符串

function stringbuffer(){
                this.array = new Array();
            }
            stringbuffer.prototype.append = function(s){
                this.array.push(s);
            }
            stringbuffer.prototype.tostring = function(){
                return this.array.join('-');
            }
            var sb = new stringbuffer();
            sb.append('tom');
            sb.append('lily');
            alert( sb.tostring());
 

javascript面向对象建立对象的五种方法

<html>
    <head>
    
    </head>
    <body>
        <script type="text/javascript">
        //工厂模式建立对象,缺点是不能知道对象的类型
            function createUser(name,age){
                var o = {};
                o.name=name;
                o.age=age;
                o.say=function(){
                    alert(this.name);
                }
                return o;
            }
            //user1 = createUser("tom",11);
            //alert(user1.name);
            //user2 = createUser("tom1",111);
            //user2.say();
            
            
            //构造函数建立对象。缺点是对象中的方法须要写在构造函数外面,有可能写不少方法
            
            function user(name,age){
                this.name=name;
                this.age = age;
                this.say = say;
            }
            function say(){
                alert(this.name);
            }
            //var user1 = new user("tom",44);
            //var user2 = new user("lily",66);
            //alert(user1.name);
            //user2.say();
            //alert(user1 instanceof user);
            
            
            //原型模式,缺点是不能有构造函数
            
            function user(){}
            user.prototype.name='';
            user.prototype.age = 0;
            user.prototype.address = [];
            user.prototype.say = function(){
                alert(this.name);
            }
            var user1 = new user();
            user1.name = 'tom';
            user1.age = 11;
            user1.address = [1,2];
            //user1.address.push("1","2");
            var user2 = new user();
            user2.name = 'lily';
            user2.age = 22;
            user2.address = [3,4];
            //user2.address.push("3","4");
            //alert(user1.name);
            //alert(user1.age);
            //alert(user1.address);
            //user1.say();
            //alert(user2.name);
            //alert(user2.age);
            //alert(user2.address);
            //user2.say();
            
            //构造函数+原型模式,构造方法构造属性,原型模式构造方法
            function user(name,age){
                this.name = name;
                this.age = age;
                this.address = ['1','2'];
            }
            user.prototype.say = function(){
                alert(this.name);
            }
            var user1 = new user('tom',11);
            var user2 = new user('lily',22);
            user1.address.push('a','b');
            user2.address = ['cc','dd'];
            alert(user1.address);
            alert(user2.address);
            
//动态原型模式
            function user(name,age){
                this.name = name;
                this.age = age;
                this.address = ['1','2'];
                if(typeof this.say != 'function'){
                    user.prototype.say = function(){
                alert(this.name);
            }
                }
            }
            var user1 = new user('tom',11);
            var user2 = new user('lily',22);
            alert(user1.say==user2.say);

        </script>
    </body>
<html/>
 

ajax下拉框联动

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'car.jsp' starting page</title>
  </head>
  
  <body>
    <select id="car" οnchange="sendAjax()">
        <option>-- 请选择汽车品牌 --</option>
        <option value="bmw">宝马</option>
        <option value="audi">奥迪</option>
        <option value="benz">奔驰</option>
    </select>
    <select id="type" οnchange="sendType()">
        <option>-- 请选择系列 --</option>
    </select>
    <script type="text/javascript">
            var xmlHttp;
        
        /*建立XMLHttpRequest对象*/
        function createXMLHttpRequest() {
            if(window.ActiveXObject) {
                  //IE
                  xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
              } else {
                  //chrome firefox opera 
                  xmlHttp = new XMLHttpRequest();
              }
        }
        
        function sendAjax(){
            createXMLHttpRequest();
            
            var name = document.getElementById("car").value;
            xmlHttp.onreadystatechange = callback;//回调函数
            
            
            xmlHttp.open("GET","car.jspx?name="+name,true);
            xmlHttp.send();
            
        }
        
        function callback() {
            if(xmlHttp.readyState == 4) {
                if(xmlHttp.status == 200) {
                    var xml = xmlHttp.responseXML;
                    
                    var types = xml.getElementsByTagName("recode");
                    document.getElementById("type").options.length = 1;
                    for(var i = 0;i < types.length;i++) {
                        
                        //alert(types[i].childNodes[0].nodeValue);
                        var myOption = new Option(types[i].childNodes[0].nodeValue,types[i].childNodes[0].nodeValue);
                        document.getElementById("type").options.add(myOption);
                        
                    }
                    
                } else {
                    alert("Ajax Error1!");
                }
            }
        }
        function sendType(){
                createXMLHttpRequest();
            
            var name = document.getElementById("type").value;
            xmlHttp.onreadystatechange = callback2;//回调函数
            
            
            xmlHttp.open("GET","ajax.jspx?name="+name,true);
            xmlHttp.send();
        }
            function callback2() {
            if(xmlHttp.readyState == 4) {
                if(xmlHttp.status == 200) {
                    var result = xmlHttp.responseText;
                    
                     alert(result);
                        
                    }
                    
                } else {
                    alert("Ajax Error2!");
                }
            }
        
    </script>
  </body>
</html>
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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


public class CarServlet extends HttpServlet {

    
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //DB取出数据
        Map<String, List<String>> data = new HashMap<String, List<String>>();
        List<String> bmwList = new ArrayList<String>();
        bmwList.add("521");
        bmwList.add("621");
        bmwList.add("721");
        bmwList.add("821");
        bmwList.add("X6");
        
        
        List<String> audiList = new ArrayList<String>();
        audiList.add("A1");
        audiList.add("A2");
        audiList.add("A3");
        audiList.add("A4");
        audiList.add("A5");
        audiList.add("A6");
        audiList.add("A8");
        
        List<String> benzList = new ArrayList<String>();
        benzList.add("B1");
        benzList.add("B2");
        benzList.add("B3");
        benzList.add("B4");
        benzList.add("B5");
        
        data.put("bmw", bmwList);
        data.put("audi", audiList);
        data.put("benz", benzList);
        //----------------------------------------------------------
        
        
        
        String name = request.getParameter("name");
        
        List<String> dataList = data.get(name);
        
        
        response.setContentType("text/xml;charset=UTF-8");
        PrintWriter out = response.getWriter();
        
        out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        out.print("<data>");
        for(String str : dataList) {
            out.print("<recode>"+str+"</recode>");
        }
        out.print("</data>");
        
        out.flush();
        out.close();
        
    }


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

}



import java.io.IOException;
import java.io.PrintWriter;

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

public class AjaxServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        
        
        System.out.println("method:" + request.getMethod());
        String name = request.getParameter("name");
        System.out.println("Hello! " + name);
        
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
    /*    if("tom".equals(name)) {
            out.print("error");
        } else {
            out.print("ok");
        }*/
        
        out.print(name);
        out.flush();
        out.close();
    }
    
}
 

ajax笔记1

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    
    <title>My JSP 'index.jsp' starting page</title>
  </head>
  
  <body>
  
      <input type="text" id="name" οnblur="sendAjax()"/>
      <img src="img/ajax.gif" style="display:none" id="loading"/>
      <span id="result"></span>
      <br/>
      <!--  
      <input type="button" value="Send Ajax" οnclick="sendAjax()"/>
      -->
  
      <script type="text/javascript">
      
      var xmlHttp;
          
          /*建立XMLHttpRequest对象*/
          function createXMLHttpRequest() {
              if(window.ActiveXObject) {
                    //IE
                              xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
                          } else {
                              //chrome firefox opera 
                              xmlHttp = new XMLHttpRequest();
                          }
          }
          
          function sendAjax(){
              createXMLHttpRequest();
              
              var name = document.getElementById("name").value;
              
              //post
              xmlHttp.open("POST", "ajax.jspx", true);
              xmlHttp.onreadystatechange = callback;             
              xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
              xmlHttp.send("name="+name);
              
              //get
              //xmlHttp.open("GET","ajax.jspx?name="+name,true);
              //xmlHttp.onreadystatechange = callback;
              //xmlHttp.send();
              
          }
          
          function callback() {
              if(xmlHttp.readyState == 4) {//服务器响应返回
                  
                  document.getElementById("loading").style.display = "none";
                  
                  if(xmlHttp.status == 200) {//响应正确
                      var result = xmlHttp.responseText;
                  
                      if(result == "ok") {
                          document.getElementById("result").innerHTML = "√";
                      } else {
                          document.getElementById("result").innerHTML = "用户名已占用";
                      }
                  } else {
                      alert("Ajax Error!");
                  }
              } else {
                  //进度条
              
                  document.getElementById("loading").style.display = "inline";
              }
          }
      
          
 
          
      </script>
  </body>
</html>
 

javascrip对象方法和数组方法

<html>
 <head>
  <script type="text/javascript">
var user = {name:'tom',age:'22'};
alert(user.name);
alert(user["name"]);
delete user.name;//删除属性
alert("name" in user);//判断属性是否在对象中

  </script>
 </head>
 
</html>
 

javascript闭包

<html>
 <head>
  <script type="text/javascript">
  function save(n1,n2){
     function fn(){
     return n1+n2;
    }
    return fn();
   }
   
   alert(save(2,3));
  //闭包第一种
   function test(){
    var num = 10;
    function inner(){
     alert(num);
    }
    inner();
   }
   //test();
   //闭包第二种
   function add(n1,n2){
    return function(){
     return n1+n2;
    }
   }
  //alert(add(2,3)());
  </script>
 </head>
 
</html>
 

jdbc的增删改查的方法

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class JdbcTest {

 public static void main(String[] args) throws ClassNotFoundException,SQLException {
  
  //1.加载数据库驱动(提供一个jdbc的数据库驱动的名称)
  Class.forName("com.mysql.jdbc.Driver");
  
  //2.获取数据库链接
  String url = "jdbc:mysql:///gooddb";
  Connection conn = DriverManager.getConnection(url, "root", "root");
  
  //3.获取Statment对象(该对象用于对数据库进行CRUD操做)
  Statement stat = conn.createStatement();
  
  //4.执行SQL语句
  //String sql = "INSERT INTO t_class(classname) VALUES('java07')";
  String sql = "UPDATE t_class SET classname = 'sql01' WHERE id = 2";
  //executeUpdate()方法用于执行insert、update、delete语句,该方法返回影响数据库的行数
  int rows = stat.executeUpdate(sql);
  if(rows > 0) {
   System.out.println("操做成功!");
  }
  
  //5.释放链接
  stat.close();
  conn.close();
  
  
 }
}

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class SelectTest {

 public static void main(String[] args) {
  
  Connection conn = null;
  Statement stat = null;
  ResultSet rs = null;
  try {
   Class.forName("com.mysql.jdbc.Driver");
   
   conn = DriverManager.getConnection("jdbc:mysql:///gooddb","root","root");
   
   stat = conn.createStatement();
   
   String sql = "select id,classname from t_class";
   //获取结果集对象
   rs = stat.executeQuery(sql);
   
   while(rs.next()) {
    //int id = rs.getInt("id");
    int id = rs.getInt(1);
    //String name = rs.getString("classname");
    String name = rs.getString(2);
    
    System.out.println("id:" + id + "\tclassname:" + name);
   }
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  } catch (SQLException e) {
   e.printStackTrace();
  } finally {
   //释放链接
   try {
    if(rs != null) {
     rs.close();
    }
   } catch (SQLException e) {
    e.printStackTrace();
   } finally {
    try {
     if(stat != null) {
      stat.close();
     }
     
    } catch (SQLException e) {
     e.printStackTrace();
    } finally {
     try {
      if(conn != null) {
       conn.close();
      }
     } catch (SQLException e) {
      e.printStackTrace();
     }
    }
   }
  }
  
  
 }
}

 

计算两个时间段相隔多少天的java方法

package com.tCalendar.d;

/*
 * java.util.Calendar 类学习
 */


import java.text.SimpleDateFormat;

/**
 *
 * @author Icer
 */
public class TCalendar {
    
    private static SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMdd");
    private String dayInfo[][];
    private int dayCount;//间隔天数

    
    public static void main(String[] args) {
        String startDate = "20120101";
        String endDate = "20120102";
        TCalendar tCalendar = new TCalendar();
        tCalendar.initDayInfo(startDate, endDate);
        System.out.println("天数: " + tCalendar.getDayCount());
    }
    
    public  void initDayInfo(String start,String end)
    {
     //初始化日期信息
     java.util.Calendar cal1=java.util.Calendar.getInstance();
     java.util.Calendar cal2=java.util.Calendar.getInstance();
     java.util.Calendar cal3=java.util.Calendar.getInstance();
     int year,month,day;
     int i=0;
     year=Integer.parseInt(start.substring(0,4));
     month=Integer.parseInt(start.substring(4,6));
     day=Integer.parseInt(start.substring(6,8));
     cal1.set(year, month-1, day);
     cal3.set(year, month-1, day);
     year=Integer.parseInt(end.substring(0,4));
     month=Integer.parseInt(end.substring(4,6));
     day=Integer.parseInt(end.substring(6,8));
     cal2.set(year, month-1, day);
     while(!cal2.before(cal3))
     { 
      i++;
      cal3.add(java.util.Calendar.DAY_OF_MONTH, 1);//日期时间+1
     }
     //每日数据列表
     dayInfo=new String[i+1][3];
     i=0;
     while(!cal2.before(cal1))
     { 
                System.out.println("==" + cal1.getTime());
      dayInfo[i][0]=sDateFormat.format(cal1.getTime());
      i++;
      cal1.add(java.util.Calendar.DAY_OF_MONTH, 1);
     }
     
     this.dayCount=i;
     for (int j=0;j<i;j++)
     {
      this.dayInfo[j][1]="0";
      this.dayInfo[j][2]="0";
     }
     
    }
    public int getDayCount() {
        return dayCount;
    }

    public void setDayCount(int dayCount) {
        this.dayCount = dayCount;
    }

    public String[][] getDayInfo() {
        return dayInfo;
    }

    public void setDayInfo(String[][] dayInfo) {
        this.dayInfo = dayInfo;
    }
}

java反射经常使用方法

package com.fanshe.obj;

import java.lang.reflect.*;   
import java.io.IOException;   
/**  
*获取指定类的构造器相关信息  
*/   
public class ConstructorTest    
{   
 private int i;   
 private double j;   
 //默认的构造器   
 public ConstructorTest(){   
 }   
 //重载的构造器   
 public ConstructorTest(int i,double j)throws IOException{   
  this.i=i;   
  this.j=j;   
 }   
 public static void main(String[] args) throws Exception   
 {   
  //获得本类的类对象   
  Class<?> cls=Class.forName("com.fanshe.obj.ConstructorTest");   
  //取得全部在本类声明的构造器   
  Constructor<?> []cs=cls.getDeclaredConstructors();   
  //遍历   
  System.out.println("----------------");
  for(Constructor<?> c:cs){   
   //构造器名称   
   System.out.println("构造器名="+c.getName());   
   //构造器声明所在的类   
   System.out.println("其声明的类="+c.getDeclaringClass());   
   //取得参数的类型集合   
   Class<?> []ps=c.getParameterTypes();   
   //遍历参数类型   
   for(int i=0;i<ps.length;i++){   
    System.out.println("参数类型"+i+"="+ps[i]);   
   }   
   //取得异常的类型集合   
   Class<?> []es=c.getExceptionTypes();   
   //遍历异常类型   
   for(int j=0;j<es.length;j++){   
    System.out.println("异常类型"+j+"="+es[j]);   
   }   
   //结束一层循环标志   
   System.out.println("-----------");   
  }   
 }   
}   

 

package com.fanshe.obj;

import java.lang.reflect.*;   
/**  
*经过反射创新类的新对象  
*/   
class CreateNewObj    
{   
 //显式默认的构造器   
 public CreateNewObj(){   
 }   
 //重载构造器   
 public CreateNewObj(int a,int b){   
  System.out.println("a= "+a+" b="+b);   
 }   
  
 public static void main(String[] args) throws Exception   
 {   
  //获得本类的类对象   
  Class<?> c=Class.forName("com.fanshe.obj.CreateNewObj");   
  //声明构造器的参数类型集合   
  Class<?> []paramTypes=new Class[2];   
  //都为int型   
  paramTypes[0]=Integer.TYPE;   
  paramTypes[1]=Integer.TYPE;   
        //根据参数类型决定获得哪一个构造器   
  Constructor<?> cs=c.getConstructor(paramTypes);   
  //声明要传入的参数集合   
  Object []argList=new Object[2];   
  //传入37和43   
  argList[0]=new Integer(37);   
  argList[1]=new Integer(43);   
  //根据符合上述参数类型的构造器来建立新的对象   
  Object rtnObj=cs.newInstance(argList);   
 }   
}  

 

package com.fanshe.obj;

import java.lang.reflect.*;   
/**  
*获取指定类的字段相关信息  
*/   
class FieldTest    
{   
 //字段1   
 private double d;   
 //字段2   
 public static final int i=37;   
 //字段3   
 String str="fieldstest";   
 public static void main(String[] args) throws Exception   
 {   
  //获取本类的类对象   
  Class<?> c=Class.forName("com.fanshe.obj.FieldTest");   
  //获取全部声明的的字段,getFields()包括继承来的字段   
  Field []fs=c.getDeclaredFields();   
  //遍历   
  for(int i=0;i<fs.length;i++){   
   Field f=fs[i];   
   //字段名   
   System.out.println("字段名"+(i+1)+"="+f.getName());   
   //字段声明所在的类   
   System.out.println("该字段所在的类为:"+f.getDeclaringClass());   
   //字段的类型   
   System.out.println("字段"+(i+1)+"的类型:"+f.getType());   
   //查看修饰符   
   int mod=f.getModifiers();   
   //为0就是默认的包类型   
   if(mod==0){   
                System.out.println("该字段的修饰符为:默认包修饰符");   
   }else{   
    //不然就是相应的类型   
    System.out.println("该字段的修饰符为:"+Modifier.toString(mod));   
   }   
   System.out.println("---结束第"+(i+1)+"循环---");   
  }   
 }   
}   

package com.fanshe.obj;

import java.lang.reflect.*;   
/**  
*获取指定类的方法相关信息  
*/   
class InformationTest    
{   
 public static void main(String[] args) throws Exception   
 {   
  //获得String类对象   
  Class<?> cls=Class.forName("java.lang.String");   
  //获得全部的方法,包括从父类继承过来的方法   
  Method []methList=cls.getMethods();   
  //下面是获得的是String类自己声明的方法   
  //Method []methList=cls.getDeclaredMethods();   
  //遍历全部的方法   
  for(Method m:methList){   
   //方法名   
   System.out.println("方法名="+m.getName());   
   //方法声明所在的类   
   System.out.println("声明的类="+m.getDeclaringClass());   
   //获取全部参数类型的集体   
   Class<?> []paramTypes=m.getParameterTypes();   
   //遍历参数类型   
   for(int i=0;i<paramTypes.length;i++){   
    System.out.println("参数 "+i+" = "+paramTypes[i]);   
   }   
   //获取全部异常的类型   
   Class<?> []excepTypes=m.getExceptionTypes();   
   //遍历异常类型   
   for(int j=0;j<excepTypes.length;j++){   
    System.out.println("异常 "+j+" = "+excepTypes[j]);   
   }   
   //方法的返回类型   
   System.out.println("返回类型 ="+m.getReturnType());   
   //结束一层循环标志   
   System.out.println("---------");   
  }   
 }   
}  

 

package com.fanshe.obj;

import java.lang.reflect.*;   
/**  
*经过反射改变字段的值  
*/   
class ModifyField    
{   
 //声明一个字段   
 public double d;   
 public static void main(String[] args) throws Exception   
 {   
  //获得类的类对象   
  Class<?> c=Class.forName("com.fanshe.obj.ModifyField");   
  //根据字段名获得字段对象   
  Field f=c.getField("d");   
  //建立类的实例   
  ModifyField mf=new ModifyField();   
  //打印修改前字段的值   
  System.out.println("修改 "+f.getName()+" 前的值为:"+mf.d);   
  //修改d的值为12.34   
  f.setDouble(mf,12.34);   
  //打印修改后的值   
  System.out.println("修改 "+f.getName()+" 后的值为:"+mf.d);   
  
 }   
}  

 

package com.fanshe.obj;

import java.lang.reflect.*;   
/**  
*经过反射执行类的方法  
*/   
class PerformMethod    
{   
 //声明一个简单的方法,用于测试   
 public int add(int a,int b){   
  return a+b;   
 }   
 public static void main(String[] args)throws Exception   
 {   
  //获取本类的类对象   
  Class<?> c=Class.forName("com.fanshe.obj.PerformMethod");   
  /**  
  *声明add方法参数类型的集合  
  *共有两个参数,都为Integer.TYPE  
  */   
  Class<?> []paramTypes=new Class[2];   
  paramTypes[0]=Integer.TYPE;   
  paramTypes[1]=Integer.TYPE;   
  //根据方法名和参数类型集合获得方法   
  Method method=c.getMethod("add",paramTypes);   
  //声明类的实例   
  PerformMethod pm=new PerformMethod();   
  //传入参数的集合   
  Object []argList=new Object[2];   
  //传入37和43   
  argList[0]=new Integer(37);   
  argList[1]=new Integer(43);   
  //执行后的返回值   
  Object returnObj=method.invoke(pm,argList);   
  //类型转换下   
  Integer returnVal=(Integer)returnObj;   
  //打印结果   
  System.out.println("方法执行结果为:"+returnVal.intValue());   
 }   
}  

 

package com.fanshe.obj;

import java.lang.reflect.*;   
/**  
*经过反射来操做数组  
*/   
class UserArray    
{   
 public static void main(String[] args) throws Exception   
 {   
  //获得String类的类对象   
  Class<?> c=Class.forName("java.lang.String");   
  //经过Array类的反射建立一个含有10个元素的String类型的数组   
  Object arr=Array.newInstance(c,10);   
  //为数组第5个位置元素赋一个值   
  Array.set(arr,5,"第5个位置元素");   
  //取得第5个位置元素的值   
  String s=(String)Array.get(arr,5);   
  //打印这个元素的值   
  System.out.println("值为:"+s);   
 }   
}  

 

package com.fanshe.obj;

import java.lang.reflect.*;   
/**  
*经过反射建立和使用更复杂的数组  
*/   
class UserArrayComplex   
{   
 public static void main(String[] args) throws Exception   
 {   
  //声明数组的维数为5X10X15   
  int dims[]=new int []{5,10,15};   
  //建立该类型的数组,元素的类型为Integer   
  Object arr=Array.newInstance(Integer.TYPE,dims);   
  //获得第3个10X15的二维数组   
  Object arrObj=Array.get(arr,3);   
  //Class c=arrObj.getClass().getComponentType();   
  //System.out.println(c);   
  //获得第2维中的第2个15位长度的数组   
  arrObj=Array.get(arrObj,5);   
        //而后设置该数组里第10个元素的值为37   
  Array.set(arrObj,10,37);   
  //再将数组还原   
  int [][][]arrCast=(int [][][])arr;   
  //打印刚刚那个值   
  System.out.println(arrCast[3][5][10]);   
     
 }   
}  

 

设计模式之门面模式

门面模式是对象的结构模式,外部与一个子系统的通讯必须经过一个统一的门面对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。
使用门面模式还有一个附带的好处,就是可以有选择性地暴露方法。一个模块中定义的方法能够分红两部分,一部分是给子系统外部使用的,一部分是子系统内部模块之间相互调用时使用的。有了Facade类,那么用于子系统内部模块之间相互调用的方法就不用暴露给子系统外部了。
public interface ServiceA {
 void methodA() ;
}

public class ServiceAImpl implements ServiceA{

 @Override
 public void methodA() {
  System.out.println("这是服务A");  
 }
}


public interface ServiceB {
 void methodB() ;
}

public class ServiceBImpl implements ServiceB{

 @Override
 public void methodB() {
   System.out.println("这是服务B");  
 }
}



public interface ServiceC {
 void methodC() ;
}


public class ServiceCImpl implements ServiceC{

 @Override
 public void methodC() {
   System.out.println("这是服务C");  
 }
}


public class Facade {
  ServiceA sa;
     
     ServiceB sb;
     
     ServiceC sc;
     
     public Facade() {
         sa = new ServiceAImpl();
         sb = new ServiceBImpl();
         sc = new ServiceCImpl(); 
     }
     
     public void methodA() {
         sa.methodA();
         sb.methodB();
     }
     
     public void methodB() {
         sb.methodB();
         sc.methodC();
     }
     
     public void methodC() {
         sc.methodC();
         sa.methodA();
     }

}


测试类:

public class Test {
 public static void main(String[] args) {
     ServiceA sa = new ServiceAImpl();
     ServiceB sb = new ServiceBImpl();       
        sa.methodA();
        sb.methodB();       
        System.out.println("========");
        //facade
        Facade facade = new Facade();
        facade.methodA();
        facade.methodB();
        facade.methodC();
    }

}

推荐免费下载430套大型商业源码

下载地址:http://www.hur.cn/tg/linkin.asp?linkid=200978

PB-商业源码
  金科信进销存软件源码(81M)
  制造业管理系统源码(257M)
  PB连锁药店GSP源码(136M)
  创某医院系统源码(813M)
  人力资源管理系统源码(182M)
  浪某财务系统源码(131M)
  医院系统源码(58M)
  医院管理软件门诊挂号收费系统源码(83M)
  医疗保险管理系统源码(191M)
  拓某连锁专卖宝典源码(90M)
  普某ERP系统源码(300M)
  科某企业ERP源码(154M)
  重庆运通商业连锁系统源码(293M)
  供电局MIS管理信息系统源码(196M)
  社区信息管理系统源码(122M)
  暂住人口管理系统4.0(网络版)源码(25M)
  高某医院系统源码(200M)
  思某商业管理系统源码(40M)
  电子厂用小型ERP系统源码(51M)
  点某财务软件源码(121M)
  和某ERP系统源码(73M)
  医院管理系统源码(956M)
  河南医院信息系统源码(400M)
  瑞某酒店管理系统源码(48M)
  飞某商业管理系统源码(87M)
  PowerBuilder 8.0 自定义报表系统(5M)
  动态报表系统(10M)
  致某动态报表模块源码(5M)
  小型商业进销存系统(带POS)(34M)
  大型酒店管理最新版本PB8(60M)
  中小超市POS综合管理系统(142M)
  检查科室报告单管理软件(17M)
  商某5.0 POS系统(20M)
  威某酒店管理系统(365M)
  鞋业ERP系统(繁体)(160M)
  新某大财务系统(301M)
  医生工做站源码(30M)
  宏声人力资源管理系统(41M)
  医疗保险系统(37M)
  医药卫生综合管理系统(54M)
  MIS系统源代码pb9(40M)
  PB影碟出租管理系统8.03(14M)
  pb-oracle通用开发框架(27M)
  PB编写的电子地图源码(5M)
  大众医院门诊收费系统(28M)
  pb洗浴管理系统(9M)
  餐饮管理程序源代码(14M)
  仓库管理系统源码(6M)
  查询打印数据窗口共享排序定制基类(5M)
  长江科学院合同成果管理(27M)
  工程造价系统源码(17M)
  国泰商业管理系统MIS(135M)
  华泰印刷源码(122M)
  检查科室报告单管理软件(17M)
  金华医院门诊挂号收费系统PB(80M)
  酒店管理系统(网络版)(73M)
  某配件公司生产管理系统(154M)
  某企业财务管理系统(125M)
  瑞通hms(245M)
  瑞通酒店管理系统V8.0网络版(102M)
  商场管理系统源代码pb(15M)
  商品进销存管理系统(pb)(9M)
  天河进销存POS系统(211M)
  物流程序源码(53M)
  小型商业进销存系统(带POS)(32M)
  鞋业ERP源码(153M)
  旭日2000企业管理系统(65M)
  血库的软件用pb作(6M)
  药品管理(27M)
  医疗保险系统pb(258M)
  普阳Erp源码(61M)
  科研管理系统源码(15M)
  酒店管理系统(59M)

Delphi-商业源码
  美容院管理系统源码(70M)
  MRPII制造资源计划系统源码(147M)
  ERP企业管理系统源码(74M)
  福某制衣MRP管理系统源码(43M)
  胜某进销存系统源码(88M)
  立某酒店、餐饮、洗浴、休闲管理系统源码(55M)
  实某聊天系统 v3.0源码(71M)
  社保管理系统源码(22M)
  商业通医药连锁经营管理系统源码(40M)
  商业管理系统源码(135M)
  日某餐饮系统源码(173M)
  企业进销存系统源码(41M)
  贸易网站登录器源码(60M)
  遵某的视频会议系统代码源码(26M)
  贸易管理系统源码(65M)
  酒店管理系统源码(106M)
  汽车租赁信息咨询系统源码(62M)
  牙科诊所管理系统源码(31M)
  制衣MRPII系统源码(65M)
  中国眼科病历系统源码(103M)
  远程控制源码(20M)
  医药连锁源码源码(55M)
  语音故障报修系统(须要TW8VID语音卡)源码(18M)
  行业应急系统源码(23M)
  销售管理系统源码(24M)
  洗浴中心管理系统源码(20M)
  五金管理信息系统源码(18M)
  网络教室系统源码(网络版)源码(58M)
  天某ERP系统源码(281M)
  医院病案管理系统源码(26M)
  VOD点歌系统源码(59M)
  国外的财务软件源码(126M)
  旅游公司信息系统源码(43M)
  人力资源管理系统源码(24M)
  POS超市管理系统源码(60M)
  POS系统源码(43M)
  医院收费与信息管理系统源码(122M)
  安某销售系统源码(10M)
  GIS系统—有线电视网络设备管理系统源码(30M)
  ICQ(客服服务器)源码(55M)
  办公自动化系统源代码源码(27M)
  仓储物流信息管理系统源码(137M)
  传奇游戏源码(178M)
  电能表载波抄表软源码(44M)
  电子试卷生成系统源码(30M)
  美容院管理系统源码(16M)
  泰某工程管理软件源码(40M)
  环某美容美发管理系统源码(23M)
  机房收费管理源码(78M)
  计划生育管理系统源码(21M)
  驾驶员考试源码(40M)
  金某验布系统源码(82M)
  进销存系统源码(43M)
  超市库存管理系统源码(23M)
  中移动大客户管理系统(7M)
  思微pos系统(48M)
  泰达图书馆工程管理软件源码(24M)
  Delphi编写的企业进销存系统源代码(11M)
  ENO企业人事信息管理系统(6M)
  NiceERP企业系统(42M)
  ST进销存源码(12M)
  宾馆软件源码(12M)
  采购应用系统源码(11M)
  超市管理系统源代码(7M)
  很是方便的物业管理系统(7M)
  钢铁进销存源码(12M)
  港汇客户管理系统源码(13M)
  海信商业管理系统完整源码版(99M)
  进销存ForD7(8M)
  牧羊人服饰系统 (ADO+SQL)(6M)
  实达企业在线EOL三层系统Delphi源码(11M)
  手机营销系统源码(10M)
  通用的进销存系统源码(10M)
  通用人力资源系统源码(7M)
  完整的市一级工资管理程序源码(142M)
  西恩软件机房管理源码(26M)
  信息管理程序源码(14M)
  制衣MRP管理系统源码(45M)
  胜天财务进销存2003源码(82M)
  AL源码(10M)
  DAGL 档案管理程序 v1.0 (SQL Server)(22M)
  delphi BookMIS 教材管理系统(7M)
  delphi_宏远VOD原代码(45M)
  大型企业ERP管理系统(84M)
  大型企业邮件管理系统(7M)
  delphi_柯龙中草药进销存 v3.0(22M)
  delphi_企业管理Erp(64M)
  delphi_思微POS连锁超市管理系统(60M)
  delphi我的理财软件源码(7M)
  delphi名佳商务系统源码(74M)
  delphi万家福超市管理系统(17M)
  delphi物流供应链管理系统(5M)
  delphi医院管理系统(18M)
  delphi咏南进销存 两层(C_S)(8M)
  NDOA南都办公自动化系统(delphi)(8M)
  POS连锁超市管理系统 (商业代码)(60M)
  delphi灰鸽子vip1.2 版本(43M)
  地磅称量系统(7M)
  典当综合业务管理系统(10M)
  电子寻更源程序(20M)
  东莞和富有限公司进销存管理系统(33M)
  动感立体KTV VOD(18M)
  工资管理系统(53M)
  广电行业GIS系统(10M)
  华丝贸易国内销售管理系统(30M)
  火锅城管理系统1.0版(10M)
  机动车驾驶员无纸化理论考试系统(38M)
  局域网即时通讯系统(52M)
  客房管理系统(网络版)(100M)
  客户关系管理系统(CRM)(11M)
  力信消费管理系统2000(12M)
  龙邦进销存源码(16M)
  美容院管理系统修改版(ADO)(21M)
  某公司工资管理系统(17M)
  某企业ERP企业管理系统(32M)
  某通用进销存系统(20M)
  配件仓库管理(24M)
  企业管理Erp(商业源码)(64M)
  全球数码仓库仓储管理信息系统(110M)
  思雷特(sunnet)物业管理信息系统(232M)
  台湾公司作的一个ERP管理系统(235M)
  万佳圆宾馆桑拿洗浴管理系统(20M)
  网络营销专家(25M)
  维修管理工具(15M)
  五金材料商业进销存(23M)
  物业管理(22M)
  校园网多媒体自动播放系统(10M)
  新艺VOD系统(59M)
  眼镜行业财务进销存后台管理代码 V1.0v(72M)
  异洲酒店(餐饮)管理系统delphi源码(delphi+sql)(20M)
  P2P即时通信源码Delphi(46M)
  POS消费管理系统2000delhi源码(12M)
  大型超市销售连锁管理系统(16M)
  电子寻更源程序delphi(20M)
  远程控制DELPHI源代码(17M)
  高考网上招生省招办投档系统(11M)
  湖南佳某软件公司商业POS通系统delphi源码(98M)
  化工颜料生产管理源码(30M)
  科技计划信息管理系统delphi源码(22M)
  视频会议系统delphi源码(45M)
  某医院HIS管理系统delphi源码(86M)
  顺某指纹考勤管理系统delphi源码(64M)
  delphi超市管理系统源码(16M)

VB-商业源码
  新世某ERP5.0升级版源码(796M)
  MIS管理信息系統源码(583M)
  医药卫生管理系统源码(60M)
  制造业ERP系统源码(125M)
  专卖店POS系统源码(36M)
  售房管理系统源码(89M)
  用某u850源码(9M)
  易某点歌系统源码(18M)
  医院系统源码(202M)
  医药管理GSP源码(36M)
  新开某酒店系统源码(29M)
  网吧管理系统源码(15M)
  太平某信息管理系统源码(33M)
  金算某财务及企业管理软件源码(134M)
  教师住房管理系统源码(12M)
  惠某ERP系统源码(442M)
  报业广告发行管理系统源码(42M)
  宝某售饭系统源码(15M)
  新世某ERP5.0彻底版源码(399M)
  宛某书社图书管理系统源码(9M)
  VB+SQL开发银行模拟系统(167M)
  VB超巿管理系统(11M)
  材料目录软件(10M)
  进销存软件(13M)
  全球通商务管理系统——POS管理系统(另外一版本)(75M)
  四季青污水处理厂系统(62M)
  网吧管理系统服务器客户端源程序(另外一版本)(15M)
  住房公积金监管系统(46M)
  邮件管理与群发系统(30M)
  学生信息管理系统(5M)
  通用文档一体化档案管理系统(127M)
  升瑞售楼管理系统(60M)
  设计系统2000(报表设计与管理系统)(12M)
  人力资源管理系统(28M)
  网络营销软件(25M)
  某企业物资管理信息系统(14M)
  某计算机网络管理系统VB(74M)
  财务系统源码(70M)
  路桥收费系统VB(702M)
  大型企业内部管理系统(228M)
  伯乐人力资源管理系统2000(161M)
  北京市区绿化隔离地区信息系统2000(34M)
  学生信息管理系统v1.0(附源码)(5M)
  馨香物业管理糸统(13M)
  新版图书综合管理系统(6M)
  审核管理系统-完整版(35M)
  华成酒店管理系统(10M)
  大型商业ERP系统2-财务系统部分(65M)
  超市销售管理系统(5M)
  宾馆桑拿休闲中心管理系统(30M)
  宾馆客房管理系统(6M)
  vb酒店管理系统(10M)
  VB物流管理系统源码(11M)
  计划生育管理系统(56M)
  vb和Mapx开发的房屋测绘系统GIS商业源码(10M)
  乡镇供电所电费处理系统(14M)
  VB人事工资管理系统(27M)
  VB财务软件源码(19M)
 
VC-商业源码
  网络听诊管理监控系统源码(1540M)
  速某(c++)MRPII系统源码(320M)
  贸易网站登录器源码(60M)
  工厂自动化生产整合管理系统源码(233M)
  高速公路收费系统源码(44M)
  北京某大卖场公司自主开发首套linux平台Pos源码(245M)
  酒店餐饮管理系统(21M)
  伯克公司生产销售系统源码(14M)
  企业短信助理源代码(20M)
  一个超完整的医药管理系统源码(59M)
  综合人事管理系统源码(vc+sql2000)(18M)
  综合人事管理系统源码(vc+sql2000)(5M)
  Hotel酒店管理系统源码(4M)
  POS前台C++程序源码(7M)
  quakeIII 源码(26M)
  视频会议系统源码(50M)
  VC客房管理系统源码(10M)
  VC数字图像模式技术及工程应用源码(106M)
  串口编程调试及双机互联源码(44M)
  代码名称:Microsoft MS-DOS6.0 完整源代码(63M)
  家族信息管理系统源码(7M)
  酒店管理系统2003(8M)
  考勤管理系统源代码下载(9M)
  利用MFC开发的OpenGL开发包(27M)
  屏幕转换成AVI文件的程序源码(25M)
  赛克思书店销售管理系统源码(7M)
  数字图像处理源码(30M)
  数字图像获取、处理与分析源盘(42M)
  图形图象类代码(8M)
  用Visual C++开发GIS系统(16M)
  游戏编程精粹源码(36M)
  云台镜头控制系统源码(20M)
  智能安防报警系统源码(37M)
  Vc视频会议源代码压缩文件(314M)
  VC数字图像模式技术及工程应用(103M)
  vc医院门诊收费系统(5M)
  互联天下im(95M)
  某公司VC视频核心代码(35M)
  视频会议开发代码(259M)
  视频监控(55M)
  视音频代码(35M)
  用Visual C++开发GIS系统(15M)
  真正的速达源码(CB5可编译)(54M)
  IM企业即时通信软件源代码(18M)
  宾馆酒店管理系统源码(25M)
  可视电话软件源码(16M)
  商品采购管理系统vc源码(25M)
  网络视频会议系统vc源码(41M)

.NET-商业源码
  和某大型ERP系统源码(510M)
  商务管理教学源码(28M)
  C#写的网上汽修汽配管理系统(52M)
  企业公文管理信息系统(87M)
  教材管理中心(3M)
  商务之星(ASP.NET)(618M)
  物流系统Logistics(v1.0)(217M)
  若冰.net远程教育系统(18M)
  asp.net+c#的人事系统(2M)
  Coffice协同办公管理系统(C#)(176M)
  NET的bbs论坛源码(6M)
  OA办公自动化系统源码(21M)
  嘉惠药品进销存管理系统(vb.net)(55M)
  企业内部信息交流系统源码(9M)
  若冰企业商务平台.net(31M)
  数据结构动画演示系统(c#)DataStructure(8M)
  医院管理系统ASP.NET+MSSQL(9M)
  中铁五局Mis系统原型设计(9M)
  住房公积金管理中ASP.NET+MSSQL(5M)
  房地产信息网(c#.net+sql)(6M)
  net网上购书系统(11M)
  NET药品进销存系统(5M)
  net采购仓库核销管理系统(6M)
  net计算机基础考试系统(10M)
  net精品OA(91M)
  net客户关系管理系统(6M)
  net企业客户服务系统(5M)
  net企业销售管理信息系统(8M)
  net汽车销售公司ERP进销存系统(38M)
  net图书馆管理系统(11M)
  net学生寝室管理系统(12M)
  net真正的全动态报表(5M)
  net自定义报表(16M)
  vb.net 销售管理系统(5M)
  vbnet进销存系统源码(6M)
  多层架构的大型.NET OA 系统(16M)
  客户关系管理系统(8M)
  某公司CRM管理系统 net(29M)
  三甲医院管理系统HIS(C#版)(27M)
  局域网考试系统C#(9M)
  进出仓管理系统(17M)
  Asp.Net用友华表(V5.1)制做自定义报表(16M)
  Asp.net通用OA系统源代码(12M)
  C#酒店管理系统(20M)
  PowerOA办公自动化系统商业源码(15M)
  餐饮管理系统(C#源码)(32M)
  公司客户关系管理系统CRM ASP.NET源码(27M)
  机械制造业信息管理系统源码(21M)
  C#某橱柜销售企业ERP管理系统(16M)
  公司的业务管理系统(15M)
  商业进销管理系统(47M)
  公路运输管理系统asp.net(30M)
  汽车销售公司ERP进销存系统(39M)
  现代教务管理系统源码(25M)
  药店管理系统(33M)
  餐饮管理系统源码(10M)
  智能办公系统(14M)

JAVA-商业源码
  大型企业JAVA的ERP源码(193M)
  可乐吧在线游戏最新服务器端及部分源代码源码(18M)
  华某物业管理系统源码-JSP源码(97M)
  华某物业管理系统安装程序源码(43M)
  乐趣大型购物系统源码(7M)
  Java作的WebMail源码(9M)
  JAVA进销存源码(60M)
  哈工大CERP系统源码(17M)
  JSP开发的项目跟踪系统源码(11M)
  季风进销存管理系统1.1(JSP版)源码(4M)
  java框架开源订销管理系统MYSQL(6M)
  条形码商品管理信息系统源码(12M)
  信用卡管理系统源码(4M)
  学生课绩管理系统(5M)
  工做流管理系统openwfe源码(38M)
  开源网上会议系统iula-0.1.0 java(5M)
  java 学生管理系统(所有代码+数据库)(5M)
  java超市购物系统(9M)
  java网上oa办公系统原码(5M)
  JAVA写的我的博客源码(8M)
  java阳光酒店管理系统(14M)
  投票管理系统java(16M)
  宠物销售管理系统 java(11M)
  网站在线客服系统(Jsp+MySql)(19M)
  企富商贸网 java(12M)
  商城之家JSP商城企业版v6.8(15M)
  石大在线财务管理系统(含源码)java(5M)
  AWT图形设计源代码(9M)
  iText能够制做中文PDF文件的JAVA源程序(5M)
  Java+sqlserver2000作的员工管理系统(5M)
  6JAVA的ICQ系统源码(7M)
  Java开发的网络办公系统(33M)
  Java设计源码(25M)
  Java作的WebMail(9M)
  雇员管理系统源码(5M)
  酒店管理系统(16M)
  员工管理系统(8M)
  CRM客户管理系统源代码(12M)
  J2EE项目源码DigitalCampus数字校园(17M)
  JAVA网上商城项目完整源码(10M)
  Java实现图书馆管理系统源码(13M)
  Java写的ERP系统(30M)
  java大型企业DRP分销系统源码(11M)
  CRM项目java源码(10M)
  JBuilder固定资产管理系统java项目源码(12M)
  基于J2EE三层结构设计ERP源码(12M)

..............

 

Struts2之annotation注解验证

 <!-- 配置方法级别的校验 -->
                <interceptor-ref name="validation">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                    <param name="validateAnnotatedMethodOnly">true</param>
                </interceptor-ref>
因此action中的这四个方法不须要验证

// 保存
    @Validations(
        requiredStrings = {
            @RequiredStringValidator(fieldName = "admin.username", message = "用户名不容许为空!"),
            @RequiredStringValidator(fieldName = "admin.password", message = "密码不容许为空!"),
            @RequiredStringValidator(fieldName = "admin.email", message = "E-mail不容许为空!")
        },
        requiredFields = {
            @RequiredFieldValidator(fieldName = "admin.isAccountEnabled", message = "是否启用不容许为空!")
        },
        stringLengthFields = {
            @StringLengthFieldValidator(fieldName = "admin.username", minLength = "2", maxLength = "20", message = "用户名长度必须在${minLength}到${maxLength}之间!"),
            @StringLengthFieldValidator(fieldName = "admin.password", minLength = "4", maxLength = "20", message = "密码长度必须在${minLength}到${maxLength}之间!")
        },
        emails = {
            @EmailValidator(fieldName = "admin.email", message = "E-mail格式错误!")
        },
        regexFields = {
            @RegexFieldValidator(fieldName = "admin.username", expression = "^[0-9a-z_A-Z\u4e00-\u9fa5]+$", message = "用户名只容许包含中文、英文、数字和下划线!") 
        }
    )
 

$.cookie的用法

一个轻量级的cookie 插件,能够读取、写入、删除 cookie。

jquery.cookie.js 的配置

首先包含jQuery的库文件,在后面包含 jquery.cookie.js 的库文件。

<script type="text/javascript" src="js/jquery-1.6.2.min.js"></script>

<script type="text/javascript" src="js/jquery.cookie.js"></script>

使用方法

1.新添加一个会话 cookie:

$.cookie('the_cookie', 'the_value');

注:当没有指明 cookie有效时间时,所建立的cookie有效期默认到用户关闭浏览器为止,因此被称为

“会话cookie(session cookie)”。

2.建立一个cookie并设置有效时间为 7天:

$.cookie('the_cookie', 'the_value', { expires: 7 });

注:当指明了cookie有效时间时,所建立的cookie被称为“持久 cookie (persistent  cookie)”。 

3.建立一个cookie并设置 cookie的有效路径:

$.cookie('the_cookie', 'the_value', { expires: 7, path: '/' });

注:在默认状况下,只有设置 cookie的网页才能读取该 cookie。若是想让一个页面读取另外一个页面设

置的cookie,必须设置cookie的路径。cookie的路径用于设置可以读取 cookie的顶级目录。将这

个路径设置为网站的根目录,能够让全部网页都能互相读取 cookie (通常不要这样设置,防止出现冲突) 。 

4.读取cookie:

$.cookie('the_cookie'); // cookie存在 => 'the_value'

$.cookie('not_existing'); // cookie不存在 => null

5.删除cookie,经过传递null做为cookie的值便可:

$.cookie('the_cookie', null);

----------相关参数的解释---------------

1).expires: 365

定义cookie的有效时间,值能够是一个数字(从建立cookie时算起,以天为单位)或一个Date 对

象。若是省略,那么建立的cookie是会话cookie,将在用户退出浏览器时被删除。

2).path: '/'

默认状况:只有设置cookie的网页才能读取该cookie。

定义cookie的有效路径。默认状况下, 该参数的值为建立 cookie 的网页所在路径(标准浏览器的行为) 。

若是你想在整个网站中访问这个cookie须要这样设置有效路径:path: '/'。若是你想删除一个定义

了有效路径的 cookie,你须要在调用函数时包含这个路径:$.cookie('the_cookie', null,

{ path: '/' });。 domain: 'example.com'

默认值:建立 cookie的网页所拥有的域名。

3).secure: true

默认值:false。若是为true,cookie的传输须要使用安全协议(HTTPS)。

4).raw: true

默认值:false。

默认状况下,读取和写入 cookie 的时候自动进行编码和解码(使用encodeURIComponent 编码,

decodeURIComponent 解码)。要关闭这个功能设置 raw: true 便可。

jdbc

public class DBHelp<T> {
 
 private static String driver;
 private static String url;
 private static String username;
 private static String password;
 private static BasicDataSource dataSource;
 
 static{
  Properties properties = new Properties();
  
  try {
   //读取到src目录中存放的db.properties配置文件
   properties.load(DBHelp.class.getClassLoader().getResourceAsStream("db.properties"));
   driver = properties.getProperty("driver");
   url = properties.getProperty("url");
   username = properties.getProperty("username");
   password = properties.getProperty("password");
  } catch (IOException e) {
   e.printStackTrace();
  }
  
  
  dataSource = new BasicDataSource();
  
  dataSource.setDriverClassName(driver);
  dataSource.setUrl(url);
  dataSource.setUsername(username);
  dataSource.setPassword(password);
  dataSource.setInitialSize(5);
  dataSource.setMaxWait(5000);
  dataSource.setMaxActive(20);
  dataSource.setMinIdle(10);
  
 }
 public Connection getConnection(){
  try {
   Connection conn = dataSource.getConnection();
   
   return conn;
  } catch (SQLException e) {
   e.printStackTrace();
  }
  return null;
 }
 public List<T> executeForList(RowMapper<T> rowMapper,String sql) {
  Connection conn = null;
  PreparedStatement stat = null;
  ResultSet rs = null;
  List<T> list = new ArrayList<T>();
  
  try {
   conn = getConnection();
   stat = conn.prepareStatement(sql);
   rs = stat.executeQuery();
   while(rs.next()) {
    list.add(rowMapper.mapperRow(rs));
   }
   System.out.println("SQL"+sql);
  } catch (SQLException e) {
   e.printStackTrace();
  }finally{
   close(rs, stat, conn);
  }
  return list;
 } 
 
 public List<T> executeForList(String sql,RowMapper<T> rowMapper,Object... args) {
  Connection conn = null;
  PreparedStatement stat = null;
  ResultSet rs = null;
  List<T> list = new ArrayList<T>();
  
  try {
   conn = getConnection();
   stat = conn.prepareStatement(sql);
   for (int i = 0; i < args.length; i++) {
    stat.setObject(i+1,args[i]);
   }
   rs = stat.executeQuery();
   while(rs.next()) {
    list.add(rowMapper.mapperRow(rs));
   }
   System.out.println("SQL"+sql);
  } catch (SQLException e) {
   e.printStackTrace();
  }finally{
   close(rs, stat, conn);
  }
  return list;
 } 
 
 public T executeForObject(String sql,RowMapper<T> rowMapper,Object... args) {
  Connection conn = null;
  PreparedStatement stat = null;
  ResultSet rs = null;
  T obj = null;
  
  try {
   conn = getConnection();
   stat = conn.prepareStatement(sql);
   for (int i = 0; i < args.length; i++) {
    stat.setObject(i+1, args[i]);
   }
   rs = stat.executeQuery();
   if(rs.next()) {
    obj = rowMapper.mapperRow(rs);
   }
   System.out.println("SQL"+sql);
  } catch (SQLException e) {
   e.printStackTrace();
  }finally{
   close(rs, stat, conn);
  }
  return obj;
  
 }
 public int executeForCount(String sql,Object... args){
  Connection conn = null;
  PreparedStatement stat = null;
  ResultSet rs = null;
  int count = 0;
  
  try {
   conn = getConnection();
   stat = conn.prepareStatement(sql);
   rs = stat.executeQuery();
   
   for(int i = 0;i < args.length;i++){
    stat.setObject(i+1, args[i]);
   }
   if(rs.next()) {
    count = rs.getInt(1);
   }
   System.out.println("SQL"+sql);
  } catch (SQLException e) {
   e.printStackTrace();
  }finally{
   close(rs, stat, conn);
  }
  return count;
 }
 
 public void executeUpdate(String sql,Object... args) {
  Connection conn = null;
  PreparedStatement stat = null;
  
  
  try {
   conn = getConnection();
   stat = conn.prepareStatement(sql);
   
   for(int i = 0;i < args.length;i++){
    stat.setObject(i+1, args[i]);
   }
   
   stat.executeUpdate();
   System.out.println("SQL"+sql);
  } catch (SQLException e) {
   e.printStackTrace();
  }finally{
   close(stat,conn);
  }
  
 }
 
 public void close(PreparedStatement stat,Connection conn) {
  close(null,stat,conn);
 }
 public void close(ResultSet rs,PreparedStatement stat,Connection conn) {
  try {
   if(rs != null){
    rs.close();
   }
  } catch (SQLException e) {
   e.printStackTrace();
  }finally{
   try {
    if(stat != null) {
     stat.close();
    }
   } catch (SQLException e) {
    e.printStackTrace();
   }finally{
    try {
     if(conn != null) {
      conn.close();
     }
    } catch (SQLException e) {
     e.printStackTrace();
    }
   }
  }
 }
 
 
}

public interface RowMapper<T> {
 public T mapperRow(ResultSet rs) throws SQLException;
}

public class TourDao {
 private DBHelp<Tour> db = new DBHelp<Tour>();
 public Tour findByName(String name){
  String sql = "SELECT id,tourname FROM t_tour WHERE tourname=?";
  Tour t = db.executeForObject(sql, new TourRowMapper(), name);
  return t;
 }
 public void insertSale(String name){
  String sql = "INSERT INTO t_tour (tourname) VALUE(?)";
  db.executeUpdate(sql, name);
 }
 public class TourRowMapper implements RowMapper<Tour>{

  public Tour mapperRow(ResultSet rs) throws SQLException {
   Tour t = new Tour();
   t.setId(rs.getInt("id"));
   t.setTourname(rs.getString("tourname"));
   
   return t;
  }
  
 }
}

 

设计模式之备忘录模式

备忘录(Memento)模式又称标记(Token)模式。GOF给备忘录模式的定义为:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象以外保存这个状态。这样之后就可将该对象恢复到原先保存的状态。
其实单就实现保存一个对象在某一时刻的状态的功能,仍是很简单的——将对象中要保存的属性放到一个专门管理备份的对象中,须要的时候则调用约定好的方法将备份的属性放回到原来的对象中去。
备忘录模式的组成部分:

  1) 备忘录(Memento)角色:备忘录角色存储“备忘发起角色”的内部状态。“备忘发起角色”根据须要决定备忘录角色存储“备忘发起角色”的哪些内部状 态。为了防止“备忘发起角色”之外的其余对象访问备忘录。备忘录实际上有两个接口,“备忘录管理者角色”只能看到备忘录提供的窄接口——对于备忘录角色中 存放的属性是不可见的。“备忘发起角色”则可以看到一个宽接口——可以获得本身放入备忘录角色中属性。 

  2) 备忘发起(Originator)角色:“备忘发起角色”建立一个备忘录,用以记录当前时刻它的内部状态。在须要时使用备忘录恢复内部状态。

  3) 备忘录管理者(Caretaker)角色:负责保存好备忘录。不能对备忘录的内容进行操做或检查。
使用备忘录模式的前提: 

  1) 必须保存一个对象在某一个时刻的(部分)状态, 这样之后须要时它才能恢复到先前的状态。

  2) 若是一个用接口来让其它对象直接获得这些状态,将会暴露对象的实现细节并破坏对象的封装性。
例子以下:
//存储信息类
public class Caretaker {
private Memento memento;
    
    public Memento getMemento(){
        return this.memento;
    }
    
    public void setMemento(Memento memento){
        this.memento = memento;
    }

}

//备忘录模式
public class Memento {
    private String state;

    public Memento(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

}

public class Originator {
    private String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
    
    public Memento createMemento() {
        return new Memento(state);
    }
    
    public void setMemento(Memento memento) {
        state = memento.getState();
    }
    
    public void showState(){
        System.out.println(state);
    }

}

测试类:
public class Test {
    public static void main(String[] args) {
        Originator org = new Originator();
        org.setState("开会中");
        org.showState();//显示
        System.out.println("---------------");
        Caretaker ctk = new Caretaker();
        
        ctk.setMemento(org.createMemento());//将数据封装在Caretaker
        System.out.println("---------------");
        org.setState("睡觉中");
        org.showState();//显示
        System.out.println("---------------");
        org.setMemento(ctk.getMemento());//将Caretaker中的数据从新导入
        org.showState();
        System.out.println("---------------");
    }

}
 

设计模式之中介者模式

Java深刻到必定程度,就不可避免的碰到设计模式这一律念,了解设计模式,将使本身对java中的接口或抽象类应用有更深的理解.设计模式在java的 中型系统中应用普遍,遵循必定的编程模式,才能使本身的代码便于理解,易于交流,Mediator(中介者模式)模式是比较经常使用的一个模式.
 

  Mediator中介者模式,当多个对象彼此间都有联系的时候,咱们就能够应用Mediator将对象间的多对多关系转换为一对多的关系,这样作,能够使各个对象间的耦合松散。统一管理对象间的交互。但也可能使得Mediator对象成为一个系统中的庞然大物,难以维护
   使用场景:集中负责维护对象模型的关系完整性 以及须要 封装对象间交互方式的时候.
   其实MVC中的controller就是一种Mediator,是UI层 和后端应用sevice层间的中介者。中介者将交互的复杂性变为中介者的复杂性

例子以下:
业务类的接口:
public interface Colleague {
void action();
}
业务类的2个实现类:
public class ColleagueA implements Colleague{

    @Override
    public void action() {
         System.out.println("普通员工努力工做aaaaaaa");        
    }
}
public class ColleagueB implements Colleague{

    @Override
    public void action() {
         System.out.println("前台注意了bbbb");        
    }
}
中介者接口:
public interface Mediator {
void notice(String content);
}

public class ConcreteMediator implements Mediator{
     private ColleagueA ca;
        
        private ColleagueB cb;
        
        public ConcreteMediator() {
            ca = new ColleagueA();
            cb = new ColleagueB();
        }
        
        public void notice(String content) {
            if (content.equals("boss")) {
                //老板来了, 通知员工A
                ca.action();
            }
            if (content.equals("client")) {
                //客户来了, 通知前台B
                cb.action();
            }
        }

}

测试类:
public class Test {
     public static void main(String[] args) {
            Mediator med = new ConcreteMediator();
            //老板来了
            med.notice("boss");
            
            //客户来了
            med.notice("client");
        }

}
当客户端传过来的字符串不同时,中介者类根据字符串实现不一样的业务类的对象,处理数据。
 

extjs 中判断坐标是否在选择区域中

function isInRect(x, y, x0, y0, x1, y1) {
 if (x0 < x && x < x1 && y0 < y && y < y1)
  return true;
 else
  return false;
}

extjs中触发隐藏和出现的方法

function ElIn(elId) {
 var el = Ext.get(elId);
 el.fadeIn( {
  endOpacity : 1,
  easing : 'easeOut',
  duration : 2
 });
}

function ElOut(elId) {
 var el = Ext.get(elId);
 el.fadeOut( {
  endOpacity : 0,
  easing : 'easeOut',
  duration : .5,
  useDisplay : true
 });
 // el.dom.style.display = 'none';
}

extjs获得图片的坐标和让图片某一区域能够点击

function getClickScale(event, target, isShowInfo) {
 var imageWidth = target.width;
 var imageHeight = target.height;
 var eventX = event.xy[0];
 var eventY = event.xy[1];

 var scalex = eventX / imageWidth;
 var scaley = eventY / imageHeight;

 var info = '';
 info += 'image (' + imageWidth + ', ' + imageHeight + '), ';
 info += 'click (' + eventX + ', ' + eventY + '), ';
 info += 'scale (' + scalex + ', ' + scaley + ')';
 if (typeof (isShowInfo) != 'undefined' && isShowInfo) {
  alert(info);
 }

 return {
  scalex : scalex,
  scaley : scaley
 };
}

Ext.get('main-navigator-image').on(
     'mousemove',
     function(event, target, obj) {
      var scale = getClickScale(event, target);
      target.style.cursor = '';
      for ( var i = 0; i < areas.length; i++) {
       var area = areas[i];
       if (isInRect(scale.scalex, scale.scaley,
         area.p1.scalex, area.p1.scaley,
         area.p2.scalex, area.p2.scaley)) {
        target.style.cursor = 'pointer';
        break;
       }
      }
     });
  });

访问tomcat时只输入ip就能够访问系统的方法

1.在tomcat的service.xml中把端口改为80
2.把本身的项目名称改为ROOT,覆盖tomcat的原ROOT项目,就能够了
 

extjs下拉框点击一行触发事件,获得valueField和displayField的值

            var combo = new Ext.form.ComboBox(
                                                        {
                                                            store : store,
                                                            emptyText : '请选择',
                                                            mode : 'local',
                                                            triggerAction : 'all',
                                                            valueField : 'value',
                                                            displayField : 'name',
                                                            //autoScroll : true,
                                                            //length : 4,
                                                            //IdValue : 'name',
                                                            listeners : {//选择一行后触发的事件
                                                                'select' : function() {
                                                            
                                                            var url = combo
                                                            .getValue();//获得valueField的值
                                                            if (url != null
                                                                    && url != '') {
                                                            
                                                                loactionTo(
                                                                        combo
                                                                        .getRawValue(),//获得displayField的值
                                                                        url);
                                                                // typeForm.getForm().submit({});
                                                            }
                                                            }
                                                            }

                                                        });

Hibernate Fetch策略

hibernate抓取策略(单端代理的批量抓取)

  保持默认,同fetch="select",如:
  <many-to-one name="classes" column="classesid" fetch="select"/>
  fetch="select",另外发送一条select语句抓取当前对象关联实体或集合
  
  设置fetch="join",如:
  <many-to-one name="classes" column="classesid" fetch="join"/>
  fetch="join",hibernate会经过select语句使用外链接来加载其关联实体或集合
  此时lazy会失效
  
  

  hibernate抓取策略(集合代理的批量抓取)

  保持默认,同fetch="select",如:
  <set name="students" inverse="true" cascade="all" fetch="select">
  fetch="select",另外发送一条select语句抓取当前对象关联实体或集合
  
  设置fetch="join",如:
  <set name="students" inverse="true" cascade="all" fetch="join">
  fetch="join",hibernate会经过select语句使用外链接来加载其关联实体或集合 此时lazy会失效
  
  设置fetch="subselect",如:
  <set name="students" inverse="true" cascade="all" fetch="subselect">
  fetch="subselect",另外发送一条select语句抓取在前面查询到的全部实体对象的关联集合
  
  hibernate抓取策略,,batch-size在<class>上的应用
  batch-size属性,能够批量加载实体类,参见:Classes.hbm.xml
  <class name="Classes" table="t_classes" batch-size="3">
  
  hibernate抓取策略,batch-size在集合上的应用
  batch-size属性,能够批量加载实体类,参见:Classes.hbm.xml
  <set name="students" inverse="true" cascade="all" batch-size="5">
  hibernate 会下先完发sql,再一次性的大数据 
 

hibernate中实体类继承,按照子类建表

实体类父类:

public class Animal {
 
 private int id;
 
 private String name;
 
 private boolean sex;

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public boolean isSex() {
  return sex;
 }

 public void setSex(boolean sex) {
  this.sex = sex;
 }
}

子类:

public class Bird extends Animal {

 private int height;

 public int getHeight() {
  return height;
 }

 public void setHeight(int height) {
  this.height = height;
 }
}


public class Pig extends Animal {
 
 private int weight;

 public int getWeight() {
  return weight;
 }

 public void setWeight(int weight) {
  this.weight = weight;
 }
}


extends.hbm.xml文件:
<hibernate-mapping package="com.hibernate">
 <class name="Animal" abstract="true">
  <id name="id">
   <generator class="assigned"/>
  </id>
  <property name="name"/>
  <property name="sex"/>
  <union-subclass name="Pig" table="t_pig">
   <property name="weight"/>
  </union-subclass>
  <union-subclass name="Bird" table="t_bird">
   <property name="height"/>
  </union-subclass>
 </class>
</hibernate-mapping>
数据库表以下:

hibernate中实体类继承,分红若干表

父类实体类:

public class Animal {
 
 private int id;
 
 private String name;
 
 private boolean sex;

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public boolean isSex() {
  return sex;
 }

 public void setSex(boolean sex) {
  this.sex = sex;
 }
}

子类实体类:

public class Bird extends Animal {

 private int height;

 public int getHeight() {
  return height;
 }

 public void setHeight(int height) {
  this.height = height;
 }
}

public class Pig extends Animal {
 
 private int weight;

 public int getWeight() {
  return weight;
 }

 public void setWeight(int weight) {
  this.weight = weight;
 }
}

extends.hbm.xml文件:
<hibernate-mapping package="com.hibernate">
 <class name="Animal" table="t_animal">
  <id name="id">
   <generator class="native"/>
  </id>
  <property name="name"/>
  <property name="sex"/>
  <joined-subclass name="Pig" table="t_pig">
   <key column="pid"/>
   <property name="weight"/>
  </joined-subclass>
  <joined-subclass name="Bird" table="t_bird">
   <key column="bid"/>
   <property name="height"/>
  </joined-subclass>
 </class>
</hibernate-mapping>
在数据库中表以下:

 

hibernate中每棵继承树映射成一张表

public class Animal {
 
 private int id;
 
 private String name;
 
 private boolean sex;

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public boolean isSex() {
  return sex;
 }

 public void setSex(boolean sex) {
  this.sex = sex;
 }
}

public class Bird extends Animal {

 private int height;

 public int getHeight() {
  return height;
 }

 public void setHeight(int height) {
  this.height = height;
 }
}

public class Pig extends Animal {
 
 private int weight;

 public int getWeight() {
  return weight;
 }

 public void setWeight(int weight) {
  this.weight = weight;
 }
}

在extends.hbm.xml文件:
<hibernate-mapping package="com.hibernate">
 <class name="Animal" table="t_animal" lazy="false">
  <id name="id">
   <generator class="native"/>
  </id>
  <discriminator column="type" type="string"/>
  <property name="name"/>
  <property name="sex"/>
  <subclass name="Pig" discriminator-value="P">
   <property name="weight"/>
  </subclass>
  <subclass name="Bird" discriminator-value="B">
   <property name="height"/>
  </subclass>
 </class>
</hibernate-mapping>
理解如何映射
  由于类继承树确定是对应多个类,要把多个类的信息存放在一张表中,必须有某种机制来区分哪些记录是属于哪一个类的。
 这种机制就是,在表中添加一个字段,用这个字段的值来进行区分。用hibernate实现这种策略的时候,有以下步骤:
 父类用普通的<class>标签订义
 在父类中定义一个discriminator,即指定这个区分的字段的名称和类型
 如:<discriminator column=”XXX” type=”string”/>
 子类使用<subclass>标签订义,在定义subclass的时候,须要注意以下几点:
 Subclass标签的name属性是子类的全路径名
 在Subclass标签中,用discriminator-value属性来标明本子类的discriminator字段(用来区分不一样类的字段)
 的值Subclass标签,既能够被class标签所包含(这种包含关系正是代表了类之间的继承关系),也能够与class标
 签平行。 当subclass标签的定义与class标签平行的时候,须要在subclass标签中,添加extends属性,里面的值
 是父类的全路径名称。子类的其它属性,像普通类同样,定义在subclass标签的内部。
 

hibernate 中集合映射成表

实体类是:

public class CollectionMapping {
 
 private int id;
 
 private String name;
 
 private Set setValue;
 
 private List listValue;
 
 private String[] arrayValue;
 
 private Map mapValue;

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public Set getSetValue() {
  return setValue;
 }

 public void setSetValue(Set setValue) {
  this.setValue = setValue;
 }

 public List getListValue() {
  return listValue;
 }

 public void setListValue(List listValue) {
  this.listValue = listValue;
 }

 public String[] getArrayValue() {
  return arrayValue;
 }

 public void setArrayValue(String[] arrayValue) {
  this.arrayValue = arrayValue;
 }

 public Map getMapValue() {
  return mapValue;
 }

 public void setMapValue(Map mapValue) {
  this.mapValue = mapValue;
 }
}

在CollectionMapping.hbm.xml文件中:
<hibernate-mapping>
 <class name="CollectionMapping" table="t_CollectionMapping">
  <id name="id">
   <generator class="native"/>
  </id>
  <property name="name"/>
  <set name="setValue" table="t_set_value">
   <key column="set_id"/>
   <element type="string" column="set_value"/>
  </set>
  <list name="listValue" table="t_list_value">
   <key column="list_id"/>
   <list-index column="list_index"/>
   <element type="string" column="list_value"/>
  </list>
  <array name="arrayValue" table="t_array_value">
   <key column="array_id"/>
   <list-index column="array_index"/>
   <element type="string" column="array_value"/>
  </array>
  <map name="mapValue" table="t_map_value">
   <key column="map_id"/>
   <map-key type="string" column="map_key"/>
   <element type="string" column="map_value"/>
  </map>
 </class>
</hibernate-mapping>
在数据库中生成5个表
 

hibernate中实体类中有其余普通类的引用,普通类的属性在数据库中是实体类的一个字段

例如:
普通类:

public class Contact {
 
 private String email;
 
 private String address;
 
 private String zipCode;
 
 private String contactTel;

 public String getEmail() {
  return email;
 }

 public void setEmail(String email) {
  this.email = email;
 }

 public String getAddress() {
  return address;
 }

 public void setAddress(String address) {
  this.address = address;
 }

 public String getZipCode() {
  return zipCode;
 }

 public void setZipCode(String zipCode) {
  this.zipCode = zipCode;
 }

 public String getContactTel() {
  return contactTel;
 }

 public void setContactTel(String contactTel) {
  this.contactTel = contactTel;
 }
}

实体类:

public class User {
 
 private int id;
 
 private String name;
 
 private Contact contact; 
 
 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public Contact getContact() {
  return contact;
 }

 public void setContact(Contact contact) {
  this.contact = contact;
 }
 
}

User.hbm.xml文件:
<hibernate-mapping>
 <class name="User" table="t_user">
  <id name="id">
   <generator class="native"/>
  </id>
  <property name="name"/>
  <component name="contact">
   <property name="email"/>
   <property name="address"/>
   <property name="zipCode"/>
   <property name="contactTel"/>
  </component>
 </class>
</hibernate-mapping>
在数据库中在t_user表中含有Contact类的属性字段
 

hibernate实体配置文件中主键生成策略

<id name="id" column="user_id" length="32">
  <!-- 主键自动生成uuid -->
   <generator class="uuid"/>
  </id>
<id name="id" column="user_id">
  <!-- 主键自动增加 -->
   <generator class="native"/>
  </id>
<id name="id" column="user_id" length="32">
  <!-- 主键须要手动定义 -->
   <generator class="assigned"/>
  </id>

dom4j解析xml文件

1.先导入dom4j-1.6.1.jar包
2.xml文件以下:

<?xml version="1.0" encoding="UTF-8"?>
<config>
 
 
 <action name="user" className="com.kaishengit.web.UserAction">
  <result name="success" type="forward">suc.jsp</result>
  <result name="error" type="redirect">404.jsp</result>
 </action>
 
 
 <action name="book" className="com.kaishengit.web.BookAction">
  <result name="success">book.jsp</result>
  <result name="error" type="redirect">bookerror.jsp</result>
 </action>
 
 <action name="person" className="com.kaishengit.web.PersonAction" method="del">
  <result name="ok">suc.jsp</result>
 </action>
 
 

</config>

3.解析测试类是:

package com.kaishengit.test;

import java.io.File;
import java.net.URL;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class Dom4jTest {

 public void readXML() {
  //拿到src文件夹里的xml配置文件
  URL url = getClass().getResource("/");
  System.out.println(url);
  String filePath = url.getFile() + "struts.xml";
  
  try {
   //建立读取配置文件的对象
   SAXReader reader = new SAXReader();
   //开始读取配置文件
   Document doc = reader.read(new File(filePath));
   //拿到根节点
   Element root = doc.getRootElement();
   
   //拿到根节点下的action接点数组
   List<Element> actions = root.elements("action");
   
   for(Element action : actions) {
    String name = action.attributeValue("name");
    String className = action.attributeValue("className");
    String method = action.attributeValue("method");
    System.out.println("name="+name);
    System.out.println("className="+className);
    System.out.println("method="+method);
    
    List<Element> results = action.elements("result");
    for(Element result : results) {
     String resultName = result.attributeValue("name");
     String resultType = result.attributeValue("type");
     String pageName = result.getText();
     
     System.out.println("name:" + resultName + "\tresultType:" + resultType + "\tpageName:" + pageName);
   
    }
    
    System.out.println("----------------------");
   }
   
   
  } catch (Exception e) {
   e.printStackTrace();
  }
  
 }
 
 
 
 public static void main(String[] args) {
  
  
  Dom4jTest d = new Dom4jTest();
  d.readXML();
  
  
  
 }
}

设计模式之状态模式

如今写一个用状态模式实现的根据上班时间状态变化而行为变化的小程序,当时间<12上午上班时间,
<13午休时间,<17下午上班时间,<21加班时间,根据时间不一样,条用的类方法不一样。
状态模式适用于当对象的状态改变时,行为也改变,就能够使用状态模式
状态接口:
public interface State {
void writeProgram(Work work);
}
不一样的实现类:

public class AfterNoonState implements State {

 @Override
 public void writeProgram(Work work) {
  if(work.getHour()<17){
   System.out.println("工做");
  }else {
   work.setCurrent(new EveningState());
   work.writeProgram();
  }

 }

}


public class EveningState implements State {

 @Override
 public void writeProgram(Work work) {
 if(work.isFinish()){
  work.setCurrent(new RestState());
  work.writeProgram();
 }else {
  if(work.getHour()<21){
   System.out.println("加班");
  }else {
   work.setCurrent(new SleepState());
   work.writeProgram();
  }
 }

 }

}


public class ForenoonState implements State {

 @Override
 public void writeProgram(Work work) {
 if(work.getHour()<12){
  System.out.println("工做时间");
 }else {
 work.setCurrent(new NoonState()); 
 work.writeProgram();
 }
  
 }

}


public class NoonState implements State {

 @Override
 public void writeProgram(Work work) {
  if(work.getHour()<13){
   System.out.println("午睡");
  }else {
   work.setCurrent(new AfterNoonState());
   work.writeProgram();
  }

 }

}


public class RestState implements State {

 @Override
 public void writeProgram(Work work) {
  System.out.println("回家");

 }

}


public class SleepState implements State {

 @Override
 public void writeProgram(Work work) {
  System.out.println("睡觉");

 }

}


调用状态的类:

public class Work {
private State current;

 public Work(double hour,boolean finish){
 current = new ForenoonState();
 this.hour = hour;
 this.finish = finish;
}
private double hour;
public double getHour() {
 return hour;
}

public State getCurrent() {
 return current;
}
public void setCurrent(State current) {
 this.current = current;
}
private boolean finish;
public boolean isFinish() {
 return finish;
}

public void writeProgram(){
 current.writeProgram(this);
}
}


测试类:
public class Test {
public static void main(String[] args) {
 Work work = new Work(20, true);
 work.writeProgram();
}
}

mysql中查询值是空,是null的查询语句


这是表数据
SELECT * FROM t_user WHERE username IS NULL;查询到id=8的数据
SELECT * FROM t_user WHERE username IS NOT NULL;查询到id=11,12,13,14的四条数据
SELECT * FROM t_user WHERE username ='';查询到id=11,12,13的三条数据
SELECT * FROM t_user WHERE username ='aa';查询到id=14的数据
 

hibernate中的get方法和load方法的区别和使用

get和load方法都是是利用对象的主键获得对象,并能够使对象处于持久态。
load方法获取对象时不会当即执行查询操做,而是在第一次使用对象是再去执行查询操做。若是查询的对象在数据库中不存在,load方法返回值不会为null,在第一次使用时抛出org.hibernate.ObjectNotFoundException异常。
使用get方法获取对象时会当即执行查询操做,而且对象在数据库中不存在时返回null值。
因此咱们在实际使用中多使用get方法,这样咱们能够先判断获得的对象是不是null,再操做
 

spring对jdbc的支持SimpleJdbcTemplate

1.在配置文件中的配置:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  <property name="driverClass" value="com.mysql.jdbc.Driver" />
  <property name="jdbcUrl" value="jdbc:mysql:///struts" />
  <property name="properties">
   <props>
    <prop key="user">root</prop>
    <prop key="password">root</prop>

   </props>
  </property>
 </bean>
 <bean id="simpleJdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
  <constructor-arg ref="dataSource"></constructor-arg>
 </bean>
 <bean  id="userSimpleJdbcTemplateDao" class="com.yjw.dao.UserSimpleJdbcTemplateDao">
  <property name="simpleJdbcTemplate" ref="simpleJdbcTemplate"></property>
 </bean>

2.dao中的写法:

package com.yjw.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import com.yjw.bean.User;

public class UserSimpleJdbcTemplateDao {

 private SimpleJdbcTemplate simpleJdbcTemplate;

 public void setSimpleJdbcTemplate(SimpleJdbcTemplate simpleJdbcTemplate) {
  this.simpleJdbcTemplate = simpleJdbcTemplate;
 }
 
 public void save(User user){
  String sql = "INSERT INTO t_user (username,PASSWORD) VALUES (?,?)";
  simpleJdbcTemplate.update(sql, user.getUsername(),user.getPassword());
 }
 public void update(User user){
  String sql = "UPDATE t_user SET username=:username ,PASSWORD=:password WHERE id=:id?";
  
  simpleJdbcTemplate.update(sql, user.getUsername(),user.getPassword(),user.getId());
 }
 public void delete(int id){
  String sql = "delete from t_user where id=?";
  simpleJdbcTemplate.update(sql, id);
 }
 private  class UserRowmapper  implements  RowMapper<User> {

  public User mapRow(ResultSet rs, int rowNum) throws SQLException {
  User u = new  User();
  u.setId(rs.getInt("id"));
  u.setUsername(rs.getString("username"));
  u.setPassword(rs.getString("password"));
   return u;
  }  
 }
 public User getUser(int id) {
  String sql = "select id,username,password from t_user where id=?";
  User user = simpleJdbcTemplate.queryForObject(sql, new UserRowmapper(), id);
  return user;
  
 }
 public List<User> getList(){
  String sql = "select id,username,password from t_user ";
  List<User> list = simpleJdbcTemplate.query(sql, new UserRowmapper() );
  return list;
 }
}

spring中aop 的配置实现

四种通知的执行地方:前置通知
try{
业务代码
后置通知
} catch{
异常通知
} finally{
最终通知
}
1.须要的jar包:aspectjrt.jar,aspectjweaver.jar,cglib-nodep-2.1.3.jar 
2.在配置文件中加入

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://www.springframework.org/schema/p"
         xmlns:aop="http://www.springframework.org/schema/aop"
         xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd

">
<bean id="myXmlAspect" class="com.yjw.aspect.MyXmlAspect"/>
<!-- 配置事务切面-->
<aop:config>
 <aop:aspect ref="myXmlAspect">
  <aop:pointcut expression="execution(* com.yjw.dao..*.*(..))" id="pointcut"/>
  <aop:before method="beforeAdvice" pointcut-ref="pointcut"/>
  <aop:after-returning method="afterReturningAdvice" returning="value" pointcut-ref="pointcut"/>
  <aop:after-throwing method="exceptionAdvice" pointcut-ref="pointcut" throwing="ex"/>
  <aop:after method="afterAdvice" pointcut-ref="pointcut"/>
 </aop:aspect>
</aop:config> 
</beans>

 

package com.yjw.aspect;

 

 

public class MyXmlAspect {


 
 //前置通知

 public void  beforeAdvice(){
  System.out.println("前置通知");
 }
 //异常通知,接收异常信息

 public  void  exceptionAdvice(Exception  ex){
  System.out.println("异常出现"+ex.getMessage());
 }
 //后置通知,能够接收方法的返回值
 
 public  void  afterReturningAdvice(Object  value){
  System.out.println("后置通知"+value);
 }
 //最终通知

 public  void  afterAdvice(){
  System.out.println("after");
 }
}

 

spring中aop的annotation的写法

四种通知的执行地方:前置通知
try{
业务代码
后置通知
} catch{
异常通知
} finally{
最终通知
}
1.须要的jar包:aspectjrt.jar,aspectjweaver.jar,cglib-nodep-2.1.3.jar 
2.在配置文件中加入

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://www.springframework.org/schema/p"
         xmlns:aop="http://www.springframework.org/schema/aop"
         xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd

">
<!-- 让spring支持annotation的aop -->
<aop:aspectj-autoproxy/>
<!-- 把切面类交给spring -->
<bean id="myAspece" class="com.yjw.aspect.MyAspect"/>

</beans>

package com.yjw.aspect;


import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
//定义切面类,存放通知
@Aspect
public class MyAspect {

 //切入点
 /**第一个星号表明返回任何类型的数据,bean后的两个点表明本包及其子包,
  * 第二个星号表明中间的全部的类;
  * 第三个星号表明中间的全部的方法;
  * (..)小括号表明参数列表,两个点表明参数类型不限
  */
 
 @Pointcut("execution(* com.yjw.dao..*.*(..))")
 public void  pointCut(){}
 //前置通知
 @Before(" pointCut()")
 public void  beforeAdvice(){
  System.out.println("前置通知");
 }
 //异常通知,接收异常信息
 @AfterThrowing( pointcut=" pointCut()",throwing="ex")
 public  void  exceptionAdvice(Exception  ex){
  System.out.println("异常出现"+ex.getMessage());
 }
 //后置通知,能够接收方法的返回值
 @AfterReturning( pointcut=" pointCut()",returning="value")
 public  void  afterReturningAdvice(Object  value){
  System.out.println("后置通知"+value);
 }
 //最终通知
 @After(" pointCut()")
 public  void  afterAdvice(){
  System.out.println("zuizhong");
 }

}
 

hibernate中使用原生sql语句查询集合和对象

查询集合
 String sql = "select id, address,userid from t_address where userid in(select id from t_user where id in (select id from t_card where cardnum=112))";
 SQLQuery query = session.createSQLQuery(sql).addEntity(Address.class);
 List list = session.createSQLQuery(sql).list();
for(Object a : list){
 Object[] address = (Object[]) a;
 System.out.println(address[0]+"  "+address[1]+"  "+address[2]);
}
查询一个对象
 String sql = "select id,username,password from t_user where id in (select id from t_card where cardnum=112)";
 SQLQuery query = session.createSQLQuery(sql).addEntity(User.class);
 User user = (User) query.uniqueResult();
System.out.println(user.getPwd());

设计模式之单例模式

单例就是在系统运行中只有一个实例对象
public class Factory {

    private  static Factory factory = new Factory();
    private Factory(){
        System.out.println("--");
    }
    public static Factory getFactory(){
        return factory;
        
    }
    public void say(){
        System.out.println("say");
    }
}
第二种
public class Factory {

    private  static Factory factory =null;
    private Factory(){
        System.out.println("--");
    }
    public synchronized static Factory getFactory(){
        if(factory==null){
            factory = new Factory();
        }
        return factory;
        
    }
    public void say(){
        System.out.println("say");
    }
}

设计模式之适配器模式

将一个类的接口转换成客户但愿的另一个接口。Adapter模式使得本来因为接口不兼容而不能一块儿工做的那些类能够一块儿工做。
例子,让羊的叫声和狼同样,羊就是一个适配器:
public class Wolf {

    public void run() {
        System.out.println("wolf run");
    }
    
    public void ho() {
        System.out.println("wolf ho");
    }
}
适配器接口:
public interface Sheep {

    public void run();
    public void ho();
}
实现类:
public class SheepAdapter implements Sheep{

    private Wolf wolf;
    public SheepAdapter(Wolf wolf) {
        this.wolf = wolf;
    }
    
    @Override
    public void run() {
        wolf.run();
    }

    @Override
    public void ho() {
        wolf.ho();
    }

}

测试类:
    public static void main(String[] args) {
        
        Wolf w = new Wolf();
        Sheep sa = new SheepAdapter(w);
        sa.run();
        sa.ho();
        
    }
}

设计模式之装饰者模式

动态地给一个对象添加一些额外的职责。就增长功能来讲,Decorator模式相比生成子类更为灵活。
例子:
被装饰的接口:
public interface Cake {

    public float cost();
}
接口的实现类:
public class MilkCake implements Cake{
    @Override
    public float cost() {
        return 100f;
    }
}
装饰者抽象类:
public abstract class CakeDecorator implements Cake{

}
装饰者的实现类
public class Chocolate extends CakeDecorator{

    private Cake cake;
    
    public Chocolate(Cake cake) {
        this.cake = cake;
    }
    
    @Override
    public float cost() {
        float chocolatePrice = 25f;
        return cake.cost() + chocolatePrice;
    }

}
public class Berry extends CakeDecorator {

    private Cake cake;
    public Berry(Cake cake) {
        this.cake = cake;
    }
    
    @Override
    public float cost() {
        float berryPrice = 5f;
        return cake.cost() + berryPrice;
    }    
}
测试类:
public class Test {

    public static void main(String[] args)  {
        
        MilkCake mc = new MilkCake();//牛奶蛋糕
        System.out.println(mc.cost());
        Berry b = new Berry(mc);//牛奶草莓蛋糕
        System.out.println(b.cost());
        Chocolate c = new Chocolate(b);//牛奶草莓巧克力蛋糕
        System.out.println("付款:" + c.cost());
        
        
        
    }
}

设计模式以外观模式

为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
1.当你要为一个复杂子系统提供一个简单接口时。子系统每每由于不断演化而变得愈来愈 复杂。大多数模式使用时都会产生更多更小的类。这使得子系统更具可重用性,也更容 易对子系统进行定制,但这也给那些不须要定制子系统的用户带来一些使用上的困难。 Facade能够提供一个简单的缺省视图,这一视图对大多数用户来讲已经足够,而那些需 要更多的可定制性的用户能够越过facade层。
 2.客户程序与抽象类的实现部分之间存在着很大的依赖性。引入facade将这个子系统与客 户以及其余的子系统分离,能够提升子系统的独立性和可移植性。
 3.当你须要构建一个层次结构的子系统时,使用facade模式定义子系统中每层的入口点。 若是子系统之间是相互依赖的,你能够让它们仅经过facade进行通信,从而简化了它们 之间的依赖关系。
例子:
外观类:
public class Facade {
     ServiceA sa;
        
        ServiceB sb;
        
        ServiceC sc;
        
        public Facade() {
            sa = new ServiceAImpl();
            sb = new ServiceBImpl();
            sc = new ServiceCImpl(); 
        }
        
        public void methodA() {
            sa.methodA();
            sb.methodB();
        }
        
        public void methodB() {
            sb.methodB();
            sc.methodC();
        }
        
        public void methodC() {
            sc.methodC();
            sa.methodA();
        }

}
接口和接口的实现类:
public interface ServiceA {
    void methodA() ;
}
public class ServiceAImpl implements ServiceA{

    @Override
    public void methodA() {
        System.out.println("这是服务A");        
    }
}
public interface ServiceB {
    void methodB() ;
}
public class ServiceBImpl implements ServiceB{

    @Override
    public void methodB() {
         System.out.println("这是服务B");        
    }
}
public interface ServiceC {
    void methodC() ;
}
public class ServiceCImpl implements ServiceC{

    @Override
    public void methodC() {
         System.out.println("这是服务C");        
    }
}
测试类:
public class Test {
    public static void main(String[] args) {
        ServiceA sa = new ServiceAImpl();
        ServiceB sb = new ServiceBImpl();       
        sa.methodA();
        sb.methodB();       
        System.out.println("========");
        //facade
        Facade facade = new Facade();
        facade.methodA();
        facade.methodB();
        facade.methodC();
    }

}

设计模式之享元模式

运用共享技术有效地支持大量细粒度的对象。
1.一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
 2.各子类中公共的行为应被提取出来并集中到一个公共父类中以免代码重复。 首先识别现有代码中的不一样之处,而且将不一样之处分离为新的操做。 最后,用一个调用这些新的操做的模板方法来替换这些不一样的代码。
 3.控制子类扩展。
例子;
享元接口:
public interface Flyweight {
    void action(int arg);

}
享元接口的实现类:
public class FlyweightImpl implements Flyweight{

    @Override
    public void action(int arg) {
          System.out.println("参数值: " + arg);        
    }
}
产生精度对象的工厂类:
public class FlyweightFactory {
private static Map<String,Flyweight> flyweightsMap = new HashMap<String,Flyweight>();
    
    public FlyweightFactory(String arg) {
        System.out.println("-----------------");
        flyweightsMap.put(arg, new FlyweightImpl());
    }
    
    public static Flyweight getFlyweight(String key) {
        if (flyweightsMap.get(key) == null) {
            flyweightsMap.put(key, new FlyweightImpl());
        }
        return (Flyweight) flyweightsMap.get(key);
    }
    
    public static int getSize() {
        return flyweightsMap.size();
    }

}
测试类:
public class Test {
    public static void main(String[] args) {
        Flyweight fly1 = FlyweightFactory.getFlyweight("a");
        fly1.action(1);
        
        Flyweight fly2 = FlyweightFactory.getFlyweight("a");
        System.out.println(fly1 == fly2);
        
        Flyweight fly3 = FlyweightFactory.getFlyweight("c");
        fly3.action(3);
        
        Flyweight fly4 = FlyweightFactory.getFlyweight("d");
        fly4.action(4);
        
        Flyweight fly5 = FlyweightFactory.getFlyweight("e");
        fly5.action(5);
        
        System.out.println(FlyweightFactory.getSize());
    }

}
 

设计模式之代理模式

代理模式实现了类与类之间直接调用的解耦,例子:
代理模式主要使用了java的多态,干活的是被代理类,代理类主要的接活
  ,把活交给幕后的被代理类作,代理类和被代理类实现同一个接口。
被代理类的接口:
public interface Object {
      void action();

}
被代理类的接口实现类:
public class ObjectImpl implements Object{
     public void action() {
            System.out.println("========");
            System.out.println("========");
            System.out.println("这是被代理的类");
            System.out.println("========");
            System.out.println("========");
        }

}
代理类:

public class ProxyObject implements Object{
     Object obj;
        
        public ProxyObject() {
            System.out.println("这是代理类");
            obj = new ObjectImpl();
        }
        
        public void action() {
            System.out.println("代理开始");
            obj.action();
            System.out.println("代理结束");
        }

}

测试类:
public class Test {
    public static void main(String[] args) {
        Object obj = new ProxyObject();
        obj.action();
    }
}
 

设计模式之策略模式

定义一系列的算法,把它们一个个封装起来,而且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
适合场合:
 * 1.以不一样的格式保存文件
 * 2.以不一样的算法压缩文件
 * 3.以不一样的算法截取图形
 * 4.以不一样的格式输出数据的图形,曲线,框图等
策略接口:
public interface Strategy {
    void method();

}
策略接口实现类:
public class StrategyImplA implements Strategy{
    public void method() {
        System.out.println("这是第一个实现a");
    }

}
public class StrategyImplB implements Strategy{
    public void method() {
        System.out.println("这是第二个实现b");
    }

}

public class StrategyImplC implements Strategy{
     public void method() {
            System.out.println("这是第三个实现c");
        }

}
调用类:
public class Context {
Strategy stra;
    
    public Context(Strategy stra) {
        this.stra = stra;
    }
    
    public void doMethod() {
        stra.method();
    }

}
测试:
public class Test {
    public static void main(String[] args) {
        Context ctx = new Context(new StrategyImplA());
        ctx.doMethod();
        
        ctx = new Context(new StrategyImplB());
        ctx.doMethod();
        
        ctx = new Context(new StrategyImplC());
        ctx.doMethod();
    }

}
 

设计模式之命令模式

 命令模式就是将一组对象的类似行为,进行了抽象,将调用者与被调用者之间进行解耦,提
高了应用的灵活性。命令模式将调用的目标对象的一些异构性给封装起来,经过统一的方式来为调用者提供服务。
适用场景
    一、当一个应用程序调用者与多个目标对象之间存在调用关系时,而且目标对象之间的操做很相似的时候。
      二、例如当一个目标对象内部的方法调用太复杂,或者内部的方法须要协做才能完成对象的某个特色操做时。
      三、有时候调用者调用目标对象后,须要回调一些方法。
例子:
命令接口:
public interface Commond {

    public void execute();
}
命令接口实现类:
public class LightOnCommond implements Commond{

    private Light light;
    public LightOnCommond(Light light) {
        this.light = light;
    }
    
    @Override
    public void execute() {
        light.on();
    }

}
命令的调用者:
public class Light {

    public void on() {
        System.out.println("灯亮了");
    }
}
public class TurnTvCommond implements Commond {
    
    private Tv tv;
    public TurnTvCommond(Tv tv) {
        this.tv = tv;
    }

    @Override
    public void execute() {
        tv.turn();

    }

}

public class Tv {

    public void turn() {
        System.out.println("调台");
    }
}
同时执行的多个命令数组
public class MracoCommond implements Commond{

    private Commond[] commonds;
    
    public MracoCommond(Commond...commonds) {
        this.commonds = commonds;
    }
    
    @Override
    public void execute() {
        for(Commond cmd : commonds) {
            cmd.execute();
        }
    }

}
命令的包装类,
public class RemoteContro {

    private List<Commond> commondList = new ArrayList<Commond>();
    
    public void setCommond(Commond commond) {
        commondList.add(commond);
    }
    
    public void buttonWasPressed(int index){
        commondList.get(index-1).execute();
    }
}
public class Test {

    public static void main(String[] args) {
        
        Light light = new Light();
        LightOnCommond loc = new LightOnCommond(light);        
        Tv tv = new Tv();
        TurnTvCommond ttc = new TurnTvCommond(tv);        
        MracoCommond mc = new MracoCommond(loc,ttc);
        RemoteContro rc = new RemoteContro();
        rc.setCommond(ttc);
        rc.setCommond(loc);
        rc.setCommond(mc);
        //rc.buttonWasPressed(3);
        //rc.buttonWasPressed(1);
        rc.buttonWasPressed(2);
        
    }
}
当输入123不一样时,调用的命令不一样,实现了多个命令的包装
 

spring中set注入

1.把依赖类(Service)和被依赖类(Dao)所有交给Spring管理
2.依赖类中提供被依赖类的set方法
3.在xml中进行配置
当把一个类交给spring管理是要给出一个无参数的构造方法给spring使用
 

spring初始化bean多例建立暨Bean的延迟加载开启方式

<bean id="person" class="com.yjw.bean.Person1" factory-method="getPerson1" scope="prototype">
 
</bean>
scope="prototype"是建立多例,不配置此项,默认单例 
或者lazy-init值设置为true
 

spring使用静态工厂方法来实例化bean

public class Person1 implements Person{

 private Person1(String s){
  System.out.println(s);
 }

 public void say() {
  System.out.println("00000000000000");  
 }
 public static Person1 getPerson1(){
  return new Person1("pppppppppp");
  
 }
}


<bean id="person" class="com.yjw.bean.Person1" factory-method="getPerson1">

public class Test {

 public static void main(String[] args) {
  ApplicationContext  ctx =new  ClassPathXmlApplicationContext("applicationContext.xml");
 // UserService userservice =(UserService) ctx.getBean("person");
  /* User u = new User();
  u.setUsername("qq");
  u.setPassword("qq");
  userservice.save(u);*/
  Person person =  (Person) ctx.getBean("person");
  person.say();
  
 }
 
}

 

设计模式之观察者模式

概述:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,全部依赖于它的对象都获得通知并被自动更新。
适用性:
1.当一个抽象模型有两个方面,其中一个方面依赖于另外一方面。 将这两者封装在独立的对象中以使它们能够各自独立地改变和复用。 2.当对一个对象的改变须要同时改变其它对象,而不知道具体有多少对象有待改变。 3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁。
咱们以天气预报的服务为例,安卓和诺基亚购买天气预报的服务,也能够停用服务:
天气预报主体的接口:
public interface Subject {

    public void zhuce(Observer observer);

    public void remove(Observer observer);

    public void tongzhi();
}
天气预报的实现类:
public class WeatherData implements Subject {

    private int low;
    private int hight;
    private String weather;
    private List<Observer> list = new ArrayList<Observer>();

    public void setData(int low, int hight, String weather) {
        this.low = low;
        this.hight = hight;
        this.weather = weather;
        tongzhi();
    }

    public int getLow() {
        return low;
    }

    public int getHight() {
        return hight;
    }

    public String getWeather() {
        return weather;
    }

    public void zhuce(Observer observer) {
        if (!list.contains(observer)) {
            list.add(observer);
        }

    }

    public void remove(Observer observer) {
        if (list.contains(observer)) {
            list.remove(observer);
        }

    }

    public void tongzhi() {
        for (Observer o : list) {
            o.update(getLow(), getHight(), getWeather());
        }

    }

}
观察者的接口:
public interface Observer {

    void remove();

    void update(int low, int hight, String weather);
}
观察者的实现类:
public class Android implements Observer {

    private Subject subject;

    public Android() {
    }

    public Android(Subject subject) {
        this.subject = subject;
        this.subject.zhuce(this);
    }

    public void update(int low, int hight, String weather) {
        System.out.println("android" + low + "" + hight + weather);

    }

    public void remove() {
        subject.remove(this);
    }
}
public class Nokia implements Observer{
    
    private Subject subject;
    public Nokia(){}
    public Nokia(Subject subject){
        this.subject = subject;
        this.subject.zhuce(this);
    }

    public void update(int low, int hight, String weather) {
        System.out.println("nokia:"+low+"-"+hight+"-"+weather);
        
    }

    public void remove(){
    subject.remove(this);
}
}
测试类:

public class Test {
    public static void main(String[] args) {

        WeatherData wd = new WeatherData();
        wd.setData(1, 22, "晴朗");
        Android a = new Android(wd);
        wd.tongzhi();
        a.remove();
        Nokia n = new Nokia(wd);
        n.remove();
        wd.tongzhi();
        
    }
}
 

设计模式之状态模式

状态模式
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,全部依赖于它的对象都获得通知并被自动更新。
用性:1.一个对象的行为取决于它的状态,而且它必须在运行时刻根据状态改变它的行为。

    2.一个操做中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。
      这个状态一般用一个或多个枚举常量表示。
      一般,有多个操做包含这一相同的条件结构。
      State模式将每个条件分支放入一个独立的类中。
      这使得你能够根据对象自身的状况将对象的状态做为一个对象,这一对象能够不依赖于其余对象而独立变化。
状态模式在工做流或游戏等各类系统中有大量使用,甚至是这些系统的核心功能设计,例如
政府OA中,一个批文的状态有多种:未办;正在办理;正在批示;正在审核;已经完成等
各类状态,使用状态机能够封装这个状态的变化规则,从而达到扩充状态时,没必要涉及到状
态的使用者。 

在网络游戏中,一个游戏活动存在开始;开玩;正在玩;输赢等各类状态,使用状态模式就
能够实现游戏状态的总控,而游戏状态决定了游戏的各个方面,使用状态模式能够对整个游
戏架构功能实现起到决定的主导做用。 

状态模式实质: 
使用状态模式前,客户端外界须要介入改变状态,而状态改变的实现是琐碎或复杂的。 

使用状态模式后,客户端外界能够直接使用事件Event实现,根本没必要关心该事件致使如
何状态变化,这些是由状态机等内部实现。 

这是一种Event-condition-State,状态模式封装了condition-State部分。 

每一个状态造成一个子类,每一个状态只关心它的下一个可能状态,从而无形中造成了状态转换
的规则。若是新的状态加入,只涉及它的前一个状态修改和定义。 

状态转换有几个方法实现:一个在每一个状态实现next(),指定下一个状态;还有一种方法,
设定一个StateOwner,在StateOwner设定stateEnter状态进入和stateExit状
态退出行为。 

状态从一个方面说明了流程,流程是随时间而改变,状态是截取流程某个时间片。
例子:
操做当前状态类:
public class Context {
     private Weather weather;

        public void setWeather(Weather weather) {
            this.weather = weather;
        }

        public Weather getWeather() {
            return this.weather;
        }

        public String weatherMessage() {
            return weather.getWeather();
        }

}
状态接口:
public interface Weather {
     String getWeather();

}
状态实现类:
public class Sunshine implements Weather{
    public String getWeather() {
        return "阳光";
    }

}
public class Rain implements Weather{
     public String getWeather() {
            return "下雨";
        }

}
测试类:
public class Test {
    public static void main(String[] args) {
        Context ctx1 = new Context();
        ctx1.setWeather(new Sunshine());
        System.out.println(ctx1.weatherMessage());

        System.out.println("===============");


        ctx1.setWeather(new Rain());
        System.out.println(ctx1.weatherMessage());
    }

}

例子2:
public class Work {
private State current;

    public Work(double hour,boolean finish){
    current = new ForenoonState();
    this.hour = hour;
    this.finish = finish;
}
private double hour;
public double getHour() {
    return hour;
}

public State getCurrent() {
    return current;
}
public void setCurrent(State current) {
    this.current = current;
}
private boolean finish;
public boolean isFinish() {
    return finish;
}

public void writeProgram(){
    current.writeProgram(this);
}
}
public interface State {
void writeProgram(Work work);
}
public class ForenoonState implements State {

    @Override
    public void writeProgram(Work work) {
    if(work.getHour()<12){
        System.out.println("工做时间");
    }else {
    work.setCurrent(new NoonState());    
    work.writeProgram();
    }
        
    }

}
public class NoonState implements State {

    @Override
    public void writeProgram(Work work) {
        if(work.getHour()<13){
            System.out.println("午睡");
        }else {
            work.setCurrent(new AfterNoonState());
            work.writeProgram();
        }

    }

}
public class AfterNoonState implements State {

    @Override
    public void writeProgram(Work work) {
        if(work.getHour()<17){
            System.out.println("工做");
        }else {
            work.setCurrent(new EveningState());
            work.writeProgram();
        }

    }

}
public class EveningState implements State {

    @Override
    public void writeProgram(Work work) {
    if(work.isFinish()){
        work.setCurrent(new RestState());
        work.writeProgram();
    }else {
        if(work.getHour()<21){
            System.out.println("加班");
        }else {
            work.setCurrent(new SleepState());
            work.writeProgram();
        }
    }

    }

}
public class SleepState implements State {

    @Override
    public void writeProgram(Work work) {
        System.out.println("睡觉");

    }

}
 

设计模式之访问者模式

访问者模式主要是将不少操做都在一个接口中声明,在接口的实现类中都要实现这些操做,
在具体的访问者类中规定了须要调用实现类的哪一个方法,
例子以下:
访问者接口:
public interface Visitor {
public void visitString(StringElement stringE);
    
    public void visitFloat(FloatElement floatE);
    
    public void visitCollection(Collection<?> collection); 
    public void visitInt(IntElement inte);

}
访问者接口实现类
public class ConcreteVisitor implements Visitor{
    public void visitCollection(Collection<?> collection) {
        Iterator<?> iterator = collection.iterator();
        while (iterator.hasNext()) {
            Object o = iterator.next();
            if (o instanceof Visitable) {
                ((Visitable)o).accept(this);
            }
        }
    }

    public void visitFloat(FloatElement floatE) {
        System.out.println(floatE.getFe());
    }

    public void visitString(StringElement stringE) {
        System.out.println(stringE.getSe());
    }

    @Override
    public void visitInt(IntElement inte) {
        System.out.println(inte.getInts());
        
    }

}
操做类的接口:

public interface Visitable {
     public void accept(Visitor visitor);

}
操做类的具体实现类:
public class FloatElement implements Visitable{
private Float fe;
    
    public FloatElement(Float fe) {
        this.fe = fe;
    }
    
    public Float getFe() {
        return this.fe;
    }
    
    public void accept(Visitor visitor) {
        visitor.visitFloat(this);
    }

}
public class IntElement implements Visitable{
    private int ints;

    public int getInts() {
        return ints;
    }

    public IntElement(int i){
        this.ints = i;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visitInt(this);
        
    }

}
public class StringElement implements Visitable{
private String se;
    
    public StringElement(String se) {
        this.se = se;
    }
    
    public String getSe() {
        return this.se;
    }
    
    public void accept(Visitor visitor) {
        visitor.visitString(this);
    }

}
测试类:
public class Test {
    public static void main(String[] args) {
        Visitor visitor = new ConcreteVisitor();
        Visitable se = new StringElement("abc");
        se.accept(visitor);
        
        Visitable fe = new FloatElement(new Float(1.5));
        fe.accept(visitor);
        System.out.println("===========");
        List<Visitable> result = new ArrayList<Visitable>();
        result.add(new StringElement("abc"));
        result.add(new StringElement("abc"));
        result.add(new StringElement("abc"));
        result.add(new FloatElement(new Float(1.5)));
        result.add(new FloatElement(new Float(1.5)));
        result.add(new FloatElement(new Float(1.5)));
        visitor.visitCollection(result);
        Visitable is = new IntElement(2);
        is.accept(visitor);
    }

}

设计模式之模板模式

概述:
定义一个操做中的算法的骨架,而将一些步骤延迟到子类中。
TemplateMethod使得子类能够不改变一个算法的结构便可重定义该算法的某些特定步骤。
适用性:
1.一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。

    2.各子类中公共的行为应被提取出来并集中到一个公共父类中以免代码重复。
      首先识别现有代码中的不一样之处,而且将不一样之处分离为新的操做。
      最后,用一个调用这些新的操做的模板方法来替换这些不一样的代码。
例子以下:模板类:
public abstract class Template {
     public abstract void print();
        
        public void update() {
            System.out.println("公共的代码");
           System.out.println("下面是子类各自实现的代码");
                print();
            
        }
}
模板类的子类:
public class TemplateConcrete extends Template{
      @Override
        public void print() {
            System.out.println("这是子类的实现");
        }

}
测试类
public class Test {
    public static void main(String[] args) {
        Template temp = new TemplateConcrete();
        temp.update();
    }

}
 

extjs中为表格添加单选行单元格的事件

grid.addListener('cellclick', cellclick);
 function cellclick(grid, rowIndex, columnIndex, e) {
  var record = grid.getStore().getAt(rowIndex); 
  var fieldName = grid.getColumnModel().getDataIndex(columnIndex); 
  var data = record.get(fieldName);
  if(data==null){ //处理预览 
   var alias=record.get("Alias");
   window.open(url);
   //window.location.href="DoIpcammera?dowith=preview&&alias="+alias;
  }
 }
 

extjs自动生成排序数组

new Ext.grid.RowNumberer()
 

extjs中单选Radio的使用

var AddtoobarT = new Ext.form.Radio({
        name : "istoobar",//后台接受的名称
        inputValue : "true",//传后台的值
        boxLabel : "有",//页面显示的值
        checked : true//默认选择的值
       });
       var AddtoobarF = new Ext.form.Radio({
        name : "istoobar",
        inputValue : "false",
        boxLabel : "没有"
       });
       var Addtoobar = new Ext.form.RadioGroup({
        name : "toolbar",
        fieldLabel : "有无工具栏",
        items : [ AddtoobarT, AddtoobarF ],
        width : 200
       });
 

设计模式之职责链模式

职责链模式规定了一个请求,这个请求须要特定的对象去处理,当把这个请求交个一个对象,可是这个对象不负责处理这个请求,能够动态地交给其余对象处理,直到交给对的对象处理,这些对象都有处理请求的机会,只有当请求是该本身负责的时候才处理,不然交给其余对象。

下面以==============

要离职, 人事审批!

请求完毕

===========

要加薪, 项目经理审批!

========

要请假, 项目组长审批!

的规定,写一个职责链模式的例子:

这是全部请求的接口

public interface Request {

void getRequest();

}

请假的请求实现类

public class LeaveRequest implements Request{

@Override

public void getRequest() {

System.out.println("leave");

}

}

离职的请求实现类

public class DimissionRequest implements Request{

@Override

public void getRequest() {

System.out.println("dimission");

}

}

加薪的请求实现类

public class AddMoneyRequest implements Request{

@Override

public void getRequest() {

System.out.println("add money");

}

}

处理请求的接口

public interface RequestHandle {

void handleRequest(Request request);

}

Hr处理离职的请求

public class HRRequestHandle implements RequestHandle{

public void handleRequest(Request request) {

        if (request instanceof DimissionRequest) {

            System.out.println("要离职, 人事审批!");

        } 

        System.out.println("请求完毕");

    }

}

组长处理请假的请求

public class TLRequestHandle implements RequestHandle{

RequestHandle rh;

    

    public TLRequestHandle(RequestHandle rh) {

        this.rh = rh;

    }

    public void handleRequest(Request request) {

        if (request instanceof LeaveRequest) {

            System.out.println("要请假, 项目组长审批!");

        } else {

            rh.handleRequest(request);

        }

    }

}

经理处理加薪的请求

public class PMRequestHandle implements RequestHandle{

RequestHandle rh;

public PMRequestHandle(RequestHandle rh) {

    this.rh = rh;

}

public void handleRequest(Request request) {

    if (request instanceof AddMoneyRequest) {

        System.out.println("要加薪, 项目经理审批!");

    } else {

        rh.handleRequest(request);

    }

}

}

测试类

public class Test {

public static void main(String[] args) {

//先把全部的处理请求的对象组成职责链

        RequestHandle hr = new HRRequestHandle();

        RequestHandle tl = new TLRequestHandle(hr);//组长

        RequestHandle pm = new PMRequestHandle(tl);//经理

      

        Request dimissionRequest = new DimissionRequest();

        Request addMoneyRequest = new AddMoneyRequest();

        Request  leaveRequest = new LeaveRequest();

        System.out.println("==============");

        //人事处理离职请求

        

        pm.handleRequest(dimissionRequest);

        

        System.out.println("===========");

        //经理处理加薪请求

      

        pm.handleRequest(addMoneyRequest);

        

        System.out.println("========");

        //项目组长处理请假请求

       

        pm.handleRequest(leaveRequest);

    }

}



在使用时要调用最高级的职责调用者,由他去负责往下分配职责

 
mysql中is null和=null的含义

is null是判断某个字段是不是空,为空并不等价于空字符串或者数字0
=null  是判断某个值是否等于null,null=null,和null<>null都是false

 
mysql查询去除重复数据DISTINCT

select DISTINCT job   from emp where deptno=20

 
mysql函数中upper()的意思和排除空值

select name from user where upper(name) ='TOM' and sal is not null;
upper()函数的做用是把表中的name转换成大写再作比较

mysql求数值列的和,其中一列多是空

求薪金sal列和绩效comm列的和,comm多是空,
select sal+if(comm is null,0,comm) from emp;
当comm是空时,返回0,不空时返回comm的数值

 
struts2中用ognl访问普通类的构造方法

public class User implements Serializable{

 /**
  * 
  */
 private static final long serialVersionUID = 1L;
 
 private String name;
 public User(){
  System.out.println("===============");
 }
 public User(String name){
  this.name = name;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
 
 @Override
 public String toString() {
  return "user="+this.name;
 }

}

  <s:property value="new User('name')"/>

 
struts2用ognl访问普通类的静态属性和静态方法

public class Test {

 public static String NAME = "nametom";
 public static String test(){
  return "testtom";
 }
}



在struts.xml配置文件中加<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
  <s:property value="@Test@test()"/>
  <s:property value="@Test@NAME"/>

 
struts2中ognl直接访问action中的方法

public class UserAction extends ActionSupport{

 /**
  * 
  */
 private static final long serialVersionUID = 1L;
  public String  mm(){
  return "mm";
  
 }
}
   <s:property value="mm()"/>

 
struts2中ognl在视图中访问对象的方法

public class User implements Serializable{

 /**
  * 
  */
 private static final long serialVersionUID = 1L;
 
 private String name;
 public User(){
  System.out.println("===============");
 }
 public User(String name){
  this.name = name;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
 
 @Override
 public String toString() {
  return "user="+this.name;
 }

}

public class UserAction extends ActionSupport{

 /**
  * 
  */
 private static final long serialVersionUID = 1L;
 private String name;
 private User user;
 private Cat cat;
 
 @Override
 public String execute() throws Exception {
 // System.out.println(cat.getFriend().getName());
  return ActionSupport.SUCCESS;
  
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public User getUser() {
  return user;
 }
 public void setUser(User user) {
  this.user = user;
 }
 public Cat getCat() {
  return cat;
 }
 public void setCat(Cat cat) {
  this.cat = cat;
 }

}

  <s:property value="user.toString()"/>

 
struts2控制反转时建立对象必定要有参数是空的实体类的构造方法

public class User implements Serializable{

 /**
  * 
  */
 private static final long serialVersionUID = 1L;
 
 private String name;
 public User(){
  System.out.println("========空的构造方法=必须有======");
 }
 public User(String name){
  this.name = name;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
 
 

}



public class UserAction extends ActionSupport{

 /**
  * 
  */
 private static final long serialVersionUID = 1L;
 private String name;
 private User user;
 
 @Override
 public String execute() throws Exception {
  System.out.println(user.getName());
  return ActionSupport.SUCCESS;
  
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public User getUser() {
  return user;
 }
 public void setUser(User user) {
  this.user = user;
 }

}

 
struts2验证框架的使用

<body>
   <s:form action="user/tologin.action" method="post">
       <s:textarea name="id"></s:textarea>
       <s:password name="user.password"></s:password>
       <s:textfield name="user.name" label="ddddd" > </s:textfield>
       <s:submit value="提交" method="login"></s:submit>
       <s:submit value="打印" method="print"></s:submit>
   </s:form>
  </body>
验证框架的命名规则是Action类名字-action的bean名字-validation.xml,这个验证文件须要放在须要验证的.class文件同一目录下
例如UserAction-tologin-validation.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC 
          "-//Apache Struts//XWork Validator 1.0.2//EN"
          "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
          <validators>
              <field name="id">
                  <field-validator type="int">
                      <param name="min">10</param>
                      <param name="max">20</param>
                      <message>必须是整数</message>
                  </field-validator>
              </field>
              
              <field name="user.name">
                  <field-validator type="requiredstring">
                      <message>name必须填写</message>
                  </field-validator>
              </field>
          </validators>

在struts-xml中的配置
<action name="tologin" class="UserAction" >
                <result>/WEB-INF/user/list.jsp</result>
                <result name="input">/WEB-INF/user/user.jsp</result>
            </action>
 

struts2一个表单多种提交ognl

 <body>
   <s:form action="user/tologin.action" method="post">
       <s:textarea name="id"></s:textarea>
       <s:password name="user.password"></s:password>
       <s:textfield name="user.name"></s:textfield>
       <s:submit value="提交" method="login"></s:submit>
       <s:submit value="打印" method="print"></s:submit>
   </s:form>
  </body>
<action name="tologin" class="UserAction" >
                <result>/WEB-INF/user/list.jsp</result>
            </action>

public class UserAction extends ActionSupport{

    private static final long serialVersionUID = 1L;

    private User user;
    private String id;

    @Override
    public String execute() throws Exception {
        
        return ActionSupport.SUCCESS;
    }

    public String login(){

        return ActionSupport.SUCCESS;
    }

    public String print(){
        System.out.println(user.getName());
        System.out.println(user.getPassword());
        System.out.println(id);
        return ActionSupport.SUCCESS;
    }
    

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
    
    
}
 

struts2重定向到jsp传值

 <a href="hello?name=1">重定向传参数</a>
<package name="default" namespace="/" extends="struts-default">
 <default-action-ref name="hello"></default-action-ref>
  <action name="hello" class="UserAction">   
   <result type="redirect">/index2.jsp?t=${name}</result>
  </action>
 </package>

 

public class UserAction extends ActionSupport{

 /**
  * 
  */
 private static final long serialVersionUID = 1L;
 private String name;
 @Override
 public String execute() throws Exception {
  System.out.println(name);
  return ActionSupport.SUCCESS;
  
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }

}
  <s:property value="#parameters.t"/>

 
struts2中四种实现request,session,application的方法

第一种
public class UserAction extends ActionSupport{

 /**
  * 
  */
 private static final long serialVersionUID = 1L;
 private String name;
 private Map session;
 private Map request;
 private Map application;
 @Override
 public String execute() throws Exception {
  session =  ActionContext.getContext().getSession();
  request = (Map) ActionContext.getContext().get("request");
  application =  ActionContext.getContext().getApplication();
  session.put("sk", "sv");
  request.put("rk", "rv");
  application.put("ak", "av");
  System.out.println(name);
  return ActionSupport.SUCCESS;
  
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }

}


第二种

public class DepAction extends ActionSupport implements RequestAware,SessionAware,ApplicationAware{

 private Map<String, Object> request;
 private Map<String, Object> session;
 private Map<String, Object> application;
 
 
 public void setRequest(Map<String, Object> request) {
  this.request = request;
  
 }

 public void setSession(Map<String, Object> session) {
  this.session = session;
  
 }

 public void setApplication(Map<String, Object> application) {
  this.application = application;
  
 }

}


第三种

public class CarAction implements ServletRequestAware{
 private HttpServletRequest request;
 private HttpSession session;
 private ServletContext application;

 public void setServletRequest(HttpServletRequest request) {
  this.request = request;
  this.session = request.getSession();
  this.application = session.getServletContext();
  
 }

}


第四种

public class HomeAction extends ActionSupport{
 
 private HttpServletRequest request;
 private HttpSession session;
 private ServletContext application;

 public HomeAction (){
  request = ServletActionContext.getRequest();
  session = request.getSession();
  application = session.getServletContext();
}

}

 

struts2的标签ognl

     摘要: Struts2经常使用标签总结 一 介绍 1.Struts2的做用 Struts2标签库提供了主题、模板支持,极大地简化了视图页面的编写,并且,struts2的主题、模板都提供了很好的扩展性。实现了更好的代码复用。Struts2容许在页面中使用自定义组件,这彻底能知足项目中页面显示复杂,多变的需求。 Struts2的标签库有一个巨大的改进之处,struts2标签库的标签不依赖于任何...   阅读全文
 

struts2值栈取值和session,request,application的取值

在strut2中因此的值都在值栈中存放,在页面中加入<s:debug></s:debug>标签,就能够点击显示出当前值栈中的全部值,如图
能够经过 <s:property value="name"/>标签获得值栈中的值,value的值是PropertyName,就能够获得对应的value 

在action中session,request,application都是Map数据类型的
private Map session;
 private Map request;
 private Map application;
session =  ActionContext.getContext().getSession();
  request = (Map) ActionContext.getContext().get("request");
  application =  ActionContext.getContext().getApplication();
  session.put("sk", "sv");
  request.put("rk", "rv");
  application.put("ak", "av");
想在页面中取到相应的值;
 <s:property value="#session.sk"/>
 <s:property value="#request.rk"/>
 <s:property value="#application.ak"/>
使用<s:debug></s:debug>观看他们都是存放在栈区,#+名称就能够取到值
 

struts2命名空间和访问路径

namespace决定来了action的访问路径,当namespace=“”时,能够接受全部路径的action,namespace=“/”,

或者"/xxx,或者"/xxx/yyy",对应的action访问路径是/index.action,或者/xxx/index.action,或

者/xxx/yyy/index.action.


<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort

()+path+"/";
%>
<base href="<%=basePath%>">
在使用namespace时容易出现路径问题,在会出现路径问题的jsp页面中加上base标签,就不会了。

 

java取得实时上周的时间

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class Test {
    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);

        calendar.add(Calendar.DATE, -7);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        Date    sTime = calendar.getTime();
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        Date    eTime = calendar.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String s = sdf.format(sTime) + " 00:00:00";
        String e = sdf.format(eTime) + " 23:59:59";
        System.out.println(s);
        System.out.println(e);
    }
}

struts2实现登陆拦截器和验证方法

     摘要: 在struts2中的拦截器的定义是先定义一个类实现Interceptor接口,重写intercept方法。下面是实现登陆验证的拦截器。 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts C...   阅读全文
 

java复习

Typeof()返回值有6中可能:number,string,boolean,object,function,undefined

Prompt(“请输入名称”)返回字符

eval(“”)能够把“”中的字符串执行

在java中继承的构造方法的规则:

1.       子类的构造的过程当中必须调用其父类的构造方法。

2.       子类能够在本身的构造方法中使用super(argument—list)调用父类的构造方法。

3.       使用this(argument—list)调用本身的另外的构造方法。

4.       若是调用super,必须卸载子类构造方法的第一行。

5.       若是子类的构造方法中没有显示调用父类工做服,系统默认调用父类无参数的构造方法。

6.       若是子类构造方法中没有显示调用父类的构造方法,而父类中又没有无参数的构造方法,编译出错。

哈希编码:每一个对象都有一个独一无二的哈希编码,经过这个哈希编码能够找到这个对象。

多态中动态绑定规则;1.有继承,2.有重写(子类重写父类中的方法),3.父类引用指向子类对象。

Public void getId(final int i){}表示i在此方法中不一样被修改

 

hibernate对数据库的创建和删除

<!--?启动时删数据库中的表,而后建立,退出时不删除数据表

<property?name="hibernate.hbm2ddl.auto">create</property>-->

<!--?启动时删数据库中的表,而后建立,退出时自动删除全部表

<property?name="hibernate.hbm2ddl.auto">create-drop</property>-->

<!--?自动修改,若是表结构与实体类不一致,那么就修改表使它们一致,数据会保留

<property?name="hibernate.hbm2ddl.auto">update</property>-->

<!--?自动校验,若是表结构与实体类不一致,那么不作任何操做,报错

<property?name="hibernate.hbm2ddl.auto">validate</property>-->

 

java io读取文本文件

public class ReadSql {

 public static void readsql(String filePath) throws Exception{
  String encoding = "gbk";
  File file = new File(filePath);
  if(file.isFile()&&file.exists()){
   InputStreamReader reader = new InputStreamReader(new FileInputStream(file),encoding);
  BufferedReader bufferedReader = new BufferedReader(reader);
   String line = null;
   while ((line = bufferedReader.readLine())!=null) {    
     System.out.println(line.toString());           
   }
   reader.close();
  }
 }
 public static void main(String[] args) throws Exception {
  System.out.println("=================================================");
  ReadSql.readsql("c:/rr.txt"); 
  
  System.out.println("=================================================");
 }
}

 

阿里云注册用户创建本身的网站

阿里云服务平台注册至关于申请到了一台服务器主机,想运行java web项目很简单,安装jdk,tomcat,数据库,把编译好的项目放在tomcat中,启动tomcat,在外网直接访问阿里云主机ip和端口,项目名称,就能够了
 

java网络编程中tcp和udp

在网络编程中,先启动service,再启动clent。
1.tcp
服务端
public class Service {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(6666);
System.out.println("等待");
while (true) {
Socket socket  =ss.accept();
InputStream is = socket.getInputStream();
DataInputStream dataInputStream = new DataInputStream(is);
System.out.println(dataInputStream.readUTF());
dataInputStream.close();
socket.close();
}
}
}
客户端
public class CientSocket {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1",6666);
OutputStream outputStream = socket.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeUTF("333333333");
dataOutputStream.flush();
dataOutputStream.close();
socket.close();
}
}
udp通讯,是不区分客户端和服务端的
public class Service {
public static void main(String[] args) throws Exception {
byte buf[] = new byte[1024];
DatagramPacket dPacket = new DatagramPacket(buf, buf.length);
DatagramSocket dSocket = new DatagramSocket(5678);
while (true) {
dSocket.receive(dPacket);
System.out.println(new String(buf,0,dPacket.getLength()));
}
}
}
public class UdpClient {
public static void main(String[] args) throws Exception{
while (true) {
byte[] buf = (new String("hello")).getBytes();
DatagramPacket dpPacket = new DatagramPacket(buf, buf.length, new InetSocketAddress("127.0.0.1", 5678));
//本身占用9999端口
DatagramSocket dSocket = new DatagramSocket(9999);
dSocket.send(dpPacket);
dSocket.close();
}
}
}
 

web.xml加载过程

当咱们去启动一个 WEB 项目的时候, 容器(包括 JBoss, Tomcat 等)首先会去读项目的 web.xml 配置文件里面的信息, 

当这一步骤没有出错而且完成以后, 项目才能正常的被启动起来。

1> 首先是, 容器会先读 <context-param></context-param> 节点, 并建立一个 ServletContext 实例, 以节点的 name 做为键, value 做为值, 

   存储到上下文环境中。

2> 接着, 容器会去读 <listener></listener> 节点, 根据配置的 class 类路径来建立监听。

3> 接着, 容器去读 <filter></filter> 节点, 根据指定的类路径来实例化过滤器。

以上都是在 WEB 项目尚未彻底启动起来的时候就已经完成了的工做。若是系统中有用到 Servlet, 则 Servlet 是在第一次发起请求的时候被实例化的,

且通常不会被容器销毁, 它能够服务于多个用户的请求。因此, Servlet 的初始化都要比上面提到的那几个要迟。

总的来讲, web.xml 的加载顺序是: context-param --> listener --> filter --> servlet

其中, 若是 web.xml 中出现了相同的节点, 则是按照在配置文件中出现的前后顺序来加载的。

下面引入一个小列子来讲明:

  
<?xml version="1.0" encoding="UTF-8"?>
  
  <listener>
    <listener-class>net.yeah.fancydeepin.listener.AppStartListener</listener-class>
  </listener>
  
  <!-- 为了更好的说明, 特地将 context-param 放在 listener 后面 -->
  <context-param>
    <param-name>technology</param-name>
    <param-value>java,javascript,ajax,css,html</param-value>
  </context-param>
  
  <filter>
    <filter-name>ReDespatcherFilter</filter-name>
    <filter-class>net.yeah.fancydeepin.filter.ReDespatcherFilter</filter-class>
    <init-param>
      <param-name>it</param-name>
      <param-value>android, python, c</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>ReDespatcherFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <filter>
    <filter-name>ReDespatcherFilter2</filter-name>
    <filter-class>net.yeah.fancydeepin.filter.ReDespatcherFilter2</filter-class>
    <init-param>
      <param-name>mail</param-name>
      <param-value>fancydeepin@yeah.net</param-value>
    </init-param>
  </filter>

</web-app>
  

 

  
package net.yeah.fancydeepin.listener;

import java.util.Arrays;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class AppStartListener implements ServletContextListener{

    public void contextInitialized(ServletContextEvent contextEvent) {
        System.out.println("********************************************");
        ServletContext context = contextEvent.getServletContext();
        List<String> params = Arrays.asList(context.getInitParameter("technology").split(","));
        for(String param : params){
            System.out.print(param + "\t");
        }
        System.out.println("\n********************************************");
    }

    public void contextDestroyed(ServletContextEvent contextEvent) {
        
    }

}
  

 

  
package net.yeah.fancydeepin.filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class ReDespatcherFilter implements Filter {
    
    public void init(FilterConfig filterConfig) throws ServletException {

        System.out.println("============================================");
        System.out.println(filterConfig.getInitParameter("it"));
        System.out.println("============================================");
    }
    
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,ServletException{
        
        chain.doFilter(request, response);
    }
    
    public void destroy() {
        
    }
}
  

 

  
package net.yeah.fancydeepin.filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class ReDespatcherFilter2 implements Filter {
    
    public void init(FilterConfig filterConfig) throws ServletException {

        System.out.println("++++++++++++++++++++++++++++++++++++++++++++");
        System.out.println(filterConfig.getInitParameter("mail"));
        System.out.println("++++++++++++++++++++++++++++++++++++++++++++");
    }
    
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,ServletException{
        
        chain.doFilter(request, response);
    }
    
    public void destroy() {
        
    }
}
  


后台启动输出结果:

 

Context上下文的区别

在 java 中, 常见的 Context 有不少, 

 像: ServletContext, ActionContext, ServletActionContext, ApplicationContext, PageContext, SessionContext ...

 那么, Context 到底是什么东西呢? 直译是上下文、环境的意思。好比像: "今天我收到了一束花, 男友送的!" 又或者 "今天我收到了一束花, 送花的人送错了的!"

 一样是收到一束花, 在不一样的上下文环境中表达的意义是不同的。

 一样的, Context 其实也是同样, 它离不开所在的上下文环境, 不然就是断章取义了。

 另外, 在网络上也有些人把 Context 当作是一些公用信息或者把它看作是一个容器的, 我的以为这种解释稍好。

 接下来讲说 ServletContext, ActionContext, ServletActionContext。
 
 1> ServletContext

 一个 WEB 运用程序只有一个 ServletContext 实例, 它是在容器(包括 JBoss, Tomcat 等)彻底启动 WEB 项目以前被建立, 生命周期伴随整个 WEB 运用。

 当在编写一个 Servlet 类的时候, 首先是要去继承一个抽象类 HttpServlet, 而后能够直接经过 getServletContext() 方法来得到 ServletContext 对象。

 这是由于 HttpServlet 类中实现了 ServletConfig 接口, 而 ServletConfig 接口中维护了一个 ServletContext 的对象的引用。

 利用 ServletContext 可以得到 WEB 运用的配置信息, 实如今多个 Servlet 之间共享数据等。

 eg:
 

  
<?xml version="1.0" encoding="UTF-8"?>

  <context-param>
    <param-name>url</param-name>
    <param-value>jdbc:oracle:thin:@localhost:1521:ORC</param-value>
  </context-param>
  <context-param>
    <param-name>username</param-name>
    <param-value>scott</param-value>
  </context-param>
  <context-param>
    <param-name>password</param-name>
    <param-value>tigger</param-value>
  </context-param>
  
  <servlet>
    <servlet-name>ConnectionServlet</servlet-name>
    <servlet-class>net.yeah.fancydeepin.servlet.ConnectionServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ConnectionServlet</servlet-name>
    <url-pattern>/ConnectionServlet.action</url-pattern>
  </servlet-mapping>
  
  <servlet>
    <servlet-name>PrepareConnectionServlet</servlet-name>
    <servlet-class>net.yeah.fancydeepin.servlet.PrepareConnectionServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>PrepareConnectionServlet</servlet-name>
    <url-pattern>/PrepareConnectionServlet.action</url-pattern>
  </servlet-mapping>

</web-app>
  

 

  
package net.yeah.fancydeepin.servlet;

import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class PrepareConnectionServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public void init() throws ServletException {
        
        ServletContext context = getServletContext();
        String url = context.getInitParameter("url");
        String username = context.getInitParameter("username");
        String password = context.getInitParameter("password");
        context.setAttribute("url", url);
        context.setAttribute("username", username);
        context.setAttribute("password", password);
    }

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        response.sendRedirect("ConnectionServlet.action");
    }
}

  

 

  
package net.yeah.fancydeepin.servlet;

import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;

public class ConnectionServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        
        ServletContext context = getServletContext();
        System.out.println("***************************************");
        System.out.println("URL: " + context.getAttribute("url"));
        System.out.println("Username: " + context.getAttribute("username"));
        System.out.println("Password: " + context.getAttribute("password"));
        System.out.println("***************************************");
        super.service(request, response);
    }
}
  

 
 当访问 PrepareConnectionServlet.action 时, 后台打印输出:
 

  
***********************************************
URL:  jdbc:oracle:thin:@localhost:1521:ORC
Username:  scott
Password:  tigger
***********************************************
  


 
 2> ActionContext
 
 ActionContext 是当前 Action 执行时的上下文环境, ActionContext 中维护了一些与当前 Action 相关的对象的引用, 

 如: Parameters (参数), Session (会话), ValueStack (值栈), Locale (本地化信息) 等。
 
 在 Struts1 时期, Struts1 的 Action 与 Servlet API 和 JSP 技术的耦合度都很紧密, 属于一个侵入式框架:

  
public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response){
    // TODO Auto-generated method stub
    return null;
}
  


 到了 Struts2 时期, Struts2 的体系结构与 Struts1 之间存在很大的不一样。Struts2 在 Struts1 的基础上与 WebWork 进行了整合, 成为了一个全新的框架。

 在 Struts2 里面, 则是经过 WebWork 来将与 Servlet 相关的数据信息转换成了与 Servlet API 无关的对象, 即 ActionContext 对象。

 这样就使得了业务逻辑控制器可以与 Servlet API 分离开来。另外, 因为 Struts2 的 Action 是每一次用户请求都产生一个新的实例, 所以, 

 ActionContext 不存在线程安全问题, 能够放心使用。

  
package net.yeah.fancydeepin.action;

import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;

public class ContextAction extends ActionSupport {

    private static final long serialVersionUID = 1L;
    private String username;
    private String password;

    public String execute(){
        
        ActionContext context = ActionContext.getContext();
        ValueStack value = context.getValueStack();
        value.set("username", username);
        value.set("password", password);
        Map<String, Object> session = context.getSession();
        session.put("url", "http://www.blogjava.net/fancydeepin");
        return SUCCESS;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

  

 

  
<s:property value="username"/><BR>
<s:property value="password"/><BR>
<s:property value="#session.url"/><BR>
  

 

 当访问 context.action 并传给相应的参数的时候, 在浏览器中会输出相应的信息。

 留意到上面 Struts2 的 Action 中并有没添加属性的 getting 方法, 而是手动的将参数值放到值栈(ValueStack)中的, 不然页面是得不到参数来输出的。

 3> ServletActionContext

 首先, ServletActionContext 是 ActionContext 的一个子类。ServletActionContext 从名字上来看, 意味着它与 Servlet API 紧密耦合。


 ServletActionContext 的构造子是私有的, 主要是提供了一些静态的方法, 能够用来获取: ActionContext, ActionMapping, PageContext, 

 HttpServletRequest, HttpServletResponse, ServletContext, ValueStack, HttpSession 对象的引用。
 

  
public String execute(){
        
    //或 implements ServletRequestAware
    HttpServletRequest request = ServletActionContext.getRequest();
    //或 implements ServletResponseAware
    HttpServletResponse response = ServletActionContext.getResponse();
    //或 implements SessionAware
    HttpSession session = request.getSession();
    //或 implements ServletContextAware
    ServletContext context = ServletActionContext.getServletContext();
        
    return SUCCESS;
}
 

java递归阶乘

public static int method(int n){
if(n==1){
return 1;
}else {
return n*method(n-1);
}
}
public static long fab(int i){
if(i==1||i==2){
return 1;
}else {
return fab(i-1)+fab(i-2);
}
}
 

把编译好的web工程用cmd打成war包或者jar包

1.先把编辑好的web文件放在c盘下,好比项目名是hello
2.打开cmd,进入hello中,c:\hello>
3.输入jar cvf hello.war .    ,就能够在hello文件夹中找到hello.war
输入jar -cvf hello.jar *.*;
 

DATE_FORMAT函数的用法

DATE_FORMAT() 函数用于以不一样的格式显示日期/时间数据。
语法是
DATE_FORMAT(date,format)
date 参数是合法的日期。 format 规定日期/时间的输出格式。

下面的脚本使用 DATE_FORMAT() 函数来显示不一样的格式。咱们使用 NOW() 来得到当前的日期/时间:
DATE_FORMAT(NOW(),'%b %d %Y %h:%i %p') DATE_FORMAT(NOW(),'%m-%d-%Y') DATE_FORMAT(NOW(),'%d %b %y') DATE_FORMAT(NOW(),'%d %b %Y %T:%f')
结果相似:
Dec 29 2008 11:45 PM 12-29-2008 29 Dec 08 29 Dec 2008 16:25:46.635
当数据库中有个字段time,数据格式是
2013-03-25 14:35:20
按年查询:
DATE_FORMAT(timetext,'%Y')=‘2013’
按年排序
DATE_FORMAT(timetext,'%Y')
按月查询
DATE_FORMAT(timetext,'%m')='03
'
 

java.util.ConcurrentModificationException

这个问题是说,你不能在对一个List进行遍历的时候将其中的元素删除掉
解决办法是,你能够先将要删除的元素用另外一个list装起来,等遍历结束再remove掉
能够这样写
List delList = new ArrayList();//用来装须要删除的元素
for(Information ia:list)
if(ia.getId()==k){
n++;
delList.add(ia);
}
list.removeAll(delList);//遍历完成后执行删除
 

随机产生4位和6位数字字符串

package com.test; 


/** 
 * 动态生成随机字符数组 
 *  
 * 
 */ 
public class ShortMessageCodeUntil 



    /** 
     * 随机生成4位数字字符数组 
     *  
     * @return rands 
     */ 
    public static char[] generateCheckCode() 
    { 
        String chars = "0123456789"; 
        char[] rands = new char[4]; 
        for (int i = 0; i < 4; i++) 
        { 
            int rand = (int) (Math.random() * 10); 
            rands[i] = chars.charAt(rand); 
        } 
        return rands; 
    } 


    /** 
     * 随机生成6位数字字符数组 
     *  
     * @return rands 
     */ 
    public static char[] generateCheckPass() 
    { 
        String chars = "0123456789"; 
        char[] rands = new char[6]; 
        for (int i = 0; i < 6; i++) 
        { 
            int rand = (int) (Math.random() * 10); 
            rands[i] = chars.charAt(rand); 
        } 
        return rands; 
    } 
public static void main(String[] args) {
    ShortMessageCodeUntil sm = new ShortMessageCodeUntil();
    System.out.println(sm.generateCheckCode());
    System.out.println(sm.generateCheckPass());
}

}
 

得的html中a标签中的值

<div><a href="javascript:void(0)" class="aa" rel="<%=k %>">点击</a></div>
 <script type="text/javascript">
        $(document).ready(function(){
            $(".aa").click(function(){        
            
                    var id = $(this).attr("rel");
                    $.get('<%=basePath%>wenshi/setDaPeng', {
            p :id 
        }, function(r,s) {
       
    
        });
            });
        });
    </script>
 

建造者模式

Builder模式定义: 将一个复杂对象的构建与它的表示分离,使得一样的构建过程能够建立不一样的表示.
Builder模式是一步一步建立一个复杂的对象,它容许用户能够只经过指定复杂对象的类型和内容就能够构建它们.
用户不知道内部的具体构建细节.Builder模式是很是相似抽象工厂模式,细微的区别大概只有在反复使用中才能体会到.
为什么使用? 是为了将构建复杂对象的过程和它的部件解耦.注意: 是解耦过程和部件.
由于一个复杂的对象,不但有不少大量组成部分,如汽车,有不少部件:车轮方向盘 发动机还有各类小零件等等,
部件不少,但远不止这些,如何将这些部件装配成一辆汽车,这个装配过程也很复杂(须要很好的组装技术),Builder模式就是为了将部件和组装过程分开.
如何使用? 首先假设一个复杂对象是由多个部件组成的,Builder模式是把复杂对象的建立和部件的建立分别开来,分别用Builder类和Director类来表示.
首先,须要一个接口,它定义如何建立复杂对象的各个部件:
public interface Builder {
//建立部件A 好比建立汽车车轮
 void buildPartA();
 //建立部件B 好比建立汽车方向盘
 void buildPartB();
 //建立部件C 好比建立汽车发动机 
 void buildPartC();
 //返回最后组装成品结果 (返回最后装配好的汽车)
 //成品的组装过程不在这里进行,而是转移到下面的Director类中进行. //从而实现了解耦过程和部件
 Product getResult();
}
 用Director构建最后的复杂对象,而在上面Builder接口中封装的是如何建立一个个部件(复杂对象是由这些部件组成的),也就是说Director的内容是如何将部件最后组装成成品:
 public class Director {
private Builder builder;
public Director( Builder builder ) {
 this.builder = builder; 
 } // 将部件partA partB partC最后组成复杂对象 //这里是将车轮方向盘和发动机组装成汽车的过程
 public void construct() { 
 builder.buildPartA();
 builder.buildPartB();
 builder.buildPartC();
}
}
Builder的具体实现ConcreteBuilder: 经过具体完成接口Builder来构建或装配产品的部件;
定义并明确它所要建立的是什么具体东西; 提供一个能够从新获取产品的接口:
public class ConcreteBuilder implements Builder {
Part partA, partB, partC; public void buildPartA() { 
//这里是具体如何构建partA的代码 }; 
public void buildPartB() {
 //这里是具体如何构建partB的代码 };
 public void buildPartC() {
 //这里是具体如何构建partB的代码 };
 public Product getResult() { //返回最后组装成品结果 };
 复杂对象:产品Product:
public interface Product { }
复杂对象的部件:
public interface Part { }
咱们看看如何调用Builder模式:
ConcreteBuilder builder = new ConcreteBuilder();
 Director director = new Director( builder );
 director.construct(); 
 Product product = builder.getResult();
 
}

Builder模式的应用在Java实际使用中,咱们常常用到"池"(Pool)的概念,当资源提供者没法提供足够的资源,而且这些资源须要被不少用户反复共享时,就须要使用池.
"池"实际是一段内存,当池中有一些复杂的资源的"断肢"(好比数据库的链接池,也许有时一个链接会中断),若是循环再利用这些"断肢",将提升内存使用效率,提升池的性能.修改Builder模式中Director类使之能诊断"断肢"断在哪一个部件上,再修复这个部件.
 

单例模式

单态定义: Singleton模式主要做用是保证在Java应用程序中,一个类Class只有一个实例存在。
在不少操做中,好比创建目录 数据库链接都须要这样的单线程操做。
还有, singleton可以被状态化; 这样,多个单态类在一块儿就能够做为一个状态仓库同样向外提供服务,好比,你要论坛中的帖子计数器,每次浏览一次须要计数,单态类可否保持住这个计数,而且能synchronize的安全自动加1,若是你要把这个数字永久保存到数据库,你能够在不修改单态接口的状况下方便的作到。
另外方面,Singleton也可以被无状态化。提供工具性质的功能, Singleton模式就为咱们提供了这样实现的可能。使用Singleton的好处还在于能够节省内存,由于它限制了实例的个数,有利于Java垃圾回收(garbage collection)。咱们经常看到工厂模式中类装入器(class loader)中也用Singleton模式实现的,由于被装入的类实际也属于资源。
public class Singleton {
private Singleton(){}
//在本身内部定义本身一个实例,是否是很奇怪? //注意这是private 只供内部调用
private static Singleton instance = new Singleton();
//这里提供了一个供外部访问本class的静态方法,能够直接访问
public static Singleton getInstance() {
 return instance; 
 } 
 }
第二种形式:
public class Singleton {
private Singleton(){}
private static Singleton instance = null;
 public static synchronized Singleton getInstance() {
 //这个方法比上面有所改进,不用每次都进行生成对象,只是第一次 //使用时生成实例,提升了效率!
 if (instance==null) 
 instance=new Singleton();
 return instance; 
 }
}
使用Singleton.getInstance()能够访问单态类。
上面第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,之后就不用再生成了。
注意到lazy initialization形式中的synchronized,这个synchronized很重要,若是没有synchronized,那么使用getInstance()是有可能获得多个Singleton
实例。
通常认为第一种形式要更加安全些。
 

设计模式之工厂模式

工厂模式定义:提供建立对象的接口
为何工厂模式是如此经常使用?由于工厂模式就至关于建立实例对象的new,咱们常常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来建立实例对象的,因此之后new时就要多个心眼,是否能够考虑实用工厂模式,虽然这样作,可能多作一些工做,但会给你系统带来更大的可扩展性和尽可能少的修改量。
咱们以类Sample为例, 若是咱们要建立Sample的实例对象:
Sample sample=new Sample();
但是,实际状况是,一般咱们都要在建立sample实例时作点初始化的工做,好比赋值查询数据库等。
首先,咱们想到的是,能够使用Sample的构造函数,这样生成实例就写成:
Sample sample=new Sample(参数);
可是,若是建立sample实例时所作的初始化工做不是象赋值这样简单的事,多是很长一段代码,若是也写入构造函数中,那你的代码很难看了(就须要Refactor重整)。
为何说代码很难看,初学者可能没有这种感受,咱们分析以下,初始化工做若是是很长一段代码,说明要作的工做不少,将不少工做装入一个方法中,至关于将不少鸡蛋放在一个篮子里,是很危险的,这也是有背于Java面向对象的原则,面向对象的封装(Encapsulation)
和分派(Delegation)告诉咱们,尽可能将长的代码分派“切割”成每段,将每段再“封装”起来(减小段和段之间偶合联系性),这样,就会将风险分散,之后若是须要修改,只要更改每段,不会再发生牵一动百的事情。
在本例中,首先,咱们须要将建立实例的工做与使用实例的工做分开, 也就是说,让建立实例所须要的大量初始化工做从Sample的构造函数中分离出去。
这时咱们就须要Factory工厂模式来生成对象了,不能再用上面简单new Sample(参数)。还有,若是Sample有个继承如MySample, 按照面向接口编程,咱们须要将Sample抽象成一个接口.如今Sample是接口,有两个子类MySample 和HisSample .咱们要实例化他们时,以下:
Sample mysample=new MySample(); Sample hissample=new HisSample();
随着项目的深刻,Sample可能还会"生出不少儿子出来", 那么咱们要对这些儿子一个个实例化,更糟糕的是,可能还要对之前的代码进行修改:加入后来生出儿子的实例.这在传统程序中是没法避免的.
但若是你一开始就有意识使用了工厂模式,这些麻烦就没有了.
工厂方法你会创建一个专门生产Sample实例的工厂:
public class Factory{
public static Sample creator(int which){
//getClass 产生Sample 通常可以使用动态类装载装入类。 if (which==1) return new SampleA(); else if (which==2)
return new SampleB();
}
}
那么在你的程序中,若是要实例化Sample时.就使用
Sample sampleA=Factory.creator(1);
这样,在整个就不涉及到Sample的具体子类,达到封装效果,也就减小错误修改的机会
使用工厂方法要注意几个角色,首先你要定义产品接口,如上面的Sample,产品接口下有Sample接口的实现类,如SampleA,其次要有一个factory类,用来生成产品Sample,
进一步稍微复杂一点,就是在工厂类上进行拓展,工厂类也有继承它的实现类concreteFactory了。
抽象工厂 工厂模式中有: 工厂方法(Factory Method) 抽象工厂(Abstract Factory).
这两个模式区别在于须要建立对象的复杂程度上。若是咱们建立对象的方法变得复杂了,如上面工厂方法中是建立一个对象Sample,若是咱们还有新的产品接口Sample2.
这里假设:Sample有两个concrete类SampleA和SamleB,而Sample2也有两个concrete类Sample2A和SampleB2
那么,咱们就将上例中Factory变成抽象类,将共同部分封装在抽象类中,不一样部分使用子类实现,下面就是将上例中的Factory拓展成抽象工厂:
public abstract class Factory{
public abstract Sample creator();
public abstract Sample2 creator(String name);
}
public class SimpleFactory extends Factory{
public Sample creator(){ ......... return new SampleA }
public Sample2 creator(String name){ ......... return new Sample2A }
}
public class BombFactory extends Factory{
public Sample creator(){ ...... return new SampleB }
public Sample2 creator(String name){ ...... return new Sample2B }
}
从上面看到两个工厂各自生产出一套Sample和Sample2,也许你会疑问,为何我不能够使用两个工厂方法来分别生产Sample和Sample2?
抽象工厂还有另一个关键要点,是由于 SimpleFactory内,生产Sample和生产Sample2的方法之间有必定联系,因此才要将这两个方法捆绑在一个类中,这个工厂类有其自己特征,也许制造过程是统一的,好比:制造工艺比较简单,因此名称叫SimpleFactory。
 

jquery选项卡

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title></title>

<!--   引入jQuery -->
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript" >
//<![CDATA[
    $(function(){
        var $div_li =$("div.tab_menu ul li");
        $div_li.click(function(){
            $(this).addClass("selected")            //当前<li>元素高亮
                   .siblings().removeClass("selected");  //去掉其它同辈<li>元素的高亮
            var index =  $div_li.index(this);  // 获取当前点击的<li>元素 在 所有li元素中的索引。
            $("div.tab_box > div")       //选取子节点。不选取子节点的话,会引发错误。若是里面还有div 
                    .eq(index).show()   //显示 <li>元素对应的<div>元素
                    .siblings().hide(); //隐藏其它几个同辈的<div>元素
        }).hover(function(){
            $(this).addClass("hover");
        },function(){
            $(this).removeClass("hover");
        })
    })
//]]>
</script>
</head>
<body>

<div class="tab">
    <div class="tab_menu">
        <ul>
            <li class="selected">时事</li>
            <li>体育</li>
            <li>娱乐</li>
        </ul>
    </div>
    <div class="tab_box"> 
         <div>时事</div>
         <div class="hide">体育</div>
         <div class="hide">娱乐</div>
    </div>
</div>

</body>
</html>
 

jquery控制字体大小

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>

 <!--   引入jQuery -->
 <script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">
    $(function(){
        $("span").click(function(){
            var thisEle = $("#para").css("font-size"); 
            var textFontSize = parseFloat(thisEle , 10);
            var unit = thisEle.slice(-2); //获取单位
            var cName = $(this).attr("class");
            if(cName == "bigger"){
                   if( textFontSize <= 22 ){
                        textFontSize += 2;
                    }
            }else if(cName == "smaller"){
                   if( textFontSize >= 12  ){
                        textFontSize -= 2;
                    }
            }
            $("#para").css("font-size",  textFontSize + unit);
        });
    });
  </script>
</head>
<body>

<div class="msg">
    <div class="msg_caption">
        <span class="bigger" >放大</span>
        <span class="smaller" >缩小</span>
    </div>
    <div>
        <p id="para">
        This is some text. This is some text. This is some text. This is some text. This
        is some text. This is some text. This is some text. This is some text. This is some
        text. This is some text. This is some text. This is some text. This is some text.
        This is some text. This is some text. This is some text. This is some text. This
        is some text. This is some text.
        </p>
    </div>
</div>

</body>
</html>
 

jquery表格内容过滤


<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
  $(function(){
       $("#filterName").keyup(function(){
          $("table tbody tr")
                    .hide()
                    .filter(":contains('"+( $(this).val() )+"')")
                    .show();
       }).keyup();
  })
</script>
</head>
<body>
<div>
<br/>
筛选:
<input id="filterName" />
<br/>

</div>

<table>
    <thead>
        <tr><th>姓名</th><th>性别</th><th>暂住地</th></tr>
    </thead>
    <tbody>
        <tr><td>张山</td><td>男</td><td>浙江宁波</td></tr>
        <tr><td>李四</td><td>女</td><td>浙江杭州</td></tr>
        <tr><td>王五</td><td>男</td><td>湖南长沙</td></tr>
        <tr><td>找六</td><td>男</td><td>浙江温州</td></tr>
        <tr><td>Rain</td><td>男</td><td>浙江杭州</td></tr>
        <tr><td>MAXMAN</td><td>女</td><td>浙江杭州</td></tr>
        <tr><td>王六</td><td>男</td><td>浙江杭州</td></tr>
        <tr><td>李字</td><td>女</td><td>浙江杭州</td></tr>
        <tr><td>李四</td><td>男</td><td>湖南长沙</td></tr>
    </tbody>
</table>

</body>
</html>
 

jquery的表格伸缩显示隐藏


<html>
<head>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
    $('tr.parent').click(function(){   // 获取所谓的父行
            $(this)
                .toggleClass("selected")   // 添加/删除高亮
                .siblings('.child_'+this.id).toggle();  // 隐藏/显示所谓的子行
    }).click();
})
</script>
</head>
<body>
    <table>
        <thead>
            <tr><th>姓名</th><th>性别</th><th>暂住地</th></tr>
        </thead>
        <tbody>
            <tr class="parent" id="row_01"><td colspan="3">前台设计组</td></tr>
            <tr class="child_row_01"><td>张山</td><td>男</td><td>浙江宁波</td></tr>
            <tr class="child_row_01"><td>李四</td><td>女</td><td>浙江杭州</td></tr>

            <tr class="parent" id="row_02"><td colspan="3">前台开发组</td></tr>
            <tr class="child_row_02"><td>王五</td><td>男</td><td>湖南长沙</td></tr>
            <tr class="child_row_02"><td>找六</td><td>男</td><td>浙江温州</td></tr>

            <tr class="parent" id="row_03"><td colspan="3">后台开发组</td></tr>
            <tr class="child_row_03"><td>Rain</td><td>男</td><td>浙江杭州</td></tr>
            <tr class="child_row_03"><td>MAXMAN</td><td>女</td><td>浙江杭州</td></tr>
        </tbody>
    </table>

</body>
</html>
 

jquery的表格的隔行换色和多选行


<html>
<head>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
    $(function(){
        $("tbody>tr:odd").addClass("odd"); //先排除第一行,而后给奇数行添加样式
        $("tbody>tr:even").addClass("even"); //先排除第一行,而后给偶数行添加样式
        $('tbody>tr').click(function() {
            if ($(this).hasClass('selected')) {
                $(this)
                    .removeClass('selected')
                    .find(':checkbox').attr('checked',false);
            }else{
                $(this)
                    .addClass('selected')
                    .find(':checkbox').attr('checked',true);
            }
        });
        // 若是复选框默认状况下是选择的,则高色.
        // $('table :checkbox:checked').parent().parent().addClass('selected');
        //简化:
        $('table :checkbox:checked').parents("tr").addClass('selected');
        //$('tbody>tr:has(:checked)').addClass('selected');
  })
</script>
</head>
<body>
    <table>
        <thead>
            <tr><th> </th><th>姓名</th><th>性别</th><th>暂住地</th></tr>
        </thead>
        <tbody>
            <tr><td><input type="checkbox" name="choice" value=""/></td>
                <td>张山</td><td>男</td><td>浙江宁波</td></tr>
            <tr><td><input type="checkbox" name="choice" value="" /></td>
                <td>李四</td><td>女</td><td>浙江杭州</td></tr>
            <tr><td><input type="checkbox" name="choice" value="" checked='checked' /></td>
                <td>王五</td><td>男</td><td>湖南长沙</td></tr>
            <tr><td><input type="checkbox" name="choice" value="" /></td>
                <td>找六</td><td>男</td><td>浙江温州</td></tr>
            <tr><td><input type="checkbox" name="choice" value="" /></td>
                <td>Rain</td><td>男</td><td>浙江杭州</td></tr>
            <tr><td><input type="checkbox" name="choice" value="" /></td>
                <td>MAXMAN</td><td>女</td><td>浙江杭州</td></tr>
        </tbody>
    </table>
</body>
</html>


<html>
<head>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
  $(function(){
        $("tbody>tr:odd").addClass("odd");
        $("tbody>tr:even").addClass("even");
        $('tbody>tr').click(function() {
            //判断当前是否选中
            var hasSelected=$(this).hasClass('selected');
            //若是选中,则移出selected类,不然就加上selected类
            $(this)[hasSelected?"removeClass":"addClass"]('selected')
                //查找内部的checkbox,设置对应的属性。
                .find(':checkbox').attr('checked',!hasSelected);
        });
        // 若是复选框默认状况下是选择的,则高色.
        $('tbody>tr:has(:checked)').addClass('selected');
  })
</script>
</head>
<body>
    <table>
        <thead>
            <tr><th> </th><th>姓名</th><th>性别</th><th>暂住地</th></tr>
        </thead>
        <tbody>
            <tr><td><input type="checkbox" name="choice" value=""/></td>
                <td>张山</td><td>男</td><td>浙江宁波</td></tr>
            <tr><td><input type="checkbox" name="choice" value="" /></td>
                <td>李四</td><td>女</td><td>浙江杭州</td></tr>
            <tr><td><input type="checkbox" name="choice" value="" checked='checked' /></td>
                <td>王五</td><td>男</td><td>湖南长沙</td></tr>
            <tr><td><input type="checkbox" name="choice" value="" /></td>
                <td>找六</td><td>男</td><td>浙江温州</td></tr>
            <tr><td><input type="checkbox" name="choice" value="" /></td>
                <td>Rain</td><td>男</td><td>浙江杭州</td></tr>
            <tr><td><input type="checkbox" name="choice" value="" /></td>
                <td>MAXMAN</td><td>女</td><td>浙江杭州</td></tr>
        </tbody>
    </table>
</body>
</html>
 

jquery的表格的隔行换色和单选某行


<html>
<head>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
    $(function(){
        $("tbody>tr:odd").addClass("odd"); //先排除第一行,而后给奇数行添加样式
        $("tbody>tr:even").addClass("even"); //先排除第一行,而后给偶数行添加样式
        $('tbody>tr').click(function() {
            $(this)
                .addClass('selected')
                .siblings().removeClass('selected')
                .end()
                .find(':radio').attr('checked',true);
        });
        // 若是单选框默认状况下是选择的,则高色.
         // $('table :radio:checked').parent().parent().addClass('selected');
        //简化:
          $('table :radio:checked').parents("tr").addClass('selected');
         //再简化:
         //$('tbody>tr:has(:checked)').addClass('selected');

    })
</script>
</head>
<body>
    <table>
        <thead>
            <tr><th> </th><th>姓名</th><th>性别</th><th>暂住地</th></tr>
        </thead>
        <tbody>
            <tr><td><input type="radio" name="choice" value=""/></td>
                <td>张山</td><td>男</td><td>浙江宁波</td></tr>
            <tr><td><input type="radio" name="choice" value="" /></td>
                <td>李四</td><td>女</td><td>浙江杭州</td></tr>
            <tr><td><input type="radio" name="choice" value="" checked='checked' /></td>
                <td>王五</td><td>男</td><td>湖南长沙</td></tr>
            <tr><td><input type="radio" name="choice" value="" /></td>
                <td>找六</td><td>男</td><td>浙江温州</td></tr>
            <tr><td><input type="radio" name="choice" value="" /></td>
                <td>Rain</td><td>男</td><td>浙江杭州</td></tr>
            <tr><td><input type="radio" name="choice" value="" /></td>
                <td>MAXMAN</td><td>女</td><td>浙江杭州</td></tr>
        </tbody>
    </table>
</body>
</html>
 

jquery表单,邮箱的验证


<html>
<head>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
        //若是是必填的,则加红星标识.
        $("form :input.required").each(function(){
            var $required = $("<strong class='high'> *</strong>"); //建立元素
            $(this).parent().append($required); //而后将它追加到文档中
        });
         //文本框失去焦点后
        $('form :input').blur(function(){
             var $parent = $(this).parent();
             $parent.find(".formtips").remove();
             //验证用户名
             if( $(this).is('#username') ){
                    if( this.value=="" || this.value.length < 6 ){
                        var errorMsg = '请输入至少6位的用户名.';
                        $parent.append('<span class="formtips onError">'+errorMsg+'</span>');
                    }else{
                        var okMsg = '输入正确.';
                        $parent.append('<span class="formtips onSuccess">'+okMsg+'</span>');
                    }
             }
             //验证邮件
             if( $(this).is('#email') ){
                if( this.value=="" || ( this.value!="" && !/.+@.+\.[a-zA-Z]{2,4}$/.test(this.value) ) ){
                      var errorMsg = '请输入正确的E-Mail地址.';
                      $parent.append('<span class="formtips onError">'+errorMsg+'</span>');
                }else{
                      var okMsg = '输入正确.';
                      $parent.append('<span class="formtips onSuccess">'+okMsg+'</span>');
                }
             }
        }).keyup(function(){
           $(this).triggerHandler("blur");
        }).focus(function(){
             $(this).triggerHandler("blur");
        });//end blur

        
        //提交,最终验证。
         $('#send').click(function(){
                $("form :input.required").trigger('blur');
                var numError = $('form .onError').length;
                if(numError){
                    return false;
                } 
                alert("注册成功,密码已发到你的邮箱,请查收.");
         });

        //重置
         $('#res').click(function(){
                $(".formtips").remove(); 
         });
})

</script>
</head>
<body>

<form method="post" action="">
    <div class="int">
        <label for="username">用户名:</label>
        <input type="text" id="username" class="required" />
    </div>
    <div class="int">
        <label for="email">邮箱:</label>
        <input type="text" id="email" class="required" />
    </div>
    <div class="int">
        <label for="personinfo">我的资料:</label>
        <input type="text" id="personinfo" />
    </div>
    <div class="sub">
        <input type="submit" value="提交" id="send"/><input type="reset" id="res"/>
    </div>
</form>

</body>
</html>
 

下拉框左右选择,获得值


<html>
<head>
<style type="text/css">
* { margin:0; padding:0; }
div.centent {
   float:left;
   text-align: center;
   margin: 10px;
}
span { 
    display:block; 
    margin:2px 2px;
    padding:4px 10px; 
    background:#898989;
    cursor:pointer;
    font-size:12px;
    color:white;
}
</style>
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
    //移到右边
    $('#add').click(function() {
    //获取选中的选项,删除并追加给对方
        $('#select1 option:selected').appendTo('#select2');
    });
    //移到左边
    $('#remove').click(function() {
        $('#select2 option:selected').appendTo('#select1');
    });
    //所有移到右边
    $('#add_all').click(function() {
        //获取所有的选项,删除并追加给对方
        $('#select1 option').appendTo('#select2');
    });
    //所有移到左边
    $('#remove_all').click(function() {
        $('#select2 option').appendTo('#select1');
    });
    //双击选项
    $('#select1').dblclick(function(){ //绑定双击事件
        //获取所有的选项,删除并追加给对方
        $("option:selected",this).appendTo('#select2'); //追加给对方
    });
    //双击选项
    $('#select2').dblclick(function(){
       $("option:selected",this).appendTo('#select1');
    });
    $('#findall').click(function(){
        var len=    $('#select2 option').length;
    
        for(var i=0;i<len;i++){
    
            //$('#select2').get(i).value;
            alert($('#select2 option')[i].value);
        }
    });
});
</script>

</head>
<body>
    <div class="centent">
        <select multiple="multiple" id="select1" style="width:100px;height:160px;">
            <option value="1">选项1</option>
            <option value="2">选项2</option>
            <option value="3">选项3</option>
            <option value="4">选项4</option>
            <option value="5">选项5</option>
            <option value="6">选项6</option>
            <option value="7">选项7</option>
        </select>
        <div>
            <span id="add" >选中添加到右边&gt;&gt;</span>
            <span id="add_all" >所有添加到右边&gt;&gt;</span>
        </div>
    </div>

    <div class="centent">
        <select multiple="multiple" id="select2" style="width: 100px;height:160px;">
            <option value="8">选项8</option>
        </select>
        <div>
            <span id="remove">&lt;&lt;选中删除到左边</span>
            <span id="remove_all">&lt;&lt;所有删除到左边</span>
            <span id="findall">&lt;&lt;选中的全部值</span>
        </div>
    </div>


</body>
</html>
 

文件的下载

        
                File f = new  File("c://a.txt");            
                    BufferedInputStream bis =new BufferedInputStream(new FileInputStream(f));
                    byte[]  buffer = new  byte[1024];
                    response.setContentType("application/octet-stream");
                    //定义下载文件的名字
                    String a = new String(z.getZiname().getBytes("utf-8"),"iso8859-1");
               
                    response.setHeader("Content-Disposition", "attachment; filename=\"" + a+"c://a.txt".substring("c://a.txt".lastIndexOf(".")) + "\"");
                    OutputStream os = response.getOutputStream();
                    int  len = -1;
                    while((len=bis.read(buffer))!=-1){
                        os.write(buffer, 0, len);
                    }
                    os.flush();
                    os.close();
                    bis.close();                
         
 

复选框的全选

复选框  按钮
<html>
<head>
 <script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">
  $(function(){
     //全选
     $("#CheckedAll").click(function(){
         $('[name=items]:checkbox').attr('checked', true);
     });
     //全不选
     $("#CheckedNo").click(function(){
        $('[type=checkbox]:checkbox').attr('checked', false);
     });
     //反选
     $("#CheckedRev").click(function(){
          $('[name=items]:checkbox').each(function(){
            //此处用JQ写法颇显啰嗦。体现不出JQ飘逸的感受。
            //$(this).attr("checked", !$(this).attr("checked"));
            
            //直接使用JS原生代码,简单实用
            this.checked=!this.checked;
          });
     });
     //输出值
    $("#send").click(function(){
        var str="你选中的是:\r\n";
        $('[name=items]:checkbox:checked').each(function(){
            str+=$(this).val()+"\r\n";
        })
        alert(str);
    });
  })

  </script>
</head>
<body>
<form method="post" action="">
   你爱好的运动是?
   <br/>
    <input type="checkbox" name="items" value="足球"/>足球
    <input type="checkbox" name="items" value="篮球"/>篮球
    <input type="checkbox" name="items" value="羽毛球"/>羽毛球
    <input type="checkbox" name="items" value="乒乓球"/>乒乓球
   <br/>
    <input type="button" id="CheckedAll" value="全 选"/>
    <input type="button" id="CheckedNo" value="全不选"/>
    <input type="button" id="CheckedRev" value="反 选"/> 

    <input type="button" id="send" value="提 交"/> 
</form>
</body>
</html>
复选框


<html>
<head>
 <script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script>
$(function(){
     //全选
     $("#CheckedAll").click(function(){
            if(this.checked){                 //若是当前点击的多选框被选中
                 $('input[type=checkbox][name=items]').attr("checked", true );
            }else{                                
                 $('input[type=checkbox][name=items]').attr("checked", false );
            }
     });
     $('input[type=checkbox][name=items]').click(function(){
               var flag=true;
               $('input[type=checkbox][name=items]').each(function(){
                    if(!this.checked){
                         flag = false;
                    }
               });

               if( flag ){
                     $('#CheckedAll').attr('checked', true );
               }else{
                     $('#CheckedAll').attr('checked', false );
               }
     });
      //输出值
    $("#send").click(function(){
        var str="你选中的是:\r\n";
        $('input[type=checkbox][name=items]:checked').each(function(){
            str+=$(this).val()+"\r\n";
        })
        alert(str);
    });
})
  </script>
</head>
<body>

<form>
   你爱好的运动是?<input type="checkbox" id="CheckedAll" />全选/全不选<br/>
    <input type="checkbox" name="items" value="足球"/>足球
    <input type="checkbox" name="items" value="篮球"/>篮球
    <input type="checkbox" name="items" value="羽毛球"/>羽毛球
    <input type="checkbox" name="items" value="乒乓球"/>乒乓球<br/>
    <input type="button" id="send" value="提 交"/> 
</form>

</body>
</html>


<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">
$(function(){
     //全选
     $("#CheckedAll").click(function(){
            //全部checkbox跟着全选的checkbox走。
            $('[name=items]:checkbox').attr("checked", this.checked );
     });
     $('[name=items]:checkbox').click(function(){
                //定义一个临时变量,避免重复使用同一个选择器选择页面中的元素,提高程序效率。
                var $tmp=$('[name=items]:checkbox');
                //用filter方法筛选出选中的复选框。并直接给CheckedAll赋值。
                $('#CheckedAll').attr('checked',$tmp.length==$tmp.filter(':checked').length);

            /*
                //一行作过多的事情须要写更多注释。复杂选择器还可能影响效率。所以不推荐以下写法。
                $('#CheckedAll').attr('checked',!$('[name=items]:checkbox').filter(':not(:checked)').length);
            */
     });
      //输出值
    $("#send").click(function(){
        var str="你选中的是:\r\n";
        $('[name=items]:checkbox:checked').each(function(){
            str+=$(this).val()+"\r\n";
        })
        alert(str);
    });
});
  </script>
</head>
<body>

<form method="post" action="">
   你爱好的运动是?<input type="checkbox" id="CheckedAll" />全选/全不选<br/>
    <input type="checkbox" name="items" value="足球"/>足球
    <input type="checkbox" name="items" value="篮球"/>篮球
    <input type="checkbox" name="items" value="羽毛球"/>羽毛球
    <input type="checkbox" name="items" value="乒乓球"/>乒乓球<br/>
    <input type="button" id="send" value="提 交"/> 
</form>

</body>
</html>
 

jquery文本框获得失去焦点


<html>
<head>
<style type="text/css">
body{
    font:normal 12px/17px Arial;
}
div{
    padding:2px;

input, textarea { 
     width: 12em; 
     border: 1px solid #888;
}
.focus { 
     border: 1px solid #f00;
     background: #fcc;

</style>
<!--   引入jQuery -->
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
    $(function(){
        $(":input").focus(function(){
              $(this).addClass("focus");
              if($(this).val() ==this.defaultValue){  
                  $(this).val("");           
              } 
        }).blur(function(){
             $(this).removeClass("focus");
             if ($(this).val() == '') {
                $(this).val(this.defaultValue);
             }
        });
    })
    </script>


</head>
<body>
    <form action="" method="post" id="regForm">
        <fieldset>
            <legend>我的基本信息</legend>
                <div>
                    <label  for="username">名称:</label>
                    <input id="username" type="text" value="名称" />
                </div>
                <div>
                    <label for="pass">密码:</label>
                    <input id="pass" type="password" value="密码" />
                </div>
                <div>
                    <label for="msg">详细信息:</label>
                    <textarea id="msg" rows="2" cols="20">详细信息</textarea>
                </div>
        </fieldset>
    </form>
</body>
</html>
 

jxl导出excel表格


先要导入jxl须要的jar包,而后在触发导出excel时传入集合对象,例如:
public class ToExcel {

    public static void excel(List<WenShi> l,HttpServletResponse response) {
        ServletOutputStream out = null;
        WritableWorkbook wwb = null;
        try {
            // 导出Excel路径
            Date d = new Date();
            String s = new SimpleDateFormat("yyyyMMddHHmmss").format(d);
            
            response.setCharacterEncoding("utf-8");
              response.reset();
              response.setContentType("application/vnd.ms-excel;charset=utf-8");
              response.setHeader("Content-Disposition", "attachment;filename="
                      + new String("历史数据.xls".getBytes(),"iso-8859-1"));
               out = response.getOutputStream();
            
            WritableSheet ws = null;
            wwb = Workbook.createWorkbook(out);
            ws = wwb.createSheet("sheet1", 0);
            // 文字样式
            WritableFont wf = new WritableFont(WritableFont.TIMES, 10,
                    WritableFont.BOLD, false);
            WritableCellFormat wcff = new WritableCellFormat(wf);
            // 标题
            // 第一列第1行(0,0)
            Label label1 = new Label(0, 0, "编号", wcff);
            // 第一列第2行(0,1)
            Label label2 = new Label(1, 0, "环境温度", wcff);
            // 第一列第3行(0,2)
            Label label3 = new Label(2, 0, "环境湿度", wcff);
            Label label4 = new Label(3, 0, "光照强度", wcff);
            Label label5 = new Label(4, 0, "土壤温度", wcff);
            Label label6 = new Label(5, 0, "土壤湿度", wcff);
            Label label7 = new Label(6, 0, "co2浓度", wcff);
            // 第一列第4行(0,3)
            Label label8 = new Label(7, 0, "时间", wcff);
            // 第一列第5行(0,4)
            Label label9 = new Label(8, 0, "星期几", wcff);
            ws.addCell(label1);
            ws.addCell(label2);
            ws.addCell(label3);
            ws.addCell(label4);
            ws.addCell(label5);
            ws.addCell(label6);
            ws.addCell(label7);
            ws.addCell(label8);
            ws.addCell(label9);
            for (int i = 0; i < l.size(); i++) {
                Label l1 = new Label(0, i + 1, l.get(i).getStr("node"));
                Label l2 = new Label(1, i + 1, l.get(i).getStr("wen"));
                Label l3 = new Label(2, i + 1, l.get(i).getStr("shi"));
                Label l4 = new Label(3, i + 1, l.get(i).getStr("sun"));
                Label l5 = new Label(4, i + 1, l.get(i).getStr("tuwen"));
                Label l6 = new Label(5, i + 1, l.get(i).getStr("tushi"));
                Label l7 = new Label(6, i + 1, l.get(i).getStr("co"));
                Label l8 = new Label(7, i + 1, l.get(i)
                        .getTimestamp("timetext").toString());
                Label l9 = new Label(8, i + 1, l.get(i).getStr("week"));
                ws.addCell(l1);
                ws.addCell(l2);
                ws.addCell(l3);
                ws.addCell(l4);
                ws.addCell(l5);
                ws.addCell(l6);
                ws.addCell(l7);
                ws.addCell(l8);
                ws.addCell(l9);
            }
            wwb.write();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
        
            try {
                wwb.close();
            } catch (WriteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        
            
        }
    }

}
 

javascript的事件方法

onblur 事件 发生在窗口失去焦点的时候。应用于:window 对象
onchange 事件 发生在文本输入区的内容被更改,然 后焦点从文本输入区
移走以后。捕捉此事件主要用于实时检测输入的有效性,或者马上改变文
档内容。应 用于:P assword 对象;S elect 对象;T ext 对象;T extarea 对

onclick 事件 发生在对象被单击的时候。单击是指鼠标停留在对象上,
按下鼠标键,没有移动鼠标而放开鼠标键这一个完整的过程。一个普通按
钮对象(Button)一般会有 onclick 事件处理程序,由于这种对象根本
不能从用户那里获得任何信息,没 有 onclick 事件处理程序就等于废柴。
按钮上添加 onclick 事件处理程序,能够模拟“另外一个提交按钮”,方
法是:在事件处理程序中更改表单的 action, target, encoding, method
等一个或几个属性,而后调用表单的 submit() 方法。在 Link 对象的
onclick 事件处理程序中返回 false 值(return false),能阻止浏览
器打开此链接。即 ,如 果有一个这样的链接:< a href="http://www.a.com"
οnclick="return false">Go!</a>,那么不管用户怎样点击,都不会去到
www.a.com 网站,除 非用户禁止浏览器运行 JavaScript。应 用于:B utton
对象;Checkbox 对象;Image 对象;Link 对象;Radio 对象;Reset 对
象;Submit 对象
onerror 事件 发生在错误发生的时候。它的事件处理程序一般就叫作
“错误处理程序”(Error Handler),用来处理错误。上边已经介绍过,
要忽略一切错误,就使用:
function ignoreError() {
return true;
}
window.onerror = ignoreError;
应用于:window 对象
onfocus 事件 发生在窗口获得焦点的时候。应用于:window 对象
onload 事件 发生在文档所有下载完毕的时候。全 部下载完毕意味着不但
HTML 文件,并且包含的图片,插件,控件,小程序等所有内容都下载完
毕。本 事件是 window 的事件,但 是在 HTML 中指定事件处理程序的时候,
咱们是把它写在<body>标记中的。应用于:window 对象
onmousedown 事件 发生在用户把鼠标放在对象上按下鼠标键的时候。参
考 onmouseup 事件。应用于:Button 对象;Link 对象
onmouseout 事件 发生在鼠标离开对象的时候。参 考 onmouseover 事件。
应用于:Link 对象
onmouseover 事件 发生在鼠标进入对象范围的时候。这个事件和
onmouseout 事件,再加上图片的预读,就能够作到当鼠标移到图像链接
上,图像更改的效果了。有时咱们看到,在指向一个链接时,状态栏上不
显示地址,而显示其它的资料,看起来这些资料是能够随时更改的。它们
是这样作出来的:
<a href="..." οnmοuseοver="window.status='Click Me Please!';
return true;" οnmοuseοut="window.status=''; return true;">
应用于:Link 对象
onmouseup 事件 发生在用户把鼠标放在对象上鼠标键被按下的状况下,
放开鼠标键的时候。若是按下鼠标键的时候,鼠标并不在放开鼠标的对象
上,则本事件不会发生。应用于:Button 对象;Link 对象

onreset 事件 发生在表单的“重置”按钮被单击(按下并放开)的时候。
经过在事件处理程序中返回 false 值(return false)能够阻止表单重
置。应用于:Form 对象
onresize 事件 发生在窗口被调整大小的时候。应用于:window 对象
onsubmit 事件 发生在表单的“提交”按钮被单击( 按下并放开)的 时候。
能够使用该事件来验证表单的有效性。通 过在事件处理程序中返回 false
值(return false)能够阻止表单提交。应用于:Form 对象
onunload 事件 发生在用户退出文档(或者关闭窗口,或者到另外一个页面
去)的时候。与 onload 同样,要写在 HTML 中就写到<body>标记里。
有的 Web Masters 用这个方法来弹出“调查表单”,以“强迫”来者填
写;有的就弹出广告窗口,挑拨来者点击链接。我以为这种
“οnunlοad="open..."”的方法很很差,有 时甚至会由于弹出太多窗口而
致使资源缺少。有 什么对来者说就应该在网页上说完,不 对吗? 应用于:
window 对象
 

javascript的Document 对象

Document 文档对象是JavaScript 中window 和frames 对象的一个属性,是显示
于窗口或框架内的一个文档。描述当前窗口或指定窗口对象的文档。它包含了文
档从<head>到</body>的内容。
用法:document (当前窗口) 或 <窗口对象>.document (指定窗口)
属性:
document.title //设置文档标题等价于HTML 的<title>标签
document.bgColor //设置页面背景色
document.fgColor //设置前景色(文本颜色)
document.linkColor //未点击过的连接颜色
document.alinkColor //激活连接(焦点在此连接上)的颜色
document.vlinkColor //已点击过的连接颜色
document.URL //设置URL 属性从而在同一窗口打开另外一网页
document.fileCreatedDate //文件创建日期,只读属性
document.fileModifiedDate //文件修改日期,只读属性
document.fileSize //文件大小,只读属性
document.cookie //设置和读出cookie
document.charset //设置字符集 简体中文:gb2312
cookie 关于 cookie 请参看“使用框架和 Cookies”一章。
lastModified 当前文档的最后修改日期,是一个 Date 对象。
referrer 若是当前文档是经过点击链接打开的,则 referrer 返回原来
的 URL。
title 指<head>标记里用<title>...</title>定义的文字。在 Netscape
里本属性不接受赋值。
fgColor 指<body>标记的 text 属性所表示的文本颜色。
bgColor 指<body>标记的 bgcolor 属性所表示的背景颜色。
linkColor 指<body>标记的 link 属性所表示的链接颜色。
alinkColor 指<body>标记的 alink 属性所表示的活动链接颜色。
vlinkColor 指<body>标记的 vlink 属性所表示的已访问链接颜色。
方法:
open() 打开文档以便 JavaScript 能向文档的当前位置(指插入
JavaScript 的位置)写入数据。一般不须要用这个方法,在须要的时候
JavaScript 自动调用。
write(); writeln() 向文档写入数据,所写入的会当成标准文档 HTML
来处理。writeln() 与 write() 的不一样点在于,writeln() 在写入数据
之后会加一个换行。这个换行只是在 HTML 中换行,具体状况能不可以是
显示出来的文字换行,要看插入 JavaScript 的位置而定。如在<pre>标
记中插入,这个换行也会体如今文档中。
clear() 清空当前文档。
close() 关闭文档,中止写入数据。若是用了 write[ln]() 或 clear()
方法,就必定要用 close() 方法来保证所作的更改可以显示出来。若是
文档尚未彻底读取,也就是说,JavaScript 是插在文档中的,那就不
必使用该方法。
 

javascript的location对象的方法

location 地址对象 它描述的是某一个窗口对象所打开的地址。要 表示当前窗口
的地址,只须要使用“location”就好了;若要表示某一个窗口的地址,就使用
“<窗口对象>.location”。先 前写了一片用window.location.href实现刷新另
个框架页面 ,特此我看了一下locaiton 的详细用法,对此有点改进,具体如
下:
注意:属于不一样协议或不一样主机的两个地址之间不能互相引用对方的 location
对象,这是出于安全性的须要。例如,当前窗口打开的是“www.a.com”下面的
某一页,另一个窗口(对象名为:bWindow)打开的是“www.b.com”的网页。
若是在当前窗口使用“bWindow.location”,就会出错:“没有权限”。这个错
误是不能用错误处理程序(Event Handler,参阅 onerror 事件)来接收处理的。
第1、简单介绍一下location 属性、用法以及相关示例:
Location
包含了关于当前 URL 的信息。location 对象描述了与一个给定的 Window 对象
关联的完整 URL。location 对象的每一个属性都描述了 URL 的不一样特性。
一般状况下,一 个 URL 会有下面的格式:协 议//主机:端口/路径名称#哈希标识?
搜索条件
例如:url 这
些部分是知足下列需求的:
“协议”是 URL 的起始部分,直到包含到第一个冒号。
“主机”描述了主机和域名,或者一个网络主机的 IP 地址。
“端口”描述了服务器用于通信的通信端口。
路径名称描述了 URL 的路径方面的信息。
“哈希标识”描述了 URL 中的锚名称,包括哈希掩码(#)。此属性只应用
于 HTTP 的 URL。
“搜索条件”描述了该 URL 中的任何查询信息,包括问号。此属性只应
用于 HTTP 的 URL。“搜索条件”字符串包含变量和值的配对;每对之间
由一个“&”链接。
属性概览
 protocol 返回地址的协议,取值为 'http:','https:','file:' 等等。
hostname 返回地址的主机名,例如,一个“
http://www.microsoft.com/china/”的地址,location.hostname ==
'www.microsoft.com'。
· port 返回地址的端口号,通常 http 的端口号是 '80'。
· host 返回主机名和端口号,如:'www.a.com:8080'。
· pathname 返回路径名,如“http://www.a.com/b/c.html”,
location.pathname == 'b/c.html'。
· hash 返回“#”以及之后的内容,如“
http://www.a.com/b/c.html#chapter4”,location.hash ==
'#chapter4';若是地址里没有“#”,则返回空字符串。
· search 返回“?”以及之后的内容,如“
http://www.a.com/b/c.asp?selection=3&jumpto=4”,l ocation.search
== '?selection=3&jumpto=4';若是地址里没有“?”,则返回空字符串。
href 返回以上所有内容,也就是说,返回整个地址。在浏览器的地址栏
上怎么显示它就怎么返回。若是想一个窗口对象打开某地址,能够使用
“location.href = '...'”,也能够直接用“location = '...'”来达
到此目的。
方法概览
reload() 至关于按浏览器上的“刷新”(IE)或“Reload”(Netscape)
键。
replace() 打开一个 URL,并取代历史对象中当前位置的地址。用这个方
法打开一个 URL 后,按 下浏览器的“后退”键将不能返回到刚才的页面。
location 之页面跳转js 以下:
//简单跳转
function gotoPage(url) {
// eg. var url =
"newsview.html?catalogid="+catalogID+"&pageid="+pageid;
window.location = url;
}
// 对location 用法的升级,为单个页面传递参数
function goto_catalog(iCat) {
if(iCat<=0) {
top.location = "../index.aspx"; // top 出去
} else {
window.location = "../newsCat.aspx?catid="+iCat;
}
}
对指定框架进行跳转页面,二种方法皆可用
function goto_iframe(url) {
parent.mainFrame.location = "../index.aspx"; //
// parent.document.getElementById("mainFrame").src =
"../index.aspx";// use dom to change page // 同时我增长了dom 的写法
}
// 对指定框架进行跳转页面,由于
parent.iframename.location="../index.aspx"; 方法不能实行,主要是
"parent.iframename" 中的iframename在js 中被默认为节点,而 不能把传递过
来的参数转换过来,因此用dom 实现了该传递二个参数的框架跳转页面,但愿那
位仁兄不吝赐教!
function goto_iframe(iframename,url) {
parent.document.getElementById(iframename).src = "../index.aspx";//
use dom to change page by iframeName
//}
// 回到首页
function gohome() {
top.location = "/index.aspx";
}
 

JavaScript 中的History 历史对象

JavaScript 中的History 历史对象包含了用户已浏览的 URL 的信息,是指历史
对象指浏览器的浏览历史。鉴于安全性的须要,该对象收到不少限制,如今只剩
下下列属性和方法。History 历史对象有length 这个属性,列出历史的项数。
JavaScript 所能管到的历史被限制在用浏览器的“前进”“后退”键能够去到
的范围。本属性返回的是“前进”和“后退”两个按键之下包含的地址数的和。
History 历史对象并有如下方法
back() 后退,跟按下“后退”键是等效的。
forward() 前进,跟按下“前进”键是等效的。
go() 用法:history.go(x);在历史的范围内去到指定的一个地址。若是
x < 0,则后退 x 个地址,若是 x > 0,则前进 x 个地址,若是 x == 0,
则刷新如今打开的网页。history.go(0) 跟 location.reload() 是等效
的。
 

javascript的window对象的方法

Window是JavaScript 中最大的对象,它描述的是一个浏览器窗口。通常要引用它的
属性和方法时,不须要用“window.xxx”这种形式,而直接使用“xxx”。一个
框架页面也是一个窗口。
Window 窗口对象有以下属性:
name 窗口的名称,由 打开它的链接( <a target="...">)或 框架页( <frame
name="...">)或某一个窗口调用的 open() 方法(见下)决定。通常我
们不会用这个属性。
status 指窗口下方的“状态栏”所显示的内容。经过对 status 赋值,
能够改变状态栏的显示。
opener 用法:window.opener;返回打开本窗口的窗口对象。注意:返回
的是一个窗口对象。若是窗口不是由其余窗口打开的,在 Netscape 中这
个属性返回 null;在 IE 中返回“未定义”( undefined)。u ndefined 在
必定程度上等于 null。注意:undefined 不是 JavaScript 常数,若是
你企图使用“undefined”,那就真的返回“未定义”了。
self 指窗口自己,它返回的对象跟 window 对象是如出一辙的。最经常使用
的是“self.close()”,放在<a>标记中:“<a
href="javascript:self.close()">关闭窗口</a>”。
parent 返回窗口所属的框架页对象。
top 返回占据整个浏览器窗口的最顶端的框架页对象。
history 历史对象,
location 地址对象,
document 文档对象,
Window 窗口对象有以下方法:
第一个方法是open() 打开一个窗口。
用法:
open(<URL 字符串>, <窗口名称字符串>, <参数字符串>);
说明:
<URL 字符串>:描述所打开的窗口打开哪个网页。若是留空(''),则
不打开任意网页。
<窗口名称字符串>:描述被打开的窗口的名称(window.name),能够使
用'_top'、'_blank'等内建名称。这里的名称跟“<a href="..."
target="...">”里的“target”属性是同样的。
<参数字符串>:描 述被打开的窗口的样貌。如 果只须要打开一个普通窗口,
该字符串留空(''),若是要指定样貌,就在字符串里写上一到多个参数,
参数之间用逗号隔开。
例:打开一个 400 x 100 的干净的窗口:
open('','_blank','width=400,height=100,menubar=no,toolbar=no,
location=no,directories=no,status=no, scrollbars=yes,resizable=yes')
open()的参数
top=# 窗口顶部离开屏幕顶部的像素数
left=# 窗口左端离开屏幕左端的像素数
 width=# 窗口的宽度
height=# 窗口的高度
menubar=... 窗口有没有菜单,取值yes 或no
toolbar=... 窗口有没有工具条,取值yes 或 no
location=... 窗口有没有地址栏,取值yes 或no
directories=... 窗口有没有链接区,取值yes 或no
scrollbars=... 窗口有没有滚动条,取值yes 或no
status=... 窗口有没有状态栏,取值yes 或no
resizable=... 窗口给不给调整大小,取值yes 或no
注意:open() 方法有返回值,返回的就是它打开的窗口对象。好比
var newWindow = open('','_blank');
这样把一个新窗口赋值到“newWindow”变量中,以 后经过“newWindow”变量就
能够控制窗口了。
close() 关闭一个已打开的窗口。
用法:
window.close()

self.close()
主要做用是关闭本窗口;
<窗口对象>.close():关闭指定的窗口。注意若是该窗口有状态栏,调用该方法
后浏览器会警告:“网页正在试图关闭窗口,是否关闭?”而后等待用户选择是
否;若是没有状态栏,调用该方法将直接关闭窗口。
另外Window 窗口对象还有以下方法
blur() 使焦点从窗口移走,窗口变为“非活动窗口”。
focus() 是窗口得到焦点,变为“活动窗口”。不过在 Windows 98,该
方法只能使窗口的标题栏和任务栏上的相应按钮闪烁,提 示用户该窗口正
在试图得到焦点。
scrollTo() 用法:&e1;<窗口对象>.&e3;scrollTo(x, y);使窗口滚动,使文档
从左上角数起的(x, y)点滚动到窗口的左上角。
scrollBy() 用法:&e1;<窗口对象>.&e3;scrollBy(deltaX, deltaY);使窗口向
右滚动 deltaX 像素,向下滚动 deltaY 像素。若是取负值,则向相反的
方向滚动。
resizeTo() 用法:&e1;<窗口对象>.&e3;resizeTo(width, height);使窗口调
整大小到宽 width 像素,高 height 像素。
resizeBy() 用法:&e1;<窗口对象>.&e3;resizeBy(deltaWidth, deltaHeight);
使窗口调整大小,宽增大 deltaWidth 像素,高增大 deltaHeight 像素。
若是取负值,则减小。
alert() 用法:alert(<字符串>);弹出一个只包含“肯定”按钮的对话
框,显示<字符串>的内容,整个文档的读取、Script 的运行都会暂停,
直到用户按下“肯定”。
confirm() 用法:c onfirm(<字符串>);弹 出一个包含“肯定”和“取消”
按钮的对话框,显示<字符串>的内容,要求用户作出选择,整个文档的读
取、Script 的运行都会暂停。若是用户按下“肯定”,则返回 true 值,
若是按下“取消”,则返回 false 值。
prompt() 用法:prompt(<字符串>[, <初始值>]);弹出一个包含“确
认”“取消”和一个文本框的对话框,显示<字符串>的内容,要求用户在
文本框输入一些数据,整个文档的读取、Script 的运行都会暂停。若是
用户按下“确认”,则 返回文本框里已有的内容,如 果用户按下“取消”,
则返回 null 值。若是指定<初始值>,则文本框里会有默认值。
Window 窗口对象有以下事件:
window.onload;发生在文档所有下载完毕的时候。所有下载完毕意味着不但
HTML 文件,并且包含的图片,插件,控件,小程序等所有内容都下载完毕。本
事件是 window 的事件,可是在 HTML 中指定事件处理程序的时候,咱们是把它
写在<body>标记中的。
window.onunload;发生在用户退出文档(或者关闭窗口,或者到另外一个页面去)
的时候。与 onload 同样,要写在 HTML 中就写到<body>标记里。
window.onresize;发生在窗口被调整大小的时候。
window.onblur;发生在窗口失去焦点的时候。
window.onfocus;发生在窗口获得焦点的时候。
window.onerror;发生在错误发生的时候。它的事件处理程序一般就叫作
“错误处理程序”(Error Handler),用来处理错误。上边已经介绍过,
要忽略一切错误,就使用:
function ignoreError() {
return true;
}
window.onerror = ignoreError;
 

javascript的navigator对象

navigator 浏览器对象,包含了正在使用的 Navigator 的版本信息。反映了当
前使用的浏览器的资料。JavaScript 客户端运行时刻引擎自动建立 navigator
对象。
包括一下几大属性:
· appCodeName 返回浏览器的“码名”(?),流行的 IE 和 NN 都返回
'Mozilla'。
下面的例子显示了 appCodeName 属性的值:
document.write("navigator.appCodeName 的值是" +
navigator.appCodeName)
· appName 返回浏览器名。I E 返回 'Microsoft Internet Explorer',N N 返
回 'Netscape'。
下面的例子显示了 appName 属性的值:
document.write("navigator.appName 的值是 " + navigator.appName)
· appVersion 返回浏览器版本,包括了大版本号、小版本号、语言、操做
平台等信息。
· language 语言
· mimeType 以数组表示所支持的MIME 类型
· platform 返回浏览器的操做平台,对于 Windows 9x 上的浏览器,返回
'Win32'(大小写可能有差别)。
· userAgent 返回以上所有信息。例如,IE5.01 返回 'Mozilla/4.0
(compatible; MSIE 5.01; Windows 98)'。
· plugins 以数组表示已安装的外挂程序
· javaEnabled() 返回一个布尔值,表明当前浏览器容许不容许 Java。
 

javascript日期操做

如下有不少“g/set[UTC]XXX”这样的方法,它表示既有“getXXX”方法,又有
“setXXX”方法。“get”是得到某个数值,而“set”是设定某个数值。若是带
有“UTC”字母,则表示得到/设定的数值是基于 UTC 时间的,没有则表示基于
本地时间或浏览期默认时间的。
如无说明,方法的使用格式为:“<对象>.<方法>”,下同。
g/set[UTC]FullYear() 返回/设置年份,用四位数表示。若是使用
“x.set[UTC]FullYear(99)”,则年份被设定为 0099 年。
g/set[UTC]Year()返回/设置年份,用两位数表示。设定的时候浏览器自动加上
“19”开头,故使用“x.set[UTC]Year(00)”把年份设定为 1900 年。
g/set[UTC]Month()返回/设置月份。
g/set[UTC]Date()返回/设置日期。
g/set[UTC]Day()返回/设置星期,0 表示星期天。
g/set[UTC]Hours()返回/设置小时数,24 小时制。
g/set[UTC]Minutes()返回/设置分钟数。
g/set[UTC]Seconds()返回/设置秒钟数。
g/set[UTC]Milliseconds()返回/设置毫秒数。
g/setTime() 返回/设置时间,该 时间就是日期对象的内部处理方法:从 1970 年
1 月 1 日零时正开始计算到日期对象所指的日期的毫秒数。若是要使某日期对
象所指的时间推迟 1 小时,就用:“x.setTime(x.getTime() + 60 * 60 *
1000);”(一小时 60 分,一分 60 秒,一秒 1000 毫秒)。
getTimezoneOffset() 返回日期对象采用的时区与格林威治时间所差的分钟数。
在格林威治东方的市区,该值为负,例如:中国时区(GMT+0800)返回“-480”。
toString() 返回一个字符串,描述日期对象所指的日期。这个字符串的格式类
似于:“Fri Jul 21 15:43:46 UTC+0800 2000”。
toLocaleString() 返回一个字符串,描述日期对象所指的日期,用本地时间表
示格式。如:“2000-07-21 15:43:46”。
toGMTString() 返回一个字符串,描述日期对象所指的日期,用 GMT 格式。
toUTCString() 返回一个字符串,描述日期对象所指的日期,用 UTC 格式。
parse() 用法:Date.parse(<日期对象>);返回该日期对象的内部表达方式。

javascriptMath函数的属性和用法

Math “数学”对象,提供对数据的数学计算。下面所提到的属性和方法,你们在使用的时候记住用“Math.<名>”这种格式。
属性
E 返回常数 e (2.718281828...)。
LN2 返回 2 的天然对数 (ln 2)。
LN10 返回 10 的天然对数 (ln 10)。
LOG2E 返回以 2 为低的 e 的对数 (log2e)。
LOG10E 返回以 10 为低的 e 的对数 (log10e)。
PI 返回π(3.1415926535...)。
SQRT1_2 返回 1/2 的平方根。
SQRT2 返回 2 的平方根。
方法
abs(x) 返回 x 的绝对值。
acos(x) 返回 x 的反余弦值(余弦值等于 x 的角度),用弧度表示。
asin(x) 返回 x 的反正弦值。
atan(x) 返回 x 的反正切值。
atan2(x, y) 返回复平面内点(x, y)对应的复数的幅角,用 弧度表示,其 值在 -π
到 π 之间。
ceil(x) 返回大于等于 x 的最小整数。
cos(x) 返回 x 的余弦。
exp(x) 返回 e 的 x 次幂 (ex)。
floor(x) 返回小于等于 x 的最大整数。
log(x) 返回 x 的天然对数 (ln x)。
max(a, b) 返回 a, b 中较大的数。
min(a, b) 返回 a, b 中较小的数。
pow(n, m) 返回 n 的 m 次幂 (nm)。
random() 返回大于 0 小于 1 的一个随机数。
round(x) 返回 x 四舍五入后的值。
sin(x) 返回 x 的正弦。
sqrt(x) 返回 x 的平方根。
tan(x) 返回 x 的正切。
Date 日期对象。这个对象能够储存任意一个日期,从 0001 年到 9999 年,并
且能够精确到毫秒数( 1/1000 秒)。在 内部,日 期对象是一个整数,它 是从 1970
年 1 月 1 日零时正开始计算到日期对象所指的日期的毫秒数。如 果所指日期比
1970 年早,则它是一个负数。全部日期时间,若是不指定时区,都采用“UTC”
(世界时)时区,它与“GMT”(格林威治时间)在数值上是同样的。
定义一个日期对象:
var d = new Date;
这个方法使 d 成为日期对象,而且已有初始值:当前时间。若是要自定初始值,
能够用:
var d = new Date(99, 10, 1); //99 年 10 月 1 日
var d = new Date('Oct 1, 1999'); //99 年 10 月 1 日
 

javascript字符串属性和方法

toString() 用法:<数值变量>.toString();返回:字符串形式的数值。如:若
a == 123;则 a.toString() == '123'。
String 字符串对象。声明一个字符串对象最简单、快捷、有效、经常使用的方法就
是直接赋值。
length 用法:<字符串对象>.length;返回该字符串的长度。
charAt() 用法:<字符串对象>.charAt(<位置>);返回该字符串位于第<位置>
位的单个字符。注 意:字 符串中的一个字符是第 0 位的,第 二个才是第 1 位的,
最后一个字符是第 length - 1 位的。
charCodeAt() 用法:<字符串对象>.charCodeAt(<位置>);返回该字符串位于第
<位置>位的单个字符的 ASCII 码。
fromCharCode() 用法:String.fromCharCode(a, b, c...);返回一个字符串,
该字符串每一个字符的 ASCII 码由 a, b, c... 等来肯定。
indexOf() 用法:<字符串对象>.indexOf(<另外一个字符串对象>[, <起始位置
>]);该方法从<字符串对象>中查找<另外一个字符串对象>(若是给出<起始位置>
就忽略以前的位置),若是找到了,就返回它的位置,没有找到就返回“-1”。
全部的“位置”都是从零开始的。
lastIndexOf() 用法:<字符串对象>.lastIndexOf(<另外一个字符串对象>[, <起
始位置>]);跟 indexOf() 类似,不过是从后边开始找。
split() 用法:<字符串对象>.split(<分隔符字符>);返回一个数组,该数组是
从<字符串对象>中分离开来的,<分隔符字符>决定了分离的地方,它自己不会包
含在所返回的数组中。例 如:' 1&2&345&678'.split('&')返回数组:1 ,2,345,678。
关于数组,咱们等一下就讨论。
substring() 用法:<字符串对象>.substring(<始>[, <终>]);返回原字符串的
子字符串,该字符串是原字符串从<始>位置到<终>位置的前一位置的一段。<终>
- <始> = 返回字符串的长度(length)。若是没有指定<终>或指定得超过字符
串长度,则子字符串从<始>位置一直取到原字符串尾。若是所指定的位置不能返
回字符串,则返回空字符串。
substr() 用法:<字符串对象>.substr(<始>[, <长>]);返回原字符串的子字符
串,该字符串是原字符串从<始>位置开始,长度为<长>的一段。若是没有指定<
长>或指定得超过字符串长度,则子字符串从<始>位置一直取到原字符串尾。如
果所指定的位置不能返回字符串,则返回空字符串。
toLowerCase() 用法:<字符串对象>.toLowerCase();返回把原字符串全部大写
字母都变成小写的字符串。
toUpperCase() 用法:<字符串对象>.toUpperCase();返回把原字符串全部小写
字母都变成大写的字符串。
Array 数组对象。数组对象是一个对象的集合,里边的对象能够是不一样类型的。
数组的每个成员对象都有一个“下标”,用来表示它在数组中的位置(既然是
“位置”,就也是从零开始的啦)。
数组的定义方法:
var <数组名> = new Array();
这样就定义了一个空数组。之后要添加数组元素,就用:
<数组名>[<下标>] = ...;
注意这里的方括号不是“能够省略”的意思,数 组的下标表示方法就是用方括号
括起来。
若是想在定义数组的时候直接初始化数据,请用:
var <数组名> = new Array(<元素1>, <元素 2>, <元素3>...);
例如,var myArray = new Array(1, 4.5, 'Hi'); 定义了一个数组 myArray,
里边的元素是:myArray[0] == 1; myArray[1] == 4.5; myArray[2] == 'Hi'。
可是,若是元素列表中只有一个元素,而这个元素又是一个正整数的话,这将定
义一个包含<正整数>个空元素的数组。
注意:JavaScript 只有一维数组!千万不要用“Array(3,4)”这种愚蠢的方法
来定义 4 x 5 的二维数组,或者用“myArray[2,3]”这种方法来返回“二维数
组”中的元素。任意“myArray[...,3]”这种形式的调用其实只返回了
“myArray[3]”。要使用多维数组,请用这种虚拟法:
var myArray = new Array(new Array(), new Array(), new Array(), ...);
其实这是一个一维数组,里边的每个元素又是一个数组。调用这个“二维数
组”的元素时:myArray[2][3] = ...;
属性
length 用法:<数组对象>.length;返回:数组的长度,即数组里有多少个元素。
它等于数组里最后一个元素的下标加一。因此,想添加一个元素,只须要:
myArray[myArray.length] = ...。
方法
join() 用法:<数组对象>.join(<分隔符>);返回一个字符串,该字符串把数组
中的各个元素串起来,用<分隔符>置于元素与元素之间。这个方法不影响数组原
本的内容。
reverse() 用法:<数组对象>.reverse();使数组中的元素顺序反过来。若是对
数组[1, 2, 3]使用这个方法,它将使数组变成:[3, 2, 1]。
slice() 用法:<数组对象>.slice(<始>[, <终>]);返回一个数组,该数组是原
数组的子集,始于<始>,终于<终>。若是不给出<终>,则子集一直取到原数组的
结尾。
sort() 用法:<数组对象>.sort([<方法函数>]);使数组中的元素按照必定的顺
序排列。若是不指定<方法函数>,则按字母顺序排列。在这种状况下,80 是比 9
排得前的。若是指定<方法函数>,则按<方法函数>所指定的排序方法排序。<方
法函数>比较难讲述,这里只将一些有用的<方法函数>介绍给你们。
按升序排列数字:
function sortMethod(a, b) {
return a - b;
}
myArray.sort(sortMethod);
按降序排列数字:把上面的“a - b”该成“b - a”。
 

jquery事件类型

添加css样式

<html>
<head>
  <style>
  .over{
  color:red;
  background:#888;
  } 
  </style>
 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
  <script type="text/javascript">
  $(function(){
     $("div").bind("mouseover mouseout", function(){
        $(this).toggleClass("over");
     });
  })
  </script>
</head>
<body>
<div style="width:100px;height:50px;">滑入.</div>
</body>
</html>

根据事件类型
<html>
<head>
  <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
  <script type="text/javascript">
  $(function(){
    $("div").bind("click.plugin",function(){
           $("body").append("<p>click事件</p>");
    });
    $("div").bind("mouseover.plugin", function(){
           $("body").append("<p>mouseover事件</p>");
    });
    $("div").bind("dblclick", function(){
           $("body").append("<p>dblclick事件</p>");
    });
    $("button").click(function() {
        $("div").unbind(".plugin");  
    })
  })
  </script>
</head>
<body>
<div style="width:100px;height:50px;background:#888;color:white;">test.</div>
<button >根据命名空间,删除事件</button>
</body>
</html>

相同事件名称,不一样命名空间执行方法

<html>
<head>
  <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
  <script type="text/javascript">
  $(function(){
    $("div").bind("click",function(){
           $("body").append("<p>click事件</p>");
    });
    $("div").bind("click.plugin", function(){
           $("body").append("<p>click.plugin事件</p>");
    });
    $("button").click(function() {
          $("div").trigger("click!");    // 注意click后面的感叹号
    });
  })
  </script>
</head>
<body>
<div style="width:100px;height:50px;background:#888;color:white;">test.</div>
<button >根据命名空间,触发事件</button>
</body>
</html> 
 

jquery自定义事件

<html>
<head>
<style type="text/css">
*{margin:0;padding:0;}    
body { font-size: 13px; line-height: 130%; padding: 60px; }
p {width:200px;background:#888;color:white;height:16px;}
</style>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
    $(function(){
       $('#btn').bind("myClick", function(){
                     $('#test').append("<p>个人自定义事件.</p>");
              });
       $('#btn').click(function(){
            $(this).trigger("myClick");
       }).trigger("myClick");
    })
</script>
</head>
<body>
<button id="btn">点击我</button>
<div id="test"></div>
</body>
</html>

<html>
<title></title>
<style type="text/css">
*{margin:0;padding:0;}    
body { font-size: 13px; line-height: 130%; padding: 60px; }
p {width:200px;background:#888;color:white;height:16px;}
</style>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
    $(function(){
        $('#old').bind("click", function(){
            $("input").trigger("focus");
        });
        $('#new').bind("click", function(){
            $("input").triggerHandler("focus");
        });
        $("input").focus(function(){
            $("body").append("<p>focus.</p>");
        })
    })
</script>
</head>
<body>
<button id="old">trigger</button>
<button id="new">triggerHandler</button>
<input />
</body>
</html>

jquery移除事件

<html>
<head>
<style type="text/css">
*{margin:0;padding:0;}    
body { font-size: 13px; line-height: 130%; padding: 60px; }
p {width:200px;background:#888;color:white;height:16px;}
</style>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
    $(function(){
       $('#btn').bind("click", function(){
                     $('#test').append("<p>个人绑定函数1</p>");
              }).bind("click", function(){
                     $('#test').append("<p>个人绑定函数2</p>");
              }).bind("click", function(){
                       $('#test').append("<p>个人绑定函数3</p>");
              });
       $('#delAll').click(function(){
              $('#btn').unbind("click");
       });
 $('#delTwo').click(function(){
              $('#btn').unbind("click",myFun2);
       });
    })
</script>
</head>
<body>
<button id="btn">点击我</button>
<div id="test"></div>
<button id="delAll">删除全部事件</button>
<button id="delTwo">删除第二个事件</button>
</body>
</html>

<html>
<head>
<style type="text/css">
*{margin:0;padding:0;}    
body { font-size: 13px; line-height: 130%; padding: 60px; }
p {width:200px;background:#888;color:white;height:16px;}
</style>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
    $(function(){
       $('#btn').one("click", function(){
                     $('#test').append("<p>个人绑定函数1</p>");
              }).one("click", function(){
                     $('#test').append("<p>个人绑定函数2</p>");
              }).one("click", function(){
                       $('#test').append("<p>个人绑定函数3</p>");
              });
    })
</script>
</head>
<body>
<button id="btn">点击我</button>
<div id="test"></div>
</body>
</html>
 

jquery获得事件类型,href,

<html>
<head>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script>
$(function(){
    $("a").click(function(event) {
      alert(event.type);//获取事件类型
 alert(event.target.href);//获取触发事件的<a>元素的href属性值
 alert("Current mouse position: " + event.pageX + ", " + event.pageY );//获取鼠标当前相对于页面的坐标
alert(e.which)  // 1 = 鼠标左键 left; 2 = 鼠标中键; 3 = 鼠标右键
      return false;//阻止连接跳转
    });
})
  </script>
</head>
<body>
<a href='http://google.com'>click me .</a>
</body>
</html>
 

jquery阻止表单提交

<html>
<head>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
   $("#sub").bind("click",function(event){
         var username = $("#username").val();  //获取元素的值
         if(username==""){     //判断值是否为空
             $("#msg").html("<p>文本框的值不能为空.</p>");  //提示信息
             event.preventDefault();  //阻止默认行为 ( 表单提交 )或者return false;
         }
   })
})
</script>
</head>
<body>
<form action="test.html">
用户名:<input type="text" id="username" />
<br/>
<input type="submit" value="提交" id="sub"/>
</form>

<div id="msg"></div>
</body>
</html>

jquery事件冒泡

<html>
<head>
<style type="text/css">
*{margin:0;padding:0;}    
body { font-size: 13px; line-height: 130%; padding: 60px; }
#content { width: 220px; border: 1px solid #0050D0;background: #96E555 }
span { width: 200px; margin: 10px; background: #666666; cursor: pointer;color:white;display:block;}
p {width:200px;background:#888;color:white;height:16px;}
</style>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
       // 为span元素绑定click事件
    $('span').bind("click",function(event){
        var txt = $('#msg').html() + "<p>内层span元素被点击.<p/>";
        $('#msg').html(txt);
        event.stopPropagation();    //  阻止事件冒泡或者return false;
    });
    // 为div元素绑定click事件
    $('#content').bind("click",function(event){
        var txt = $('#msg').html() + "<p>外层div元素被点击.<p/>";
        $('#msg').html(txt);
        event.stopPropagation();    //  阻止事件冒泡或者return false;
    });
    // 为body元素绑定click事件
    $("body").bind("click",function(){
        var txt = $('#msg').html() + "<p>body元素被点击.<p/>";
        $('#msg').html(txt);
    });
})
</script>
</head>
<body>
<div id="content">
    外层div元素
    <span>内层span元素</span>
    外层div元素
</div>

<div id="msg"></div>
</body>
</html>

jquery隐藏显示的合成事件

<html>
<head>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
    $("#panel h5.head").hover(function(){//鼠标移动事件
        $(this).next().show();
    },function(){
        $(this).next().hide();   
    })
})
</script>
</head>
<body>
<div id="panel">
    <h5 class="head">什么是jQuery?</h5>
    <div class="content">
        jQuery是继Prototype以后又一个优秀的JavaScript库,它是一个由 John Resig 建立于2006年1月的开源项目。jQuery凭借简洁的语法和

跨平台的兼容性,极大地简化了JavaScript开发人员遍历HTML文档、操做DOM、处理事件、执行动画和开发Ajax。它独特而又优雅的代码风格改变了

JavaScript程序员的设计思路和编写程序的方式。
    </div>
</div>
</body>
</html>

<html>
<head>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<style type="text/css">
.highlight{ background:#FF3300; }
</style>
<script type="text/javascript">
$(function(){
    $("#panel h5.head").toggle(function(){//鼠标点击事件
            $(this).addClass("highlight");
            $(this).next().show();
    },function(){
            $(this).removeClass("highlight");
            $(this).next().hide();
    });
})
</script>
</head>
<body>
<div id="panel">
    <h5 class="head">什么是jQuery?</h5>
    <div class="content">
        jQuery是继Prototype以后又一个优秀的JavaScript库,它是一个由 John Resig 建立于2006年1月的开源项目。jQuery凭借简洁的语法和

跨平台的兼容性,极大地简化了JavaScript开发人员遍历HTML文档、操做DOM、处理事件、执行动画和开发Ajax。它独特而又优雅的代码风格改变了

JavaScript程序员的设计思路和编写程序的方式。
    </div>
</div>
</body>
</html>

jquery点击,鼠标模块的隐藏和显示

<head>

<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>

<script type="text/javascript">
$(function(){
    $("#panel h5.head").bind("click",function(){
        var $content = $(this).next();
        if($content.is(":visible")){
            $content.hide();
        }else{
            $content.show();
        }
    })
})
</script>
</head>
<body>
<div id="panel">
    <h5 class="head">什么是jQuery?</h5>
    <div class="content">
        jQuery是继Prototype以后又一个优秀的JavaScript库,它是一个由 John Resig 建立于2006年1月的开源项目。jQuery凭借简洁的语法和

跨平台的兼容性,极大地简化了JavaScript开发人员遍历HTML文档、操做DOM、处理事件、执行动画和开发Ajax。它独特而又优雅的代码风格改变了

JavaScript程序员的设计思路和编写程序的方式。
    </div>
</div>
</body>
</html>

<html >
<head>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
    $("#panel h5.head").bind("mouseover",function(){
        $(this).next().show();
    });
      $("#panel h5.head").bind("mouseout",function(){
         $(this).next().hide();
    })
})
</script>
</head>
<body>
<div id="panel">
    <h5 class="head">什么是jQuery?</h5>
    <div class="content">
        jQuery是继Prototype以后又一个优秀的JavaScript库,它是一个由 John Resig 建立于2006年1月的开源项目。jQuery凭借简洁的语法和

跨平台的兼容性,极大地简化了JavaScript开发人员遍历HTML文档、操做DOM、处理事件、执行动画和开发Ajax。它独特而又优雅的代码风格改变了

JavaScript程序员的设计思路和编写程序的方式。
    </div>
</div>
</body>
</html>

<html>
<head>
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
    $("#panel h5.head").mouseover(function(){
        $(this).next().show();
    });
    $("#panel h5.head").mouseout(function(){
         $(this).next().hide();
    })
})
</script>
</head>
<body>
<div id="panel">
    <h5 class="head">什么是jQuery?</h5>
    <div class="content">
        jQuery是继Prototype以后又一个优秀的JavaScript库,它是一个由 John Resig 建立于2006年1月的开源项目。jQuery凭借简洁的语法和

跨平台的兼容性,极大地简化了JavaScript开发人员遍历HTML文档、操做DOM、处理事件、执行动画和开发Ajax。它独特而又优雅的代码风格改变了

JavaScript程序员的设计思路和编写程序的方式。
    </div>
</div>
</body>
</html>

jquery加载时间比较


<head>

<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
   var startTime = new Date().getTime();
   $(document).ready(function(){
        test1();
  })
    
  function test1(){
      var endTime2  = new Date().getTime(); 
      var a = endTime2 - startTime;
      $("<div>jQuery的ready() : "+a+" ms</div>").appendTo("body");
  }

  function test2(){
       var endTime1  = new Date().getTime();
       var b = endTime1 - startTime;
       $("<p>JavaScript的window.onload : "+b+" ms</p>").appendTo("body");
  }
</script>
</head>
<body  οnlοad="test2();">
    <img src="demo.jpg" style="width:200px;height:200px;"/>
</body>
</html>

jquery表单操做


<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

 <script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 
  <script type="text/javascript">

  $(document).ready(function(){
      //重置表单元素
      $(":reset").click(function(){
          setTimeout(function() {
            countChecked();
            $("select").change();
          },0);
      });

      
      //对表单内 可用input 赋值操做.
      $('#btn1').click(function(){
          $("#form1 input:enabled").val("这里变化了!");  
          return false;
      })
      //对表单内 不可用input 赋值操做.
      $('#btn2').click(function(){
          $("#form1 input:disabled").val("这里变化了!");
          return false;
      })
     
          
      //使用:checked选择器,来操做多选框.
        $(":checkbox").click(countChecked);

        function countChecked() {
          var n = $("input:checked").length;
          $("div").eq(0).html("<strong>有"+n+" 个被选中!</strong>");
        }

        countChecked();//进入页面就调用.

     //使用:selected选择器,来操做下拉列表.
        $("select").change(function () {
              var str = "";
              $("select :selected").each(function () {
                    str += $(this).text() + ",";
              });
              $("div").eq(1).html("<strong>你选中的是:"+str+"</strong>");
        }).trigger('change');
        // trigger('change') 在这里的意思是:
        // select加载后,立刻执行onchange.
        // 也能够用.change()代替.
  });


  </script>

</head>
<body>
  <h3> 表单对象属性过滤选择器.</h3>
   <form id="form1" action="#">
    <button type="reset">重置全部表单元素</button>
    <br /><br />
  <button id="btn1">对表单内 可用input 赋值操做.</button>
  <button id="btn2">对表单内 不可用input 赋值操做.</button><br /><br />
    
     可用元素:<input name="add" value="可用文本框"/>  <br/>
     不可用元素:<input name="email" disabled="disabled" value="不可用文本框"/><br/>
     可用元素: <input name="che" value="可用文本框" /><br/>
     不可用元素:<input name="name" disabled="disabled"  value="不可用文本框"/><br/>
     <br/>
     多选框:<br/>
     <input type="checkbox" name="newsletter" checked="checked" value="test1" />test1
     <input type="checkbox" name="newsletter" value="test2" />test2
     <input type="checkbox" name="newsletter" value="test3" />test3
     <input type="checkbox" name="newsletter" checked="checked" value="test4" />test4
     <input type="checkbox" name="newsletter" value="test5" />test5
     <div></div>

     <br/><br/>
     下拉列表1:<br/>
    <select name="test" multiple="multiple" style="height:100px">
        <option>浙江</option>
        <option selected="selected">湖南</option>
        <option>北京</option>
        <option selected="selected">天津</option>
        <option>广州</option>
        <option>湖北</option>
    </select>
    
     <br/><br/>
     下拉列表2:<br/>
     <select name="test2" >
    <option>浙江</option>
    <option>湖南</option>
    <option selected="selected">北京</option>
    <option>天津</option>
    <option>广州</option>
    <option>湖北</option>
    </select>
    <br/><br/>

     <div></div>
  </form>



</body>
</html>


<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
  <script type="text/javascript">
  $(document).ready(function(){

    var $alltext = $("#form1 :text");
    var $allpassword= $("#form1 :password");
    var $allradio= $("#form1 :radio");
    var $allcheckbox= $("#form1 :checkbox");

    var $allsubmit= $("#form1 :submit");
    var $allimage= $("#form1 :image");
    var $allreset= $("#form1 :reset");
    var $allbutton= $("#form1 :button"); // <input type=button />  和 <button ></button>均可以匹配
    var $allfile= $("#form1 :file");
    var $allhidden= $("#form1 :hidden"); // <input type="hidden" />和<div style="display:none">test</div>均可以匹配.
    var $allselect = $("#form1 select");
    var $alltextarea = $("#form1 textarea");
    
    var $AllInputs = $("#form1 :input");
    var $inputs = $("#form1 input");

    $("div").append(" 有" + $alltext.length + " 个( :text 元素)<br/>")
            .append(" 有" + $allpassword.length + " 个( :password 元素)<br/>")
            .append(" 有" + $allradio.length + " 个( :radio 元素)<br/>")
            .append(" 有" + $allcheckbox.length + " 个( :checkbox 元素)<br/>")
            .append(" 有" + $allsubmit.length + " 个( :submit 元素)<br/>")
            .append(" 有" + $allimage.length + " 个( :image 元素)<br/>")
            .append(" 有" + $allreset.length + " 个( :reset 元素)<br/>")
            .append(" 有" + $allbutton.length + " 个( :button 元素)<br/>")
            .append(" 有" + $allfile.length + " 个( :file 元素)<br/>")
            .append(" 有" + $allhidden.length + " 个( :hidden 元素)<br/>")
            .append(" 有" + $allselect.length + " 个( select 元素)<br/>")
            .append(" 有" + $alltextarea.length + " 个( textarea 元素)<br/>")
            .append(" 表单有 " + $inputs.length + " 个(input)元素。<br/>")
            .append(" 总共有 " + $AllInputs.length + " 个(:input)元素。<br/>")
            .css("color", "red")

    $("form").submit(function () { return false; }); // return false;不能提交.

  });
  </script>
</head>
<body>
  <form id="form1" action="#">
    <input type="button" value="Button"/><br/>
    <input type="checkbox" name="c"/>1<input type="checkbox" name="c"/>2<input type="checkbox" name="c"/>3<br/>
    <input type="file" /><br/>
    <input type="hidden" /><div style="display:none">test</div><br/>
    <input type="image" /><br/>
    <input type="password" /><br/>
    <input type="radio" name="a"/>1<input type="radio" name="a"/>2<br/>
    <input type="reset" /><br/>
    <input type="submit" value="提交"/><br/>
    <input type="text" /><br/>
    <select><option>Option</option></select><br/>
    <textarea rows="5" cols="20"></textarea><br/>
    <button>Button</button><br/>
  </form>
 
  <div></div>
</body>
</html>

jquery选择器

  //选取每一个父元素下的第2个子元素
      $('#btn1').click(function(){
          $('div.one :nth-child(2)').css("background","#bbffaa");
      })
      //选取每一个父元素下的第一个子元素
      $('#btn2').click(function(){
          $('div.one :first-child').css("background","#bbffaa");
      })
      //选取每一个父元素下的最后一个子元素
      $('#btn3').click(function(){
          $('div.one :last-child').css("background","#bbffaa");
      })
      //若是父元素下的仅仅只有一个子元素,那么选中这个子元素
      $('#btn4').click(function(){
          $('div.one :only-child').css("background","#bbffaa");
      })
 //选取含有 属性title 的div元素.
      $('#btn1').click(function(){
          $('div[title]').css("background","#bbffaa");
      })
      //选取 属性title值等于 test 的div元素.
      $('#btn2').click(function(){
          $('div[title=test]').css("background","#bbffaa");
      })
      //选取 属性title值不等于 test 的div元素.
      $('#btn3').click(function(){
          $('div[title!=test]').css("background","#bbffaa");
      })
      //选取 属性title值 以 te 开始 的div元素.
      $('#btn4').click(function(){
          $('div[title^=te]').css("background","#bbffaa");
      })
      //选取 属性title值 以 est 结束 的div元素.
      $('#btn5').click(function(){
          $("div[title$=est]").css("background","#bbffaa");
      })
      //选取 属性title值 含有 es  的div元素.
      $('#btn6').click(function(){
          $("div[title*=es]").css("background","#bbffaa");
      })
      //组合属性选择器,首先选取有属性id的div元素,而后在结果中 选取属性title值 含有 es 的元素.
      $('#btn7').click(function(){
          $("div[id][title*=es]").css("background","#bbffaa");
      })
 $('#reset').click(function(){
          window.location.reload();
      })
      //给id为mover的元素添加动画.
       function animateIt() {
          $("#mover").slideToggle("slow", animateIt);
        }
        animateIt();
      
        //选取全部不可见的元素.包括<input type="hidden"/>.
      $('#btn_hidden').click(function(){
          alert( "不可见的元素有:"+$('body :hidden').length +"个!\n"+
           "其中不可见的div元素有:"+$('div:hidden').length+"个!\n"+
           "其中文本隐藏域有:"+$('input:hidden').length+"个!");
          $('div:hidden').show(3000).css("background","#bbffaa");
      })
      //选取全部可见的元素.
      $('#btn_visible').click(function(){
          $('div:visible').css("background","#FF6500");
      })
  //选取含有文本"di"的div元素.
      $('#btn1').click(function(){
          $('div:contains(di)').css("background","#bbffaa");
      })
      //选取不包含子元素(或者文本元素)的div空元素.
      $('#btn2').click(function(){
          $('div:empty').css("background","#bbffaa");
      })
      //选取含有class为mini元素 的div元素.
      $('#btn3').click(function(){
          $('div:has(.mini)').css("background","#bbffaa");
      })
      //选取含有子元素(或者文本元素)的div元素.
      $('#btn4').click(function(){
          $('div:parent').css("background","#bbffaa");
      })
  //选择第一个div元素.
      $('#btn1').click(function(){
          $('div:first').css("background","#bfa");
      })
      //选择最后一个div元素.
      $('#btn2').click(function(){
          $('div:last').css("background","#bfa");
      })
      //选择class不为one的 全部div元素.
      $('#btn3').click(function(){
          $('div:not(.one)').css("background","#bfa");
      })
      //选择 索引值为偶数 的div元素。
      $('#btn4').click(function(){
          $('div:even').css("background","#bfa");
      })
      //选择 索引值为奇数 的div元素。
      $('#btn5').click(function(){
          $('div:odd').css("background","#bfa");
      })
      //选择 索引等于 3 的元素
      $('#btn6').click(function(){
          $('div:eq(3)').css("background","#bfa");
      })
      //选择 索引大于 3 的元素
      $('#btn7').click(function(){
          $('div:gt(3)').css("background","#bfa");
      })
     //选择 索引小于 3 的元素
      $('#btn8').click(function(){
          $('div:lt(3)').css("background","#bfa");
      })
       //选择 全部的标题元素.好比h1, h2, h3等等...
      $('#btn9').click(function(){
          $(':header').css("background","#bfa");
      })
      //选择 当前正在执行动画的全部元素.
      $('#btn10').click(function(){
          $(':animated').css("background","#bfa");
      });
  //选择 body内的全部div元素.
      $('#btn1').click(function(){
          $('body div').css("background","#bbffaa");
      })
      //在body内的选择 元素名是div 的子元素.
      $('#btn2').click(function(){
          $('body > div').css("background","#bbffaa");
      })
      //选择 全部class为one 的下一个div元素.
      $('#btn3').click(function(){
          $('.one + div').css("background","#bbffaa");
      })
      //选择 id为two的元素后面的全部div兄弟元素.
      $('#btn4').click(function(){
           $('#two ~ div').css("background","#bbffaa");
      })
 //选择 id为 one 的元素
      $('#btn1').click(function(){
          $('#one').css("background","#bfa");
      });
      //选择 class 为 mini 的全部元素
      $('#btn2').click(function(){
          $('.mini').css("background","#bfa");
      });
      //选择 元素名是 div 的全部元素
      $('#btn3').click(function(){
          $('div').css("background","#bfa");
      });
      //选择 全部的元素
      $('#btn4').click(function(){
          $('*').css("background","#bfa");
      });
      //选择 全部的span元素和id为two的div元素
      $('#btn5').click(function(){
          $('span,#two').css("background","#bfa");
      });    
 

jquery文字提示


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">
$(function(){
    var x = 10;  
    var y = 20;
    $("a.tooltip").mouseover(function(e){
           this.myTitle = this.title;
        this.title = "";    
        var tooltip = "<div id='tooltip'>"+ this.myTitle +"<\/div>"; //建立 div 元素
        $("body").append(tooltip);    //把它追加到文档中
        $("#tooltip")
            .css({
                "top": (e.pageY+y) + "px",
                "left": (e.pageX+x)  + "px"
            }).show("fast");      //设置x坐标和y坐标,而且显示
    }).mouseout(function(){        
        this.title = this.myTitle;
        $("#tooltip").remove();   //移除 
    }).mousemove(function(e){
        $("#tooltip")
            .css({
                "top": (e.pageY+y) + "px",
                "left": (e.pageX+x)  + "px"
            });
    });
})
</script>
<style type="text/css">
body{
    margin:0;
    padding:40px;
    background:#fff;
    font:80% Arial, Helvetica, sans-serif;
    color:#555;
    line-height:180%;
}
p{
    clear:both;
    margin:0;
    padding:.5em 0;
}
/* tooltip */
#tooltip{
    position:absolute;
    border:1px solid #333;
    background:#f7f5d1;
    padding:1px;
    color:#333;
    display:none;
}
</style>

</head>
<body>
<p><a href="#" class="tooltip" title="这是个人超连接提示1.">提示1.</a></p>
<p><a href="#" class="tooltip" title="这是个人超连接提示2.">提示2.</a></p>
<p><a href="#" title="这是自带提示1.">自带提示1.</a></p>
<p><a href="#" title="这是自带提示2.">自带提示2.</a> </p>
</body>
</html>

jquery遍历节点树

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">
  $(function(){
     var $body = $("body").children();
     var $p = $("p").children();
     var $ul = $("ul").children();
     alert( $body.length );  // <body>元素下有2个子元素
     alert( $p.length );     // <p>元素下有0个子元素
     alert( $ul.length );    // <p>元素下有3个子元素
     for(var i=0;i< $ul.length;i++){
         alert( $ul[i].innerHTML );
     }
  }); 
  </script>
</head>
<body>
    <p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
    <ul>
      <li title='苹果'>苹果</li>
      <li title='橘子'>橘子</li>
      <li title='菠萝'>菠萝</li>
    </ul>
</body>
</html>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">
  $(function(){
     var $p1 = $("p").next();
     alert( $p1.html() );  //  紧邻<p>元素后的同辈元素
     var $ul = $("ul").prev();
     alert( $ul.html() );  //  紧邻<ul>元素前的同辈元素
     var $p2 = $("p").siblings();
     alert( $p2.html() );  //  紧邻<p>元素的惟一同辈元素
  });
  </script>
</head>
<body>
    <p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
    <ul>
      <li title='苹果'>苹果</li>
      <li title='橘子'>橘子</li>
      <li title='菠萝'>菠萝</li>
    </ul>
</body>
</html>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">
  $(function(){
    $(document).bind("click", function (e) {
        $(e.target).closest("li").css("color","red");
    })
  });
  </script>
</head>
<body>
    <p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
    <ul>
      <li title='苹果'>苹果</li>
      <li title='橘子'>橘子</li>
      <li title='菠萝'>菠萝</li>
    </ul>
</body>
</html>

jquery设置和获取HTML,文本和值

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
.test{
 font-weight:bold;
 color : red;
}
.add{
 font-style:italic;
}
</style>
 <!--   引入jQuery -->
 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">
  $(function(){
      //获取<p>元素的HTML代码
      $("input:eq(0)").click(function(){
            alert(  $("p").html() );
      });
      //获取<p>元素的文本
      $("input:eq(1)").click(function(){
            alert(  $("p").text() );
      });
      //设置<p>元素的HTML代码
      $("input:eq(2)").click(function(){
             $("p").html("<strong>你最喜欢的水果是?</strong>");
      });    
       //设置<p>元素的文本
      $("input:eq(3)").click(function(){
             $("p").text("你最喜欢的水果是?");
      });  
      //设置<p>元素的文本
      $("input:eq(4)").click(function(){
             $("p").text("<strong>你最喜欢的水果是?</strong>");
      });  
      //获取按钮的value值
      $("input:eq(5)").click(function(){
             alert( $(this).val() );
      });   
      //设置按钮的value值
      $("input:eq(6)").click(function(){
            $(this).val("我被点击了!");
      });  
  });
  </script>
</head>
<body>
    <input type="button" value="获取<p>元素的HTML代码"/>
    <input type="button" value="获取<p>元素的文本"/>
    <input type="button" value="设置<p>元素的HTML代码"/>
    <input type="button" value="设置<p>元素的文本"/>
    <input type="button" value="设置<p>元素的文本(带HTML)"/>
    <input type="button" value="获取按钮的value值"/>
    <input type="button" value="设置按钮的value值"/>

    <p title="选择你最喜欢的水果." ><strong>你最喜欢的水果是?</strong></p>
    <ul>
      <li title='苹果'>苹果</li>
      <li title='橘子'>橘子</li>
      <li title='菠萝'>菠萝</li>
    </ul>
</body>
</html>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">
  $(function(){
      $("#address").focus(function(){         // 地址框得到鼠标焦点
            var txt_value =  $(this).val();   // 获得当前文本框的值
            if(txt_value==this.defaultValue){  
                $(this).val("");              // 若是符合条件,则清空文本框内容
            } 
      });
      $("#address").blur(function(){          // 地址框失去鼠标焦点
              var txt_value =  $(this).val();   // 获得当前文本框的值
            if(txt_value==""){
                $(this).val(this.defaultValue);// 若是符合条件,则设置内容
            } 
      })

      $("#password").focus(function(){
            var txt_value =  $(this).val();
            if(txt_value==this.defaultValue){
                $(this).val("");
            } 
      });
      $("#password").blur(function(){
              var txt_value =  $(this).val();
            if(txt_value==""){
                $(this).val(this.defaultValue);
            } 
      })
  });
  </script>

</head>
<body>
    <input type="text" id="address" value="请输入邮箱地址"/>   <br/><br/>
    <input type="text" id="password" value="请输入邮箱密码"/>  <br/><br/>
    <input type="button" value="登录"/>
</body>
</html>


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
.test{
 font-weight:bold;
 color : red;
}
.add{
 font-style:italic;
}
</style>
 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">
  $(function(){
      //设置单选下拉框选中
      $("input:eq(0)").click(function(){
            $("#single option").removeAttr("selected");  //移除属性selected
            $("#single option:eq(1)").attr("selected",true); //设置属性selected
      });
      //设置多选下拉框选中
      $("input:eq(1)").click(function(){
            $("#multiple option").removeAttr("selected");  //移除属性selected
            $("#multiple option:eq(2)").attr("selected",true);//设置属性selected
            $("#multiple option:eq(3)").attr("selected",true);//设置属性selected
      });
      //设置单选框和多选框选中
      $("input:eq(2)").click(function(){
            $(":checkbox").removeAttr("checked"); //移除属性checked
            $(":radio").removeAttr("checked"); //移除属性checked
            $("[value=check2]:checkbox").attr("checked",true);//设置属性checked
            $("[value=check3]:checkbox").attr("checked",true);//设置属性checked
            $("[value=radio2]:radio").attr("checked",true);//设置属性checked
      });   
  });
  </script>
</head>
<body>
    <input type="button" value="设置单选下拉框选中"/>
    <input type="button" value="设置多选下拉框选中"/>
    <input type="button" value="设置单选框和多选框选中"/>

<br/><br/>

<select id="single">
  <option>选择1号</option>
  <option>选择2号</option>
  <option>选择3号</option>
</select>

<select id="multiple" multiple="multiple" style="height:120px;">
  <option selected="selected">选择1号</option>
  <option>选择2号</option>
  <option>选择3号</option>
  <option>选择4号</option>
  <option selected="selected">选择5号</option>
</select>

<br/><br/>


<input type="checkbox" value="check1"/> 多选1
<input type="checkbox" value="check2"/> 多选2
<input type="checkbox" value="check3"/> 多选3
<input type="checkbox" value="check4"/> 多选4

<br/>

<input type="radio" value="radio1" name="a"/> 单选1
<input type="radio" value="radio2" name="a"/> 单选2
<input type="radio" value="radio3" name="a"/> 单选3
</body>
</html>

jquery样式操做


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<style type="text/css">
.high{
 font-weight:bold;   /* 粗体字 */
 color : red;        /* 字体颜色设置红色*/
}
.another{
 font-style:italic;
 color:blue;
}
</style>
 <!--   引入jQuery -->
 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">

  $(function(){
      //获取样式
      $("input:eq(0)").click(function(){
            alert( $("p").attr("class") );
      });
      //设置样式
      $("input:eq(1)").click(function(){
            $("p").attr("class","high");
      });
      //追加样式
      $("input:eq(2)").click(function(){
            $("p").addClass("another");
      });    
      //删除所有样式
      $("input:eq(3)").click(function(){
            $("p").removeClass();
      });  
       //删除指定样式
      $("input:eq(4)").click(function(){
            $("p").removeClass("high");
      });   
      //重复切换样式
      $("input:eq(5)").click(function(){
            $("p").toggleClass("another");
      });  
      //判断元素是否含有某样式
      $("input:eq(6)").click(function(){
            alert( $("p").hasClass("another") )
            alert( $("p").is(".another") )
      });  
  });

  </script>
</head>
<body>
    <input type="button" value="输出class类"/>
    <input type="button" value="设置class类"/>
    <input type="button" value="追加class类"/>
    <input type="button" value="删除所有class类"/>
    <input type="button" value="删除指定class类"/>
    <input type="button" value="重复切换class类"/>
    <input type="button" value="判断元素是否含有某个class类"/>

    <p class="myClass" title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
    <ul>
      <li title='苹果'>苹果</li>
      <li title='橘子'>橘子</li>
      <li title='菠萝'>菠萝</li>
    </ul>
</body>
</html>


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
.test{
 font-weight:bold;
 color : red;
}
.add{
 font-style:italic;
}
</style>
 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">
  $(function(){
      //获取<p>元素的color
      $("input:eq(0)").click(function(){
            alert(  $("p").css("color") );
      });
      //设置<p>元素的color
      $("input:eq(1)").click(function(){
             $("p").css("color","red")
      });
      //设置<p>元素的fontSize和backgroundColor
      $("input:eq(2)").click(function(){
             $("p").css({"fontSize":"30px" ,"backgroundColor":"#888888"})
      });    
      //获取<p>元素的高度
      $("input:eq(3)").click(function(){
              alert( $("p").height() );
      });  
      //获取<p>元素的宽度
      $("input:eq(4)").click(function(){
              alert( $("p").width() );
      });   

        //获取<p>元素的高度
      $("input:eq(5)").click(function(){
              $("p").height("100px");
      });  
      //获取<p>元素的宽度
      $("input:eq(6)").click(function(){
              $("p").width("400px");
      }); 
      //获取<p>元素的的左边距和上边距
      $("input:eq(7)").click(function(){
              var offset = $("p").offset();
              var left = offset.left;
              var top =  offset.top;
              alert("left:"+left+";top:"+top);
      });  
  });
  </script>
</head>
<body>
    <input type="button" value="获取<p>元素的color"/>
    <input type="button" value="设置<p>元素的color"/>
    <input type="button" value="设置<p>元素的fontSize和backgroundColor"/>
    <input type="button" value="获取<p>元素的高度"/>
    <input type="button" value="获取<p>元素的宽度"/>
    <input type="button" value="设置<p>元素的高度"/>
    <input type="button" value="设置<p>元素的宽度"/>
    <input type="button" value="获取<p>元素的的左边距和上边距"/>


    <p title="选择你最喜欢的水果."><strong>你最喜欢的水果是?</strong></p>
    <ul>
      <li title='苹果'>苹果</li>
      <li title='橘子'>橘子</li>
      <li title='菠萝'>菠萝</li>
    </ul>
</body>
</html>
 

jquery替换节点和属性操做

替换节点

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">

  $(function(){
     $("p").replaceWith("<strong>你最不喜欢的水果是?</strong>"); 
     // 一样的实现: $("<strong>你最不喜欢的水果是?</strong>").replaceAll("p"); 
  });

  </script>
</head>
<body>
    <p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
    <ul>
      <li title='苹果'>苹果</li>
      <li title='橘子'>橘子</li>
      <li title='菠萝'>菠萝</li>
    </ul>
</body>
</html>
属性操做
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">

  $(function(){
      //设置<p>元素的属性'title'
      $("input:eq(0)").click(function(){
            $("p").attr("title","选择你最喜欢的水果.");
      });
      //获取<p>元素的属性'title'
      $("input:eq(1)").click(function(){
            alert( $("p").attr("title") );
      });
      //删除<p>元素的属性'title'
      $("input:eq(2)").click(function(){
            $("p").removeAttr("title");
      });   

  });

  </script>
</head>
<body>
    <input type="button" value="设置<p>元素的属性'title'"/>
    <input type="button" value="获取<p>元素的属性'title'"/>
    <input type="button" value="删除<p>元素的属性'title'"/>


    <p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
    <ul>
      <li title='苹果'>苹果</li>
      <li title='橘子'>橘子</li>
      <li title='菠萝'>菠萝</li>
    </ul>
</body>
</html>

jquery删除和复制节点

删除节点
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">

  $(function(){
     var $li = $("ul li:eq(1)").remove(); // 获取第二个<li>元素节点后,将它从网页中删除。

     $li.appendTo("ul");                        // 把刚才删除的又从新添加到<ul>元素里
     //因此,删除只是从网页中删除,在jQuery对象中,这个元素仍是存在的,咱们能够从新获取它
      $("ul li").remove("li[title!=菠萝]");  //把<li>元素中属性title不等于"菠萝"的<li>元素删除 
     $("ul li:eq(1)").empty(); // 找到第二个<li>元素节点后,清空此元素里的内容
  });

  </script>
</head>
<body>
    <p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
    <ul>
      <li title='苹果'>苹果</li>
      <li title='橘子'>橘子</li>
      <li title='菠萝'>菠萝</li>
    </ul>
</body>
</html>
复制节点
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">
  $(function(){
     $("ul li").click(function(){
         $(this).clone(true).appendTo("ul"); // 
         //注意参数true能够复制本身,而且他的副本也有一样功能。 
     })   
  });
  </script>
</head>
<body>
    <p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
    <ul>
      <li title='苹果'>苹果</li>
      <li title='橘子'>橘子</li>
      <li title='菠萝'>菠萝</li>
    </ul>
</body>
</html>

jquery插入和移动节点


插入节点
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">

  $(function(){
    var $li_1 = $("<li title='香蕉'>香蕉</li>");    //  建立第一个<li>元素
    var $li_2 = $("<li title='雪梨'>雪梨</li>");    //  建立第二个<li>元素
    var $li_3 = $("<li title='其它'>其它</li>");    //  建立第三个<li>元素


    var $parent = $("ul");                             // 获取<ul>节点,即<li>的父节点
    var $two_li = $("ul li:eq(1)");             //  获取<ul>节点中第二个<li>元素节点
   
    $parent.append($li_1);                 //  append方法将建立的第一个<li>元素添加到父元素的最后面
    $parent.prepend($li_2);                 //  prepend方法将建立的第二个<li>元素添加到父元素里的最前面
    $li_3.insertAfter($two_li);               //  insertAfter方法将建立的第三个<li>元素元素插入到获取的<li>以后

  });
 
  </script>
</head>
<body>
    <p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
    <ul>
      <li title='苹果'>苹果</li>
      <li title='橘子'>橘子</li>
      <li title='菠萝'>菠萝</li>
    </ul>
</body>
</html>

移动节点

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />


 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">

  $(function(){
    var $one_li = $("ul li:eq(1)");             //  获取<ul>节点中第二个<li>元素节点
    var $two_li = $("ul li:eq(2)");             //  获取<ul>节点中第三个<li>元素节点
    $two_li.insertBefore($one_li);    //移动节点
  });

  </script>
</head>
<body>
    <p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
    <ul>
      <li title='苹果'>苹果</li>
      <li title='橘子'>橘子</li>
      <li title='菠萝'>菠萝</li>
    </ul>
</body>
</html>

jquery查找和建立节点

获得元素的值
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />


 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">
 
  $(function(){
      var $para = $("p");            // 获取<p>节点
      var $li = $("ul li:eq(1)");   // 获取第二个<li>元素节点

      var p_txt = $para.attr("title"); // 输出<p>元素节点属性title
      var ul_txt =  $li.attr("title");    // 获取<ul>里的第二个<li>元素节点的属性title
      var li_txt =  $li.text();       // 输出第二个<li>元素节点的text
         alert(p_txt);
      alert(ul_txt);
      alert(li_txt);
     
  });
 
  </script>
</head>
<body>
    <p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
    <ul>
      <li title='苹果'>苹果</li>
      <li title='橘子'>橘子</li>
      <li title='菠萝'>菠萝</li>
    </ul>
</body>
</html>
建立节点
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>3-2-3</title>
 <!--   引入jQuery -->
 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
 <script type="text/javascript">
  $(function(){
    var $li_1 = $("<li title='香蕉'>香蕉</li>");    //建立一个<li>元素
                                                                        

    //包括元素节点,文本节点和属性节点
                                                                        

    //其中title='香蕉' 就是建立的属性节点
    var $li_2 = $("<li title='雪梨'>雪梨</li>");     //建立一个<li>元素
                                                                        

    //包括元素节点,文本节点和属性节点
                                                                        

    //其中title='雪梨' 就是建立的属性节点  


     var $parent = $("ul");        // 获取<ul>节点。<li>的父节点

     $parent.append($li_1);        // 添加到<ul>节点中,使之能在网页中显示
     $parent.append($li_2);        // 等价于:$parent.append($li_1).append($li_2);
  });

  </script>
</head>
<body>

    <p title="选择你最喜欢的水果." >你最喜欢的水果是?</p>
    <ul>
      <li title='苹果'>苹果</li>
      <li title='橘子'>橘子</li>
      <li title='菠萝'>菠萝</li>
    </ul>

</body>
</html>

dwr的简单例子

1.在lib中加入相应的dwr.jar包
2.在web.xml中加入如下代码:

<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>
org.directwebremoting.servlet.DwrServlet
</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
3.在web-inf目录下新建dwr.xml文件,加入一个简单的配置:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://www.getahead.ltd.uk/dwr/dwr20.dtd">
<dwr>
<allow>
<create creator="new" javascript="service">
<param name="class" value="helloWorld.Service"/>
</create>
</allow>
</dwr>
4.新建一个servlet类,
public class Service {
public String sayHello(String yourName){
return yourName;
}
}
5.新建一个jsp页面以下:
<html>
  <head>
  
    
    <title>My JSP 'index.jsp' starting page</title>
  <script type='text/javascript' src='/dwr2/dwr/interface/service.js'></script>
  <script type='text/javascript' src='/dwr2/dwr/engine.js'></script>
  <script type='text/javascript' src='/dwr2/dwr/util.js'></script>
<script type="text/javascript">
function firstdwr(){
service.sayHello("yangjunwei",callback);
}
function callback(d){
alert(d);
}
</script>
  </head>
  
  <body>
   <input type="button" οnclick="firstdwr()"/>
  </body>
</html>
当点击按钮时,就会弹出yangjunwei,这就完成了一个简单的dwrajax交互
 

手机访问网站拦截请求头信息类

public class HttpRequestDeviceUtils {

    /**Wap网关Via头信息中特有的描述信息*/
    private static String mobileGateWayHeaders[]=new String[]{
    "ZXWAP",//中兴提供的wap网关的via信息,例如:Via=ZXWAP GateWayZTE Technologies,
    "chinamobile.com",//中国移动的诺基亚wap网关,例如:Via=WTP/1.1 GDSZ-PB-GW003-WAP07.gd.chinamobile.com (Nokia WAP Gateway 4.1 CD1/ECD13_D/4.1.04)
    "monternet.com",//移动梦网的网关,例如:Via=WTP/1.1 BJBJ-PS-WAP1-GW08.bj1.monternet.com. (Nokia WAP Gateway 4.1 CD1/ECD13_E/4.1.05)
    "infoX",//华为提供的wap网关,例如:Via=HTTP/1.1 GDGZ-PS-GW011-WAP2 (infoX-WISG Huawei Technologies),或Via=infoX WAP Gateway V300R001 Huawei Technologies
    "XMS 724Solutions HTG",//国外电信运营商的wap网关,不知道是哪一家
    "wap.lizongbo.com",//本身测试时模拟的头信息
    "Bytemobile",//貌似是一个给移动互联网提供解决方案提升网络运行效率的,例如:Via=1.1 Bytemobile OSN WebProxy/5.1
    };
    /**电脑上的IE或Firefox浏览器等的User-Agent关键词*/
    private static String[] pcHeaders=new String[]{
    "Windows 98",
    "Windows ME",
    "Windows 2000",
    "Windows XP",
    "Windows NT",
    "Ubuntu"
    };
    /**手机浏览器的User-Agent里的关键词*/
    private static String[] mobileUserAgents=new String[]{
    "Nokia",//诺基亚,有山寨机也写这个的,总还算是手机,Mozilla/5.0 (Nokia5800 XpressMusic)UC AppleWebkit(like Gecko) Safari/530
    "SAMSUNG",//三星手机 SAMSUNG-GT-B7722/1.0+SHP/VPP/R5+Dolfin/1.5+Nextreaming+SMM-MMS/1.2.0+profile/MIDP-2.1+configuration/CLDC-1.1
    "MIDP-2",//j2me2.0,Mozilla/5.0 (SymbianOS/9.3; U; Series60/3.2 NokiaE75-1 /110.48.125 Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML like Gecko) Safari/413
    "CLDC1.1",//M600/MIDP2.0/CLDC1.1/Screen-240X320
    "SymbianOS",//塞班系统的,
    "MAUI",//MTK山寨机默认ua
    "UNTRUSTED/1.0",//疑似山寨机的ua,基本能够肯定仍是手机
    "Windows CE",//Windows CE,Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 7.11)
    "iPhone",//iPhone是否也转wap?无论它,先区分出来再说。Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; zh-cn) AppleWebKit/532.9 (KHTML like Gecko) Mobile/8B117
    "iPad",//iPad的ua,Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; zh-cn) AppleWebKit/531.21.10 (KHTML like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10
    "Android",//Android是否也转wap?Mozilla/5.0 (Linux; U; Android 2.1-update1; zh-cn; XT800 Build/TITA_M2_16.22.7) AppleWebKit/530.17 (KHTML like Gecko) Version/4.0 Mobile Safari/530.17
    "BlackBerry",//BlackBerry8310/2.7.0.106-4.5.0.182
    "UCWEB",//ucweb是否只给wap页面? Nokia5800 XpressMusic/UCWEB7.5.0.66/50/999
    "ucweb",//小写的ucweb貌似是uc的代理服务器Mozilla/6.0 (compatible; MSIE 6.0;) Opera ucweb-squid
    "BREW",//很奇怪的ua,例如:REW-Applet/0x20068888 (BREW/3.1.5.20; DeviceId: 40105; Lang: zhcn) ucweb-squid
    "J2ME",//很奇怪的ua,只有J2ME四个字母
    "YULONG",//宇龙手机,YULONG-CoolpadN68/10.14 IPANEL/2.0 CTC/1.0
    "YuLong",//仍是宇龙
    "COOLPAD",//宇龙酷派YL-COOLPADS100/08.10.S100 POLARIS/2.9 CTC/1.0
    "TIANYU",//天语手机TIANYU-KTOUCH/V209/MIDP2.0/CLDC1.1/Screen-240X320
    "TY-",//天语,TY-F6229/701116_6215_V0230 JUPITOR/2.2 CTC/1.0
    "K-Touch",//仍是天语K-Touch_N2200_CMCC/TBG110022_1223_V0801 MTK/6223 Release/30.07.2008 Browser/WAP2.0
    "Haier",//海尔手机,Haier-HG-M217_CMCC/3.0 Release/12.1.2007 Browser/WAP2.0
    "DOPOD",//多普达手机
    "Lenovo",// 联想手机,Lenovo-P650WG/S100 LMP/LML Release/2010.02.22 Profile/MIDP2.0 Configuration/CLDC1.1
    "LENOVO",// 联想手机,好比:LENOVO-P780/176A
    "HUAQIN",//华勤手机
    "AIGO-",//爱国者竟然也出过手机,AIGO-800C/2.04 TMSS-BROWSER/1.0.0 CTC/1.0
    "CTC/1.0",//含义不明
    "CTC/2.0",//含义不明
    "CMCC",//移动定制手机,K-Touch_N2200_CMCC/TBG110022_1223_V0801 MTK/6223 Release/30.07.2008 Browser/WAP2.0
    "DAXIAN",//大显手机DAXIAN X180 UP.Browser/6.2.3.2(GUI) MMP/2.0
    "MOT-",//摩托罗拉,MOT-MOTOROKRE6/1.0 LinuxOS/2.4.20 Release/8.4.2006 Browser/Opera8.00 Profile/MIDP2.0 Configuration/CLDC1.1 Software/R533_G_11.10.54R
    "SonyEricsson",// 索爱手机,SonyEricssonP990i/R100 Mozilla/4.0 (compatible; MSIE 6.0; Symbian OS; 405) Opera 8.65 [zh-CN]
    "GIONEE",//金立手机
    "HTC",//HTC手机
    "ZTE",//中兴手机,ZTE-A211/P109A2V1.0.0/WAP2.0 Profile
    "HUAWEI",//华为手机,
    "webOS",//palm手机,Mozilla/5.0 (webOS/1.4.5; U; zh-CN) AppleWebKit/532.2 (KHTML like Gecko) Version/1.0 Safari/532.2 Pre/1.0
    "GoBrowser",//3g GoBrowser.User-Agent=Nokia5230/GoBrowser/2.0.290 Safari
    "IEMobile",//Windows CE手机自带浏览器,
    "WAP2.0"//支持wap 2.0的
    };
    /**
    * 根据当前请求的特征,判断该请求是否来自手机终端,主要检测特殊的头信息,以及user-Agent这个header
    * @param request http请求
    * @return 若是命中手机特征规则,则返回对应的特征字符串
    */
    public static boolean isMobileDevice(HttpServletRequest request){
        boolean b = false;
        boolean pcFlag = false;
        boolean mobileFlag = false;
        String via = request.getHeader("Via");
        String userAgent = request.getHeader("user-agent");
        for (int i = 0; via!=null && !via.trim().equals("") && i < mobileGateWayHeaders.length; i++) {
            if(via.contains(mobileGateWayHeaders[i])){
                mobileFlag = true;
                break;
            }
        }
        for (int i = 0;!mobileFlag && userAgent!=null && !userAgent.trim().equals("") && i < mobileUserAgents.length; i++) {
            if(userAgent.contains(mobileUserAgents[i])){
                mobileFlag = true;
                break;
            }
        }
        for (int i = 0; userAgent!=null && !userAgent.trim().equals("") && i < pcHeaders.length; i++) {
            if(userAgent.contains(pcHeaders[i])){
                pcFlag = true;
                break;
            }
        }
        if(mobileFlag==true && pcFlag==false){
            b=true;
        }
        return b;//false pc  true shouji
    
    }

}
 

jfinal控制手机访问和电脑访问,跳转到不一样的页面

能够写一个类继承Handler类,拦截全部的请求,获得url,根据请求头的信息判断出是手机访问仍是电脑访问,根据需求跳转到不一样的页面或者方法中

javascript笔记之onload和表单提交

<html>
<head>
<script>
function hello(){
alert("hello");
}
function byee(){
alert("bye");
}
function show(){
var v = document.myform.inname.value;
var p = document.myform.pwd.value;
alert(v+p);
}
function valia(f){
var v = document.myform.inname.value;
var p = document.myform.pwd.value;
return true;
}
</script>
</head>
<body οnlοad="hello()" onUnLoad="byee()" >
<form action="dd" name="myform" οnsubmit="return valia(this) "> 
<input type="text" name="inname"   />
<input type="text" name="pwd" />
<input type="submit"  />
</form>
</body>
</html>
 

火狐伪造请求头模拟手机访问网站

判断应该属于程序部分的处理,不属于 前端的范畴,是靠判断请求头信息(HTTP_USER_AGENT)进行判断的。
步骤是:1.
首先须要安装三个Firefox插件:wmlbrowser、XHTML Mobile Profile、User Agent Switcher;(我称它们为“伪娘三贱客”)
2.
安装好后须要设置 User Agent Switcher ,点击菜单 工具 → Default User Agent → User Agent Switcher → Options → New→New User Agent... ,Description是你给它的一个称呼,好比小三,凹凸曼等等。关键的部分是User Agent里面的东西(这里是请求头主要的信息,程序会根据这个请求头进行判断你是不是手持设备),这里就须要把咱们想要模拟的手持设备的信息填入了。
3.
添加好后一路肯定,回到浏览器界面。工具 →default user agent  →选择你本身添加的那个 →在浏览器地址输入你想要访问的地址便可。
十分大方这里你会看到几个选项,Default User Agent (浏览器默认的信息),Internet Explorer (能够模拟ie6,7,8的头信息),Search Robots (模拟谷歌,雅虎,msn的蜘蛛),iphone 3.0 (默认存在的一个)
4.
下面列出几个比较常见手机的User Agent:(若是想要查询更多的手机user agent 信息的话, 去看这里还有这里)
iPhone3:
Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16
Android:
Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
诺基亚N95:
Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaN95/30.0.015; Profile MIDP-2.0 Configuration/CLDC-1.1) AppleWebKit/413 (KHTML, like Gecko) Safari/413
诺基亚N97:
Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/20.0.019; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.1.18124

判断手机访问仍是电脑访问

package pc;

import javax.servlet.http.HttpServletRequest;
public class HttpRequestDeviceUtils {

    /**Wap网关Via头信息中特有的描述信息*/
    private static String mobileGateWayHeaders[]=new String[]{
    "ZXWAP",//中兴提供的wap网关的via信息,例如:Via=ZXWAP GateWayZTE Technologies,
    "chinamobile.com",//中国移动的诺基亚wap网关,例如:Via=WTP/1.1 GDSZ-PB-GW003-WAP07.gd.chinamobile.com (Nokia WAP Gateway 4.1 CD1/ECD13_D/4.1.04)
    "monternet.com",//移动梦网的网关,例如:Via=WTP/1.1 BJBJ-PS-WAP1-GW08.bj1.monternet.com. (Nokia WAP Gateway 4.1 CD1/ECD13_E/4.1.05)
    "infoX",//华为提供的wap网关,例如:Via=HTTP/1.1 GDGZ-PS-GW011-WAP2 (infoX-WISG Huawei Technologies),或Via=infoX WAP Gateway V300R001 Huawei Technologies
    "XMS 724Solutions HTG",//国外电信运营商的wap网关,不知道是哪一家
    "wap.lizongbo.com",//本身测试时模拟的头信息
    "Bytemobile",//貌似是一个给移动互联网提供解决方案提升网络运行效率的,例如:Via=1.1 Bytemobile OSN WebProxy/5.1
    };
    /**电脑上的IE或Firefox浏览器等的User-Agent关键词*/
    private static String[] pcHeaders=new String[]{
    "Windows 98",
    "Windows ME",
    "Windows 2000",
    "Windows XP",
    "Windows NT",
    "Ubuntu"
    };
    /**手机浏览器的User-Agent里的关键词*/
    private static String[] mobileUserAgents=new String[]{
    "Nokia",//诺基亚,有山寨机也写这个的,总还算是手机,Mozilla/5.0 (Nokia5800 XpressMusic)UC AppleWebkit(like Gecko) Safari/530
    "SAMSUNG",//三星手机 SAMSUNG-GT-B7722/1.0+SHP/VPP/R5+Dolfin/1.5+Nextreaming+SMM-MMS/1.2.0+profile/MIDP-2.1+configuration/CLDC-1.1
    "MIDP-2",//j2me2.0,Mozilla/5.0 (SymbianOS/9.3; U; Series60/3.2 NokiaE75-1 /110.48.125 Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML like Gecko) Safari/413
    "CLDC1.1",//M600/MIDP2.0/CLDC1.1/Screen-240X320
    "SymbianOS",//塞班系统的,
    "MAUI",//MTK山寨机默认ua
    "UNTRUSTED/1.0",//疑似山寨机的ua,基本能够肯定仍是手机
    "Windows CE",//Windows CE,Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 7.11)
    "iPhone",//iPhone是否也转wap?无论它,先区分出来再说。Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; zh-cn) AppleWebKit/532.9 (KHTML like Gecko) Mobile/8B117
    "iPad",//iPad的ua,Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; zh-cn) AppleWebKit/531.21.10 (KHTML like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10
    "Android",//Android是否也转wap?Mozilla/5.0 (Linux; U; Android 2.1-update1; zh-cn; XT800 Build/TITA_M2_16.22.7) AppleWebKit/530.17 (KHTML like Gecko) Version/4.0 Mobile Safari/530.17
    "BlackBerry",//BlackBerry8310/2.7.0.106-4.5.0.182
    "UCWEB",//ucweb是否只给wap页面? Nokia5800 XpressMusic/UCWEB7.5.0.66/50/999
    "ucweb",//小写的ucweb貌似是uc的代理服务器Mozilla/6.0 (compatible; MSIE 6.0;) Opera ucweb-squid
    "BREW",//很奇怪的ua,例如:REW-Applet/0x20068888 (BREW/3.1.5.20; DeviceId: 40105; Lang: zhcn) ucweb-squid
    "J2ME",//很奇怪的ua,只有J2ME四个字母
    "YULONG",//宇龙手机,YULONG-CoolpadN68/10.14 IPANEL/2.0 CTC/1.0
    "YuLong",//仍是宇龙
    "COOLPAD",//宇龙酷派YL-COOLPADS100/08.10.S100 POLARIS/2.9 CTC/1.0
    "TIANYU",//天语手机TIANYU-KTOUCH/V209/MIDP2.0/CLDC1.1/Screen-240X320
    "TY-",//天语,TY-F6229/701116_6215_V0230 JUPITOR/2.2 CTC/1.0
    "K-Touch",//仍是天语K-Touch_N2200_CMCC/TBG110022_1223_V0801 MTK/6223 Release/30.07.2008 Browser/WAP2.0
    "Haier",//海尔手机,Haier-HG-M217_CMCC/3.0 Release/12.1.2007 Browser/WAP2.0
    "DOPOD",//多普达手机
    "Lenovo",// 联想手机,Lenovo-P650WG/S100 LMP/LML Release/2010.02.22 Profile/MIDP2.0 Configuration/CLDC1.1
    "LENOVO",// 联想手机,好比:LENOVO-P780/176A
    "HUAQIN",//华勤手机
    "AIGO-",//爱国者竟然也出过手机,AIGO-800C/2.04 TMSS-BROWSER/1.0.0 CTC/1.0
    "CTC/1.0",//含义不明
    "CTC/2.0",//含义不明
    "CMCC",//移动定制手机,K-Touch_N2200_CMCC/TBG110022_1223_V0801 MTK/6223 Release/30.07.2008 Browser/WAP2.0
    "DAXIAN",//大显手机DAXIAN X180 UP.Browser/6.2.3.2(GUI) MMP/2.0
    "MOT-",//摩托罗拉,MOT-MOTOROKRE6/1.0 LinuxOS/2.4.20 Release/8.4.2006 Browser/Opera8.00 Profile/MIDP2.0 Configuration/CLDC1.1 Software/R533_G_11.10.54R
    "SonyEricsson",// 索爱手机,SonyEricssonP990i/R100 Mozilla/4.0 (compatible; MSIE 6.0; Symbian OS; 405) Opera 8.65 [zh-CN]
    "GIONEE",//金立手机
    "HTC",//HTC手机
    "ZTE",//中兴手机,ZTE-A211/P109A2V1.0.0/WAP2.0 Profile
    "HUAWEI",//华为手机,
    "webOS",//palm手机,Mozilla/5.0 (webOS/1.4.5; U; zh-CN) AppleWebKit/532.2 (KHTML like Gecko) Version/1.0 Safari/532.2 Pre/1.0
    "GoBrowser",//3g GoBrowser.User-Agent=Nokia5230/GoBrowser/2.0.290 Safari
    "IEMobile",//Windows CE手机自带浏览器,
    "WAP2.0"//支持wap 2.0的
    };
    /**
    * 根据当前请求的特征,判断该请求是否来自手机终端,主要检测特殊的头信息,以及user-Agent这个header
    * @param request http请求
    * @return 若是命中手机特征规则,则返回对应的特征字符串
    */
    public static boolean isMobileDevice(HttpServletRequest request){
        boolean b = false;
        boolean pcFlag = false;
        boolean mobileFlag = false;
        String via = request.getHeader("Via");
        String userAgent = request.getHeader("user-agent");
        for (int i = 0; via!=null && !via.trim().equals("") && i < mobileGateWayHeaders.length; i++) {
            if(via.contains(mobileGateWayHeaders[i])){
                mobileFlag = true;
                break;
            }
        }
        for (int i = 0;!mobileFlag && userAgent!=null && !userAgent.trim().equals("") && i < mobileUserAgents.length; i++) {
            if(userAgent.contains(mobileUserAgents[i])){
                mobileFlag = true;
                break;
            }
        }
        for (int i = 0; userAgent!=null && !userAgent.trim().equals("") && i < pcHeaders.length; i++) {
            if(userAgent.contains(pcHeaders[i])){
                pcFlag = true;
                break;
            }
        }
        if(mobileFlag==true && pcFlag==false){
            b=true;
        }
        return b;//false pc  true shouji
    
    }

}
 

java年月日的操做

 public static List<String> getWeekDay(String strDate) {
         List<String> list = new ArrayList<String>();//第几周,周几
            String nReturn = null;
            Calendar c = Calendar.getInstance(); // 实例化一个Calendar对象
            c.clear(); // 清空Calendar
            c.set(Integer.parseInt(strDate.substring(0, 4)), Integer
                    .parseInt(strDate.substring(5, 7)) - 1, Integer
                    .parseInt(strDate.substring(8, 10))); // 设置这个日期的内容
            System.out.println("------------" + c.get(Calendar.YEAR) + "年" + (c.get(Calendar.MONTH) + 1) + "月"+(c.get(Calendar.DATE))+"日的天数和周数-------------");  
            System.out.println("天数:" + c.getActualMaximum(Calendar.DAY_OF_MONTH));  
            System.out.println("周数:" + c.getActualMaximum(Calendar.WEEK_OF_MONTH));
            System.out.println("第几周:"+c.get(Calendar.DAY_OF_WEEK_IN_MONTH));
            switch (c.get(Calendar.DAY_OF_WEEK)) {
            case 1:
                nReturn = "7";
                break;
            case 2:
                nReturn = "1";
                break;
            case 3:
                nReturn = "2";
                break;
            case 4:
                nReturn = "3";
                break;
            case 5:
                nReturn = "4";
                break;
            case 6:
                nReturn = "5";
                break;
            case 7:
                nReturn = "6";
                break;
            default:
                nReturn = null;
                break;
            }
            list.add(String.valueOf(c.get(Calendar.DAY_OF_WEEK_IN_MONTH)));
            list.add(nReturn);
            return list;
        }
 

highcharts本地导出图片,pdf服务端代码


先要在exporting.js中修改导出图片的url是本地的服务器地址

String type = getPara("type");//getRequest().getParameter("type");
        String svg =getPara("svg");// getRequest().getParameter("svg");
        String filename = getPara("filename");//getRequest().getParameter("filename");
        ServletOutputStream out1 =  null;
        try {
            //getRequest().setCharacterEncoding("utf-8");
            
            System.out.println(type);
            System.out.println(svg);
            System.out.println(filename);
            filename = filename==null?"chart":filename;
             out1 = getResponse().getOutputStream();
            if (null != type && null != svg) {
                svg = svg.replaceAll(":rect", "rect");
                String ext = "";
                Transcoder t = null;
                if (type.equals("image/png")) {
                    ext = "png";
                    t = new PNGTranscoder();
                } else if (type.equals("image/jpeg")) {
                    ext = "jpg";
                    t = new JPEGTranscoder();
                } else if(type.equals("image/svg+xml")) {
                      ext = "svg"; 
                }else if(type.equals("application/pdf")){
                    t = new PDFTranscoder();
                    ext = "pdf";
                }
                    
                getResponse().addHeader("Content-Disposition", "attachment; filename="+ filename + "."+ext);
                getResponse().addHeader("Content-Type", type);
                
                if (null != t) {
                    TranscoderInput input = new TranscoderInput(new StringReader(svg));
                    TranscoderOutput output = new TranscoderOutput(out1);                    
                    try {
                        t.transcode(input, output);
                    } catch (TranscoderException e) {
                        out1.print("Problem transcoding stream. See the web logs for more details.");
                        e.printStackTrace();
                    }
                } else if (ext.equals("svg")) {
                //    out.print(svg);
                    OutputStreamWriter writer = new OutputStreamWriter(out1, "UTF-8");
                    writer.append(svg);
                    writer.flush();
                    writer.close();
                } /*else 
                    out.print("Invalid type: " + type);*/
            } else {
                //getResponse().addHeader("Content-Type", "text/html");
               // out.println("Usage:\n\tParameter [svg]: The DOM Element to be converted." +
               //         "\n\tParameter [type]: The destination MIME type for the elment to be transcoded.");
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            try {
                out1.flush();
                getResponse().flushBuffer(); 
                out1.close();
                
            } catch (Exception e2) {
            
            }
            
        }
须要的jar包:
 

extjs实现实时数据显示

Ext.namespace('Ext.ux');
Ext.ux.EmRealtimeDisplayPanel = function(treeNode, panelId, config) {
    this.treeNode = treeNode;
    this.panelId = panelId;
    

    var temhum = new Ext.form.ComboBox({
        name : 'temhunm',
        fieldLabel : '状态',
        allowBlank : false,
        blankText : '请选择温湿度',
        editable : false,
        triggerAction : 'all',//all表示把下拉框列表框的列表值所有显示出来
        store : new Ext.data.ArrayStore({
            fields : [ 'name', 'value' ],
            data : [ [ '温度', '1' ], [ '湿度', '2' ] ]
        }),
        mode : 'local',
        displayField : 'name',
        valueField : 'value',
        width : 60
    });
    var storenode = new Ext.data.JsonStore({   //读配置文件
        autoLoad:true,   
        url : path+"/wenshi/getnode",   
        root : "options",   
        fields : [ {   
            name : 'name'  
        }]   
    });

    var node = new Ext.form.ComboBox({
        fieldLabel : '节点',
        allowBlank : false,
        blankText : '请选择节点',
        editable : false,
        triggerAction : 'all',
        store : storenode,
        mode : 'local',
        displayField : 'name',
        valueField : 'name',
        width : 60
    });
    
    var dataArr = new Array();
    var store = new Ext.data.ArrayStore({
            fields: ['data', 'time'],
            data: dataArr
    });
    

    
    var varNodeId = '';//节点的id值
    var taskStart = false;
    //定时器里面的参数配置
    var task = {
            run: function(){
                gridStore.load({
                    params: {
                    'nodeid' : varNodeId,
                    'tem'    :th
                    },
                    callback:function(r){
                       if(!(typeof(r[0])==='undefined')) {
                         dataArr.push([r[0].data.data, r[0].data.time]);
                         store.loadData(dataArr);
                       }
                    }
                });
            },
            interval: 3000 
    };

    var gridStore= new Ext.data.JsonStore({
        fields:['time', 'data'],
        autoLoad:true,  
         baseParams : {
            'nodeid' : "",
            'tem'    :""
        },
        url :path+'/wenshi/getShishiData',   
        root : "data"
    });
    var panel1= new Ext.Panel({
        title: '实时曲线图显示',
        width: 700,
        height: 400,
        smooth: true,
        type: 'circle',
        items: {
            xtype: 'linechart',
            url: 'extjs3/resources/charts.swf',
            store: store,
            xField: 'time',
            yField: 'data',
            xAxis: new Ext.chart.CategoryAxis({
                title: '时间(秒)'//00 09:00 分钟 秒:毫秒
            }),
            yAxis: new Ext.chart.NumericAxis({
                title: '数值'
            })
        },
               tbar : [
                       {
                            xtype    : 'label',
                            text    : '请选择节点: '
                        },
                   node, {
                        xtype    : 'label',
                        text    : '请选择温湿度: '
                    },
                    temhum,
                {    
                    text    : '查询',
                    handler    : function(btn, event) {
                            var nodeid = node.getValue();
                            var tem = temhum.getValue();
                            if (nodeid == undefined || nodeid == ''||tem==''){
                                return;
                            } else {
                                dataArr = new Array();
                                varNodeId = nodeid;
                                th = tem;
                            //    alert(th);
                                if(!taskStart) {
                                    Ext.TaskMgr.start(task);//定时执行代码
                                    taskStart  =true;
                                }
                            }
                    }
                }]
    });
    Ext.ux.EmRealtimeDisplayPanel.superclass.constructor.call(this, {
        id : this.panelId,
        title : this.treeNode.text,
        layout        : 'fit',
        closable : true,
        preventBodyReset : true,
        items : [panel1]
    });

};
Ext.extend(Ext.ux.EmRealtimeDisplayPanel, Ext.Panel, {});

Ext.reg('emEmRealtimeDisplayPanel', Ext.ux.EmRealtimeDisplayPanel);

extjs和highcharts整合显示数据曲线和打印图片

Ext.namespace('Ext.ux');

Ext.ux.WaterRealtimeDisplayPanel = function(treeNode, panelId, config) {
    this.treeNode = treeNode;
    this.panelId = panelId;
    var series=[{"name":"实时数据显示","data":[]}];
    
    var temhum = new Ext.form.ComboBox({
        name : 'temhunm',
        fieldLabel : '状态',
        allowBlank : false,
        blankText : '请选择温湿度',
        editable : false,
        triggerAction : 'all',//all表示把下拉框列表框的列表值所有显示出来
        store : new Ext.data.ArrayStore({
            fields : [ 'name', 'value' ],
            data : [ [ '温度', '1' ], [ '湿度', '2' ] ]
        }),
        mode : 'local',
        displayField : 'name',
        valueField : 'value',
        width : 60
    });
    var storeProvince = new Ext.data.JsonStore({   
        autoLoad:true,   
        url : path+"/wenshi/getnode",   
        root : "options",   
        fields : [ {   
            name : 'name'  
        }]
    });
    var nodeCtl = new Ext.form.ComboBox({
        fieldLabel : '节点',
        allowBlank : false,
        blankText : '请选择节点',
        editable : false,
        triggerAction : 'all',
        store : storeProvince,
        mode : 'local',
        displayField : 'name',
        valueField : 'name',
        width : 140
    });
    var stTime = new Ext.form.DateField({
                fieldLabel    : '选择时间',
                allowBlank    : false,
                emptyText    : '请选择开始日期',
                editable    : false,
                format        : 'Y-m-d',
                maxValue    : new Date(),
                width        : 130
            });
    var data = [
        ['y','年'],
        ['m','月'],
        ['d','日']
      //  ['w','周']
    ];

    var store = new Ext.data.SimpleStore({
        fields: ['value', 'text'],
        data: data
    });
    var combo = new Ext.form.ComboBox({
        store: store,
        fieldLabel:"请选择时间对应的类型",
        emptyText: '请选择筛选类型',
        mode: 'local',
        triggerAction : 'all',
        valueField: 'value',
        displayField: 'text'
    });
    Ext.ux.WaterRealtimeDisplayPanel.superclass.constructor.call(this, {
                id : this.panelId,
                title : this.treeNode.text,
                closable : true,
                autoScroll : true,
                height : 400,
                items:[
                    {  
                layout:'column',  
                border:false,  
                items:[{  
                //columnWidth: .25 ,  
                layout:'form',  
                border:false,  
                labelAlign:'right',  
                width : 200,  
                labelWidth:40,  
                items:[
temhum,  nodeCtl]  
                }
                ,{  
                    layout:'form',  
                    width : 200,  
                    labelWidth:60,  
                    border:false,  
                    labelAlign:'left',  
                    items:[stTime]  
                },//combo
                combo 
                ,
                {    
                    layout:'form',  
                    border:false,  
                    scope:this,  
                    items:[{  
                        xtype:'button',  
                        border:false,
                        width:70,
                        style:"margin-left:10px",
                        text:'查询',  
                        scope:this,  
                        handler:function(){ 
                            
                            // 获取表单对象  
                            var _params_ = this.getForm().getValues(false);    
                            var nodeid = nodeCtl.getValue();//获取节点id
                            var checktype=combo.getValue();//选择的筛选类型
                            var checktime=stTime.getValue();//获取时间的值
                            var th = temhum.getValue();
                            if (th == undefined || th == ''){
                                Ext.Msg.alert("提示","节点不能为空");
                                return;
                            } 
                            if (nodeid == undefined || nodeid == ''){
                                Ext.Msg.alert("提示","节点不能为空");
                                return;
                            } 
                            if(!stTime.isValid()){
                                Ext.Msg.alert('信息', '时间为必选项');    
                                return;
                            }                          
                            if (checktype == undefined || checktype == ''){
                                Ext.Msg.alert("提示","筛选类型不能为空");
                                return;
                            } 
                            // 得到统计【就是显示的那个图】 配置文件对象  
                            var _op_ = this.getOptions();
                            
                            //首先从后台得到x轴上值
                            var categories=_op_.xAxis.categories;
                            categories=[];
                            $.ajax({  
                                    type:"POST",  // 提交方式  
                                    url:path+'/wenshi/collectHositoryDataName', // 提交地址         
                                    dataType:"json", // 解释格式  
                                    data:{"nodeid":nodeid,"checktime":checktime.format('Y-m-d'),"checktype":checktype,"th":th},     // 请求参数  
                                    success:function(iJson){  
                                        var results = eval(iJson); // 转换成 JSON 数据  
                                   var r = results[0].data;
                                 for(var i=0;i<r.length;i++){
                                     categories.push(r[i]);
                                 }
                                    
                                        _op_.xAxis.categories=categories;
                                     },  
                                    error:function(){  
                                        Ext.Msg.alert('系统操做','网络不通畅或数据格式不对!');  
                                    }  
                            });
                           
                            // 得到统计 对象的 数据 
                            var _series_ = _op_.series;                             
                            // 清空 统计 对象的 数据 从新加载                              
                            _series_ = [] ;  
                            // 建立一个统计 对象胡方法   
                            var _createChart_ = function (obj){new Highcharts.Chart(obj);};  
                            // 向后台发送请求   
                        var d = new Ext.util.DelayedTask(function(){  
                             $.ajax({  
                                    type:"POST",  // 提交方式  
                                    url:path+'/wenshi/collectHositoryData', // 提交地址         
                                    dataType:"json", // 解释格式  
                                    data:{"nodeid":nodeid,"checktime":checktime.format('Y-m-d'),"checktype":checktype,"th":th},     // 请求参数  
                                    success:function(iJson){  
                                        var results = eval(iJson); // 转换成 JSON 数据  
                                        for(var i =0 ; i < results.length;i++){  // 解释和装载数据   
                                            _series_.push({name:results[i].name,data:results[i].data});  
                                        }  
                                        _op_.series = _series_; // 赋值   
                                        _createChart_(_op_);  // 从新建立一个统计  
                                     },  
                                    error:function(){  
                                        Ext.Msg.alert('系统操做','网络不通畅或数据格式不对!');  
                                    }  
                            });
                         });  
                         d.delay(1000);
                        }  
                    }]  
                }]  
            },
            {  
                xtype:'panel',  // 建立  Highcharts  所依赖的 div   
                html:'<div id="'+"test"+'" style="width:1000px; height: 500px; margin: 0 auto"></div>'  
            }
                    ],
                listeners : {
                    activate : function(p) {
                          var obj=this.getOptions();
                          obj.series=series;
                          var chart =new Highcharts.Chart(obj);
                    }
                },
                getOptions:function(){
                    return     {
                                    chart : {
                                        renderTo :"test",
                                          type: 'spline'
                                    },
                                    lang : {
                                        exportButtonTitle : '导出图表',
                                        printButtonTitle : '打印报表'
                                    },
                                    title : {
                                        text : '节点历史参数曲线图'
                                    },
                                    xAxis : {
                                        title : {
                                            text : '采集时间'
                                        }
                                       ,
                                        //categories : ['1秒', '2秒','3秒']//设置x轴上分类名称
                                    },
                                    yAxis : {
                                        title : {
                                            text : '节点参数值'
                                        },
                                        plotLines: [{  
                                              value: 0,  
                                              width: 1,  
                                              color: '#808080'  
                                             }] 
                                    },
                                    tooltip: {  
                                                //enabled: false,  //是否显示提示框
                                                formatter: function() {  
                                                        return "时间:"+this.x +'<br/>'+"参数值:"+ this.y;
                                                }  
                                          }
                                    //,
//                                   series : [{
//                                                name : '实时数据显示',
//                                                data : [141, 100, 4]
//                                            }]
                                };
                }
            });
};
Ext.extend(Ext.ux.WaterRealtimeDisplayPanel, Ext.FormPanel, {
});
Ext.reg('ljsStudentTuPanel', Ext.ux.WaterRealtimeDisplayPanel);


后台导出图片的方法是:
public class ImageController extends Controller{

    public void index(){
        
        String type = getPara("type");
        String svg =getPara("svg");
        String filename = getPara("filename");
        ServletOutputStream out1 =  null;
        try {
            filename = filename==null?"chart":filename;
             out1 = getResponse().getOutputStream();
            if (null != type && null != svg) {
                svg = svg.replaceAll(":rect", "rect");
                String ext = "";
                Transcoder t = null;
                if (type.equals("image/png")) {
                    ext = "png";
                    t = new PNGTranscoder();
                } else if (type.equals("image/jpeg")) {
                    ext = "jpg";
                    t = new JPEGTranscoder();
                } else if(type.equals("image/svg+xml")) {
                      ext = "svg"; 
                }else if(type.equals("application/pdf")){
                    t = new PDFTranscoder();
                    ext = "pdf";
                }
                    
                getResponse().addHeader("Content-Disposition", "attachment; filename="+ filename + "."+ext);
                getResponse().addHeader("Content-Type", type);
                
                if (null != t) {
                    TranscoderInput input = new TranscoderInput(new StringReader(svg));
                    TranscoderOutput output = new TranscoderOutput(out1);                    
                    try {
                        t.transcode(input, output);
                    } catch (TranscoderException e) {
                        out1.print("Problem transcoding stream. See the web logs for more details.");
                        e.printStackTrace();
                    }
                } else if (ext.equals("svg")) {
                    OutputStreamWriter writer = new OutputStreamWriter(out1, "UTF-8");
                    writer.append(svg);
                    writer.flush();
                    writer.close();
                } else 
                    out1.print("Invalid type: " + type);
            } else {
                //getResponse().addHeader("Content-Type", "text/html");
               // out.println("Usage:\n\tParameter [svg]: The DOM Element to be converted." +
               //         "\n\tParameter [type]: The destination MIME type for the elment to be transcoded.");
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            try {
                out1.flush();
                getResponse().flushBuffer(); 
                out1.close();
                
            } catch (Exception e2) {
            
            }
            
        }
        
        renderNull();//不跳转
        
        

        }
}
 

java由年份和月份获得这个月有多少天

 public static int getDaysByMonth(String time){
         Calendar rightNow = Calendar.getInstance();

         SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM"); //若是写成年月日的形式的话,要写小d,如:"yyyy/MM/dd"

         try {

         rightNow.setTime(simpleDate.parse(time)); //要计算你想要的月份,改变这里便可

         } catch (Exception e) {

         e.printStackTrace();

         }

         int days = rightNow.getActualMaximum(Calendar.DAY_OF_MONTH);
return days;
        
     }

     public static List<String> getWeekDay(String str) {
         List<String> list = new ArrayList<String>();
         Calendar c = Calendar.getInstance(); 
           SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
           Date date = null;
        try {
            date = sdf.parse(str);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
           c.setTime(date);
           int week = c.get(Calendar.WEEK_OF_MONTH);//获取是本月的第几周 
           System.out.println("今天是本月的第" + week + "周");
            String nReturn;
            switch (c.get(Calendar.DAY_OF_WEEK)) {
            case 1:
                nReturn = "7";
                break;
            case 2:
                nReturn = "1";
                break;
            case 3:
                nReturn = "2";
                break;
            case 4:
                nReturn = "3";
                break;
            case 5:
                nReturn = "4";
                break;
            case 6:
                nReturn = "5";
                break;
            case 7:
                nReturn = "6";
                break;
            default:
                nReturn = null;
                break;
            }
            list.add(String.valueOf(String.valueOf(week)));
            list.add(nReturn);
            System.out.println(nReturn);
            return list;
        }
 

取得今天的星期几java

public static String getWeekOfDate(Date dt) {
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);

        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;

        return weekDays[w];
    }

 

setInterval和setTimeout的区别

这两个方法均可以用来实如今一个固定时间段以后去执行JavaScript。不过二者各有各的应用场景。

 方 法

实际上,setTimeout和setInterval的语法相同。它们都有两个参数,一个是将要执行的代码字符串,还有一个是以毫秒为单位的时间间隔,当过了那个时间段以后就将执行那段代码。

不过这两个函数仍是有区别的,setInterval在执行完一次代码以后,通过了那个固定的时间间隔,它还会自动重复执行代码,而setTimeout只执行一次那段代码。

虽然表面上看来setTimeout只能应用在on-off方式的动做上,不过能够经过建立一个函数循环重复调用setTimeout,以实现重复的操做:

showTime();
function showTime()
{
    var today = new Date();
    alert("The time is: " + today.toString());
    setTimeout("showTime()", 5000);
}
一旦调用了这个函数,那么就会每隔5秒钟就显示一次时间。若是使用setInterval,则相应的代码以下所示: 
setInterval("showTime()", 5000);
function showTime()
{
    var today = new Date();
    alert("The time is: " + today.toString());
}

这两种方法可能看起来很是像,并且显示的结果也会很类似,不过二者的最大区别就是,setTimeout方法不会每隔5秒钟就执行一次showTime函数,它是在每次调用setTimeout后过5秒钟再去执行showTime函数。这意味着若是showTime函数的主体部分须要2秒钟执行完,那么整个函数则要每7秒钟才执行一次。而setInterval却没有被本身所调用的函数所束缚,它只是简单地每隔必定时间就重复执行一次那个函数。

若是要求在每隔一个固定的时间间隔后就精确地执行某动做,那么最好使用setInterval,而若是不想因为连续调用产生互相干扰的问题,尤为是每次函数的调用须要繁重的计算以及很长的处理时间,那么最好使用setTimeout。

两个计时函数中的第一个参数是一段代码的字符串,其实该参数也能够是一个函数指针,不过Mac下的IE 5对此不支持。

若是用函数指针做为setTimeout和setInterval函数的第二个参数,那么它们就能够去执行一个在别处定义的函数了:

setTimeout(showTime, 500);

function showTime()

{

    var today = new Date();

    alert("The time is: " + today.toString());

}

另外,匿名函数还能够声明为内联函数:

setTimeout(function(){var today = new Date();

     alert("The time is: " + today.toString());}, 500);

若是对计时函数不加以处理,那么setInterval将会持续执行相同的代码,一直到浏览器窗口关闭,或者用户转到了另一个页面为止。不过仍是有办法能够终止setTimeout和setInterval函数的执行。

当setInterval调用执行完毕时,它将返回一个timer ID,未来即可以利用该值对计时器进行访问,若是将该ID传递给clearInterval,即可以终止那段被调用的过程代码的执行了,具体实现以下:

var intervalProcess = setInterval("alert('GOAL!')", 3000);
var stopGoalLink = document.getElementById("stopGoalLink");
attachEventListener(stopGoalLink, "click", stopGoal, false);
function stopGoal()
{
    clearInterval(intervalProcess);
}
只要点击了stopGoalLink,无论是何时点击,intervalProcess都会被取消掉,之后都不会再继续反复执行intervalProcess。若是在超时时间段内就取消setTimeout,那么这种终止效果也能够在setTimeout身上实现,具体实现以下: 

var timeoutProcess = setTimeout("alert('GOAL!')", 3000);
var stopGoalLink = document.getElementById("stopGoalLink");
attachEventListener(stopGoalLink, "click", stopGoal, false);
function stopGoal()
{
   clearTimeout(timeoutProcess);
}
 

jquery隐藏和显示的切换


<html >
<head>
<style type="text/css">
 *{ margin:0; padding:0;}
body {font-size:12px;text-align:center;}
a { color:#04D; text-decoration:none;}
a:hover { color:#F50; text-decoration:underline;}
.SubCategoryBox {width:600px; margin:0 auto; text-align:center;margin-top:40px;}
.SubCategoryBox ul { list-style:none;}
.SubCategoryBox ul li { display:block; float:left; width:200px; line-height:20px;}
.showmore { clear:both; text-align:center;padding-top:10px;}
.showmore a { display:block; width:120px; margin:0 auto; line-height:24px; border:1px solid #AAA;}
.showmore a span { padding-left:15px; background:url(img/down.gif) no-repeat 0 0;}
.promoted a { color:#F50;}
</style>
<!-- 引入jQuery -->
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){                                     //  等待DOM加载完毕.
        var $category = $('ul li:gt(5):not(:last)');             //  得到索引值大于5的品牌集合对象(除最后一条)    
        $category.hide();                                //  隐藏上面获取到的jQuery对象。
        var $toggleBtn = $('div.showmore > a');             //  获取“显示所有品牌”按钮
        $toggleBtn.click(function(){
              if($category.is(":visible")){
                    $category.hide();                            //  隐藏$category
                    $('.showmore a span')
                        .css("background","url(img/down.gif) no-repeat 0 0")      
                        .text("显示所有品牌");                  //改变背景图片和文本
                    $('ul li').removeClass("promoted");            // 去掉高亮样式
              }else{
                    $category.show();                            //  显示$category
                    $('.showmore a span')
                        .css("background","url(img/up.gif) no-repeat 0 0")      
                        .text("精简显示品牌");                  //改变背景图片和文本
                    $('ul li').filter(":contains('佳能'),:contains('尼康'),:contains('奥林巴斯')")
                        .addClass("promoted");                //添加高亮样式
              }
            return false;                              //超连接不跳转
        })
})
</script>
</head>
<body>
<div class="SubCategoryBox">
<ul>
<li ><a href="#">佳能</a><i>(30440) </i></li>
<li ><a href="#">索尼</a><i>(27220) </i></li>
<li ><a href="#">三星</a><i>(20808) </i></li>
<li ><a href="#">尼康</a><i>(17821) </i></li>
<li ><a href="#">松下</a><i>(12289) </i></li>
<li ><a href="#">卡西欧</a><i>(8242) </i></li>
<li ><a href="#">富士</a><i>(14894) </i></li>
<li ><a href="#">柯达</a><i>(9520) </i></li>
<li ><a href="#">宾得</a><i>(2195) </i></li>
<li ><a href="#">理光</a><i>(4114) </i></li>
<li ><a href="#">奥林巴斯</a><i>(12205) </i></li>
<li ><a href="#">明基</a><i>(1466) </i></li>
<li ><a href="#">爱国者</a><i>(3091) </i></li>
<li ><a href="#">其它品牌相机</a><i>(7275) </i></li>
</ul>
<div class="showmore">
<a href="more.html"><span>显示所有品牌</span></a>
</div>
</div>
</body>
</html>
 

jquery笔记

javascript点击触发事件

<html>
<head>
 <title></title>
 <script type="text/javascript">
  function demo(){
    alert('JavaScript demo.');
  }
</script>
</head>
<body>
<p οnclick="demo();">点击我.</p>
</body>
</html>

jquery点击触发事件

<html>
<head>
 <title></title>
 <!--   引入jQuery -->
 <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
</head>
<body>
    <p class="demo">jQuery Demo</p>
    <script type="text/javascript">
        $(".demo").click(function(){          // 给class为demo 的元素添加行为
           alert("jQuery demo!"); 
        })
    </script>
</body>
</html>

javascript得到元素改变css

<html >
<head>
</head>
<body>
    <div id="tt">test</div>
    <script type="text/javascript">
        document.getElementById("tt").style.color="red";
    </script>
</body>
</html>

jquery获得元素改变css

<html >
<head>
    <!--   引入jQuery -->
    <script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
</head>
<body>
    <div id="tt">test</div>
    <script type="text/javascript">
        $('#tt').css("color","yellow");
    </script>
</body>
</html>

javascript多选的获得值

<html >
<head>
<script type="text/javascript">
window.onload = function(){//页面全部元素加载完毕
    var btn = document.getElementById("btn");  //获取id为btn的元素(button)
    btn.onclick = function(){                   //给元素添加onclick事件
        var arrays = new Array();              //建立一个数组对象
        var items = document.getElementsByName("check");  //获取name为check的一组元素(checkbox)
        for(i=0; i < items.length; i++){  //循环这组数据
            if(items[i].checked){      //判断是否选中
                arrays.push(items[i].value);  //把符合条件的 添加到数组中. push()是javascript数组中的方法.
            }
        }
        alert( "选中的个数为:"+arrays.length  );
    }
}
</script>
</head>
<body>
<form method="post" action="#">
    <input type="checkbox" value="1" name="check" checked="checked"/>
    <input type="checkbox" value="2" name="check" />
    <input type="checkbox" value="3" name="check" checked="checked"/>
    <input type="button" value="你选中的个数" id="btn"/>
</form>
</body>
</html>

jquery隔行换色

<html >
<head>
<!--   引入jQuery -->
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script language="javascript" >
    $(function(){// dom元素加载完毕
       $('#tb tbody tr:even').css("backgroundColor","#888");//偶数行
         $('#tb tbody tr:odd').css("backgroundColor","red");//奇数行
       //获取id为tb的元素,而后寻找他下面的tbody标签,再寻找tbody下索引值是偶数的tr元素,
       //改变它的背景色.
    })
</script>
</head>
<body>
<table id="tb">
<tbody>
<tr><td>第一行</td><td>第一行</td></tr>
<tr><td>第二行</td><td>第二行</td></tr>
<tr><td>第三行</td><td>第三行</td></tr>
<tr><td>第四行</td><td>第四行</td></tr>
<tr><td>第五行</td><td>第五行</td></tr>
<tr><td>第六行</td><td>第六行</td></tr>
</tbody>
</table>
</body>
</html>

javascript隔行换色

<html >
<head>
<script type="text/javascript">
window.onload = function(){ //页面全部元素加载完毕
    var item  =  document.getElementById("tb");            //获取id为tb的元素(table)
    var tbody =  item.getElementsByTagName("tbody")[0];    //获取表格的第一个tbody元素
    var trs =   tbody.getElementsByTagName("tr");            //获取tbody元素下的全部tr元素
    for(var i=0;i < trs.length;i++){//循环tr元素
        if(i%2==0){        //取模. (取余数.好比 0%2=0 , 1%2=1 , 2%2=0 , 3%2=1)
            trs[i].style.backgroundColor = "#888"; // 改变 符合条件的tr元素 的背景色.
        }else {
            trs[i].style.backgroundColor = "red";
        }
    }
}
</script>
</head>
<body>
<table id="tb">
    <tbody>
        <tr><td>第一行</td><td>第一行</td></tr>
        <tr><td>第二行</td><td>第二行</td></tr>
        <tr><td>第三行</td><td>第三行</td></tr>
        <tr><td>第四行</td><td>第四行</td></tr>
        <tr><td>第五行</td><td>第五行</td></tr>
        <tr><td>第六行</td><td>第六行</td></tr>
    </tbody>
</table>
</body>
</html>

jquery获得checkbox值

<html>
<head>
<!--   引入jQuery -->
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script language="javascript" >
    $(function(){// dom元素加载完毕
        $('#btn').click(function(){ //获取id为btn的元素,给它添加onclick事件
            var items =  $("input[name='check']:checked"); 
            //获取name为check的一组元素,而后选取它们中选中(checked)的。
          //     alert( "选中的个数为:"+items.length  )
           items.each(function(){
            
            alert($(this).val());
           });
        })
    })
</script>
</head>
<body>
<input type="checkbox" value="1" name="check" checked/>
<input type="checkbox" value="2" name="check" />
<input type="checkbox" value="3" name="check" checked/>
<input type="button" value="测试选中的个数" id="btn"/>
</body>
</html>
 $('ul li:gt(5):not(:last)') : 
      选取ul元素下的li元素的索引值大于5的集合元素后,去掉集合元素中的最后一个。
      索引值从0开始。
 

checkbox使用javascript和jquery两种方式选择

DOM方式
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>1-6-2</title>
<!-- 引入 jQuery -->
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
//等待dom元素加载完毕.
$(document).ready(function(){
    var $cr = $("#cr");  //jQuery对象
    var cr = $cr.get(0); //DOM对象,获取 $cr[0]
    $cr.click(function(){
        if(cr.checked){ //DOM方式判断
            alert("感谢你的支持!你能够继续操做!");
        }
    })
});
</script>
</head>
<body>
<input type="checkbox" id="cr"/> <label for="cr">我已经阅读了上面制度.</label>
</body>
</html>
jQuery方式
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>1-6-1</title>
<!-- 引入 jQuery -->
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
//等待dom元素加载完毕.
$(document).ready(function(){
    var $cr = $("#cr");  //jQuery对象
    $cr.click(function(){
        if($cr.is(":checked")){ //jQuery方式判断
            alert("感谢你的支持!你能够继续操做!");
        }
    })
});
</script>
</head>
<body>
<input type="checkbox" id="cr"/><label for="cr">我已经阅读了上面制度.</label>
</body>
</html>
 

折叠隐藏导航栏jquery

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>1-5-1</title>
<style type="text/css">
#menu { 
    width:300px; 
}
.has_children{
    background : #555;
    color :#fff;
    cursor:pointer;
}
.highlight{
    color : #fff;
    background : green;
}
div{
    padding:0;
}
div a{
    background : #888;
    display : none;
    float:left;
    width:300px;
}
</style>
<!-- 引入 jQuery -->
<script src="../../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
//等待dom元素加载完毕.
$(document).ready(function(){
    $(".has_children").click(function(){
        $(this).addClass("highlight")            //为当前元素增长highlight类
            .children("a").show().end()            //将子节点的a元素显示出来并从新定位到上次操做的元素
        .siblings().removeClass("highlight")        //获取元素的兄弟元素,并去掉他们的highlight类
            .children("a").hide();                //将兄弟元素下的a元素隐藏
    });
});
</script>
</head>
<body>
<div id="menu">
    <div class="has_children">
        <span>第1章-认识jQuery</span>
        <a>1.1-JavaScript和JavaScript库</a>
        <a>1.2-加入jQuery</a>
        <a>1.3-编写简单jQuery代码</a>
        <a>1.4-jQuery对象和DOM对象</a>
        <a>1.5-解决jQuery和其它库的冲突</a>
        <a>1.6-jQuery开发工具和插件</a>
        <a>1.7-小结</a>
    </div>
    <div class="has_children">
        <span>第2章-jQuery选择器</span>
        <a>2.1-jQuery选择器是什么</a>
        <a>2.2-jQuery选择器的优点</a>
        <a>2.3-jQuery选择器</a>
        <a>2.4-应用jQuery改写示例</a>
        <a>2.5-选择器中的一些注意事项</a>
        <a>2.6-案例研究——相似淘宝网品牌列表的效果</a>
        <a>2.7-还有其它选择器么?</a>
        <a>2.8-小结</a>
    </div>
    <div class="has_children">
        <span>第3章-jQuery中的DOM操做</span>
        <a>3.1-DOM操做的分类</a>
        <a>3.2-jQuery中的DOM操做</a>
        <a>3.3-案例研究——某网站超连接和图片提示效果</a>
        <a>3.4-小结</a>
    </div>
</div>
</body>
</html>
 

javascript笔记

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>1-4</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- 引入 jQuery -->
<script src="../scripts/jquery-1.3.1.js" type="text/javascript"></script>
<script type="text/javascript">
//等待dom元素加载完毕.
$(document).ready(function(){
    var domObj = document.getElementsByTagName("h3")[0]; // Dom对象
    var $jQueryObj = $(domObj);  //jQuery对象
    alert("DOM对象:"+domObj.innerHTML);
    alert("jQuery对象:"+$jQueryObj.html());
});
</script>
</head>
<body>
<h3>例子</h3>

</body>
</html>
     摘要: //定义一个对象 var obj = new Object(); //动态建立属性name obj.name = "an object"; //动态建立属性sayHi obj.sayHi = function(){ return "Hi";...   阅读全文
 

java程序性能优化2

HaspMap的遍历。 Map<String, String[]> paraMap = new HashMap<String, String[]>(); for( Entry<String, String[]> entry : paraMap.entrySet() )
{ String appFieldDefId = entry.getKey(); String[] values = entry.getValue(); }
利用散列值取出相应的Entry作比较获得结果,取得entry的值以后直接取key和 value。
奇偶判断 不要使用 i % 2 == 1 来判断是不是奇数,由于i为负奇数时不成立,请使用 i % 2 != 0 来判断是不是奇数,或使用 高效式 (i & 1) != 0来判断。
 

java程序性能优化3

6、避免不须要的instanceof操做 若是左边的对象的静态类型等于右边的,instanceof表达式返回永远为true。 例子: public class uiso { public uiso () {} } class dog extends uiso { void method (dog dog, uiso u) { dog d = dog;if (d instanceof uiso) // always true. system.out.println("dog is a uiso"); uiso uiso = u; if (uiso instanceof object) // always true. system.out.println("uiso is an object"); } } 更正: 删掉不须要的instanceof操做。 class dog extends uiso { void method () { dog d; system.out.println ("dog is an uiso"); system.out.println ("uiso is an uiso"); } }
7、避免不须要的造型操做 全部的类都是直接或者间接继承自object。一样,全部的子类也都隐含的“等于”其父类。那么,由子类造型至父类的操做就是没必要要的了。 例子: class unc { string _id = "unc"; } class dog extends unc { void method () { dog dog = new dog (); unc animal = (unc)dog; // not necessary. object o = (object)dog; // not necessary. } } 更正: class dog extends unc { void method () { dog dog = new dog(); unc animal = dog; object o = dog; } }
8、若是只是查找单个字符的话,用charat()代替startswith()
用一个字符做为参数调用startswith()也会工做的很好,但从性能角度上来看,调用用string api无疑是错误的! 例子: public class pcts { private void method(string s) { if (s.startswith("a")) { // violation // ... } } } 更正 将'startswith()' 替换成'charat()'. public class pcts { private void method(string s) { if ('a' == s.charat(0)) { // ... } } }
9、使用移位操做来代替'a / b'操做 "/"是一个很“昂贵”的操做,使用移位操做将会更快更有效。 例子: public class sdiv { public static final int num = 16; public void calculate(int a) { int div = a / 4; // should be replaced with "a >> 2". int div2 = a / 8; // should be replaced with "a >> 3". int temp = a / 3; } } 更正: public class sdiv { public static final int num = 16; public void calculate(int a) { int div = a >> 2; int div2 = a >> 3; int temp = a / 3; // 不能转换成位移操做 } }
10、使用移位操做代替'a * b'
同上。 [i]但我我的认为,除非是在一个很是大的循环内,性能很是重要,并且你很清楚你本身在作什么,方可以使用这种方法。不然提升性能所带来的程序晚读性的下降将是不合算的。 例子: public class smul { public void calculate(int a) { int mul = a * 4; // should be replaced with "a << 2". int mul2 = 8 * a; // should be replaced with "a << 3". int temp = a * 3; } } 更正: package opt; public class smul { public void calculate(int a) { int mul = a << 2; int mul2 = a << 3; int temp = a * 3; // 不能转换 } }
11、在字符串相加的时候,使用 ' ' 代替 " ",若是该字符串只有一个字符的话 例子: public class str { public void method(string s) { string string = s + "d" // violation. string = "abc" + "d" // violation. } } 更正: 将一个字符的字符串替换成' ' public class str { public void method(string s) { string string = s + 'd' string = "abc" + 'd' } }
12、将try/catch块移出循环 把try/catch块放入循环体内,会极大的影响性能,若是编译jit被关闭或者你所使用的是一个不带jit的jvm,性能会将降低21%之多! 例子: import java.io.fileinputstream; public class try { void method (fileinputstream fis) { for (int i = 0; i < size; i++) { try { // violation _sum += fis.read(); } catch (exception e) {} } } private int _sum; } 更正: 将try/catch块移出循环 void method (fileinputstream fis) { try { for (int i = 0; i < size; i++) {
_sum += fis.read(); } } catch (exception e) {} }
十3、对于boolean值,避免没必要要的等式判断 将一个boolean值与一个true比较是一个恒等操做(直接返回该boolean变量的值). 移走对于boolean的没必要要操做至少会带来2个好处: 1)代码执行的更快 (生成的字节码少了5个字节); 2)代码也会更加干净 。 例子: public class ueq { boolean method (string string) { return string.endswith ("a") == true; // violation } } 更正: class ueq_fixed { boolean method (string string) { return string.endswith ("a"); } }
十4、对于常量字符串,用'string' 代替 'stringbuffer' 常量字符串并不须要动态改变长度。 例子: public class usc { string method () { stringbuffer s = new stringbuffer ("hello"); string t = s + "world!"; return t; } } 更正: 把stringbuffer换成string,若是肯定这个string不会再变的话,这将会减小运行开销提升性能。
十5、使用条件操做符替代"if (cond) return; else return;" 结构 条件操做符更加的简捷 例子: public class if { public int method(boolean isdone) { if (isdone) { return 0; } else { return 10; } } } 更正: public class if { public int method(boolean isdone) { return (isdone ? 0 : 10); } }
十6、不要在循环体中实例化变量 在循环体中实例化临时变量将会增长内存消耗 例子: import java.util.vector; public class loop { void method (vector v) { for (int i=0;i < v.size();i++) { object o = new object(); o = v.elementat(i); } } } 更正: 在循环体外定义变量,并反复使用 import java.util.vector; public class loop { void method (vector v) { object o; for (int i=0;i<v.size();i++) { o = v.elementat(i); } } }
 

java程序性能优化4

1、避免在循环条件中使用复杂表达式 在不作编译优化的状况下,在循环中,循环条件会被反复计算,若是不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快。 例子: import java.util.vector; class cel { void method (vector vector) { for (int i = 0; i < vector.size (); i++) // violation ; //   } } 更正: class cel_fixed { void method (vector vector) { int size = vector.size () for (int i = 0; i < size; i++) ; //   } }
2、为'vectors' 和 'hashtables'定义初始大小 jvm为vector扩充大小的时候须要从新建立一个更大的数组,将原原先数组中的内容复制过来,最后,原先的数组再被回收。可见vector容量的扩大是一个颇费时间的事。 一般,默认的10个元素大小是不够的。你最好能准确的估计你所须要的最佳大小。 例子: import java.util.vector;
 public class dic { public void addobjects (object[] o) { // if length > 10, vector needs to expand for (int i = 0; i< o.length;i++) { v.add(o); // capacity before it can add more elements. } } public vector v = new vector(); // no initialcapacity. } 更正: 本身设定初始大小。 public vector v = new vector(20); public hashtable hash = new hashtable(10);

3、在finally块中关闭stream 程序中使用到的资源应当被释放,以免资源泄漏。这最好在finally块中去作。无论程序执行的结果如何,finally块老是会执行的,以确保资源的正确关闭。 例子: import java.io.*; public class cs { public static void main (string args[]) { cs cs = new cs (); cs.method (); } public void method () { try { fileinputstream fis = new fileinputstream ("cs.java"); int count = 0; while (fis.read () != -1) count++; system.out.println (count); fis.close (); } catch (filenotfoundexception e1) { } catch (ioexception e2) { } } } 更正: 在最后一个catch后添加一个finally块

4、使用'system.arraycopy ()'代替经过来循环复制数组 'system.arraycopy ()' 要比经过循环来复制数组快的多。 例子: public class irb { void method () { int[] array1 = new int [100]; for (int i = 0; i < array1.length; i++) { array1 [i] = i; } int[] array2 = new int [100]; for (int i = 0; i < array2.length; i++) { array2 [i] = array1 [i]; // violation } } } 更正: public class irb{ void method () { int[] array1 = new int [100]; for (int i = 0; i < array1.length; i++) { array1 [i] = i; } int[] array2 = new int [100]; system.arraycopy(array1, 0, array2, 0, 100); } }

5、让访问实例内变量的getter/setter方法变成”final” 简单的getter/setter方法应该被置成final,这会告诉编译器,这个方法不会被重载,因此,能够变成”inlined” 例子: class maf { public void setsize (int size) { _size = size; } private int _size; } 更正: class daf_fixed { final public void setsize (int size) { _size = size; } private int _size; }

checkbox选择

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<style type="text/css" media="all"> 
label{ 
cursor:pointer; 
font-size:12px; 
margin:0px 2px 0px 0px; 
color:#2B86BD; 
.d0{ 
margin-bottom:30px; 
.d0 input{ 
cursor:pointer; 
margin:0px; 
padding:0px 2px; 
</style> 
<script language="javascript" type="text/javascript"> 
var dr=document.getElementsByTagName("div"),i,t=""; 
function submit1(num,type){ 
t=""; 
var dri=dr[num].getElementsByTagName("input"); 
for(i=0;i<dri.length;i++){ 
if(dri[i].checked){ 
if(type==0){ 
alert(dri[i].value); 
break; 
}else{ 
t=t+dri[i].value+";"; 
if(type==1) alert(t); 
//ChangeSelect 
submit1.allselect=function(){ 
var drc=dr[1].getElementsByTagName("input"); 
for(i=0;i<drc.length;i++){ 
drc[i].checked=true; 
//allNot 
submit1.allNot=function(){ 
var drc=dr[1].getElementsByTagName("input"); 
for(i=0;i<drc.length;i++){ 
drc[i].checked=false; 
//reverse 
submit1.reverseSelect=function(){ 
var drc=dr[1].getElementsByTagName("input"); 
for(i=0;i<drc.length;i++){ 
if(drc[i].checked){ 
drc[i].checked=false; 
}else{ 
drc[i].checked=true; 
</script> 
<title>js获取单选框、复选框的值及操做</title> 
</head> 
<body> 
<div class="d0"> 
<input type="radio" name="day" id="r0" value="前天"/><label for="r0">前天</label> 
<input type="radio" name="day" id="r1" value="昨天"/><label for="r1">昨天</label> 
<input type="radio" name="day" id="r2" checked="checked" value="今天"/><label for="r2">今天</label> 
<input type="radio" name="day" id="r3" value="明天"/><label for="r3">明天</label> 
<input type="radio" name="day" id="r4" value="后天"/><label for="r4">后天</label> 
<button type="button" οnclick="submit1(0,0)" >提交</button> 
</div> 
<div> 
<input type="checkbox" value="前年" οnclick="alert(this.value);"/><label>前年</label> 
<input type="checkbox" value="去年" οnclick="submit1(1,1);"/><label>去年</label> 
<input type="checkbox" value="今年" /><label>今年</label> 
<input type="checkbox" value="明年"/><label>明年</label> 
<input type="checkbox" value="后年"/><label>后年</label> 
<button type="button" οnclick="submit1(1,1)" >提交</button> 
<button type="button" οnclick="submit1.allselect()" >全选</button> 
<button type="button" οnclick="submit1.reverseSelect()" >反选</button> 
<button type="button" οnclick="submit1.allNot()" >全不选</button> 
</div> 
</body> 
</html> 

ext向后台传隐藏的id值

var stroeName = new Ext.data.JsonStore({
        autoLoad : true,
        url : "BookAction_getName.action",
        root : "options",
        fields : [
                  'name','id'
                  ]
        
    });

    
    var state = new Ext.form.ComboBox({
        name : 'name',
        fieldLabel : '图书名',
        allowBlank : false,
        blankText : '请选择',
        emptyText : '请选择',
        editable : false,
        triggerAction : 'all',
        store : stroeName,
        //加载本地数据框
        mode : 'local',
        displayField : 'name',
        valueField : 'id',
        hiddenName :'id',
        //hiddenName :'id',
        width : 125
    });
 

Niagara采集温湿度和控制灯的亮灭

1.在采集温湿度数据时,如今config下创建温湿度的文件夹(view),

2.在此文件夹下新创建NumericWritable的wen节点,在view中创建kitPx中的Bargraph柱状图,编辑对应wen节点中out中的value,

3.在控制灯的开关时在kitPx中选择ActionButton,为每一个灯选择2个ActionButton,一个开,一个关,编辑开的开关选择此灯节点中的emergencyActive,编辑关的开关选择此灯节点中的emergencyInactive,

4.在Palette中找iopt,找host,,在config下创建iopt文件夹,Local Port设置6800,Dest Port设置1025

 

Niagara新建station灯光报警

1.在tools中选择new station,新建一个station

2.点击Platform启动新建的station

3.在File中选择open station(fox)点击

4.选择station中的Config右键新建文件夹(如yang)

5.在此文件夹下右键新疆Wire Sheet

6.在Wire Sheet下右键选择new 一个numericWritable

7.在这个numericWritable右键action中set数值

8.重复6.7再次创建一个标准值的numericWritable

9.在Wire Sheet下右键选择new 一个BooleanWritable

10.在这个BooleanWritable右键action中setboolean值

11.在Window中的Side Bars中点击Palette

12.在Palette中找到kitControl中的Logic中的GreaterThan拖入到Wire Sheet中

13.让两个的numericWritable的Out分别指向GreaterThan的A和B(A>B是true)

14.再让GreaterThan的Out指向BooleanWritable其中一个值

15.在yang文件夹右键点击Views中的New View

16.在kitPx中把AnalogMeter拖入New View,再双击New View选择ord

在ord的弹出框中的下箭头选择Component Chooser,,选择yang文件夹中的一个值(不是标准值)

17.在KitPxHvac中的boolean中的bulb,拖入New View,再双击New View选择ord

在ord的弹出框中的下箭头选择Component Chooser,,选择yang文件夹中的boolean对象。

jfinal源码学习

当用户访问系统时,全部请求先进过在web.xml中配置的com.jfinal.core.JFinalFilter这个核心类,
先执行这个类的的init方法,实例化jfinalConfig对象,这个对象是须要开发者本身定义一个类继承
JFinalConfig类,实现几个抽象方法,其中public void configConstant(Constants me)方法是配置数据库的信息,
开发模式,视图的类型等,public void configRoute(Routes me)方法是配置访问路径的路由信息,
public void configPlugin(Plugins me) 方法是配置数据库链接,其余一些插件,对象模型, public void configInterceptor(Interceptors me)方法是配置全局拦截器,public void configHandler(Handlers me)
是配置处理器,此方法会获得访问的url,进行处理。此类须要在web.xml中配置,以下:
  <filter>
    <filter-name>jfinal</filter-name>
    <filter-class>com.jfinal.core.JFinalFilter</filter-class>
    <init-param>
      <param-name>configClass</param-name>
      <param-value>com.demo.config.DemoConfig</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>jfinal</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
在JFinalFilter类中当执行完init方法后,会执行jfinal类的init方法,此方法是先定义获得工程的路径,再初始化开发者刚刚写的
继承JFinalConfig类的类,读入配置信息。当init方法执行完后,执行doFilter方法,获得用户访问的url,分到不一样的handler中进行处理

java时间程序

     摘要: import java.util.*;002import java.text.*;003import java.util.Calendar;004public class VeDate {005 /**006  * 获取如今时间007  * 008  * <a href="http://my.oschina.net/u/5...   阅读全文
 

多个有用的程序

     摘要: 1. 字符串有整型的相互转换 1    2 String a = String.valueOf(2);   //integer to numeric string   3 int i = Integer.parseInt(a); //numeric string to an int ...   阅读全文
 

svn使用

     摘要: 1.svn环境搭建在应用myEclips 8.5作项目时,svn会成为团队项目的一个很是好的工具,苦苦在网上寻求了一下午,终于整合好了这个环境,在这里简单介绍下,但愿能为刚开始用svn的朋友一点点帮助。   svn环境须要(1)服务器端(2)客户端(3)应用在myeclipse中的svn插件   第一步,安装svn服务器端。我用的是VisualSVN-Server-2.1.3这...   阅读全文
 

myeclipse自动提示配置

1. 打开MyEclipse,而后 Window-------->Preferences;

 

2.选择Java-------->展开-------->Editor-------->选择ContentAssist;

 

3.选择ContentAssist-------->而后看到右边-------->右边的Auto-Activation下面的Auto Activation triggers for java(指触发代码提示的就是”.”这个符号)这个选项;

4. AutoActivation triggers for java这个选项-------->在”.”后加
abcdefghijklmnopqrstuvwxyz
字母,方便后面的查找修改-------->而后apply-------->点击OK;
 

struts2标签

     摘要: Struts2 Taglib抽象了不一样表示技术,如今Struts2主要支持三种表示技术:JSP,FreeMarker和Velocity。但部分的Tag在三种表示技术下均可以使用,可是也有部分只能在某一种状况下使用。 Tab能够分为两类:通用标签和UI标签。 4.1节 通用标签 通用标签用来在页面表示的时候控制代码执行的过程,这些标签也容许从Action或者值堆栈中取得数据。例如地域,JavaBea...   阅读全文
 

4.1链接池知识简介

众所周知创建数据库链接是一个很是耗时耗资源的行为,所以现代的Web中间件,不管是开源的Tomcat、Jboss仍是商业的 websphere、weblogic都提供了数据库链接池功能,能够绝不夸张的说,数据库链接池性能的好坏,不一样厂商对链接池有着不一样的实现,本文只介 绍拜特公司使用较多的开源web中间件Tomcat中默认的链接池DBCP(DataBase connection pool)的使用。

4.2 Tomcat下配置链接池

下面以tomcat5.5.26为例来介绍如何配置链接池

1:须要的jar

在tomcat的安装目录common\lib下有一个naming-factory-dbcp.jar,这个是tomcat修改后的dbcp链接池实现,同时为了可以正常运行,还须要commons-pool.jar。

2:创建context文件

进入到conf\Catalina\localhost新建一个上下文文件,文件的名称既为未来要访问是输入url上下文名称,例如咱们创建一个名为btweb的文件内容以下:

<Context debug="0"docBase="D:\v10_workspace\build\WebRoot"  reloadable="false">

   <Resource

   name="jdbc/btdb1"

  type="javax.sql.DataSource"

  factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"

    username="v10"

    password="v10"

driverClassName="oracle.jdbc.driver.OracleDriver"

url="jdbc:oracle:thin:@127.0.0.1:1521:cahs"

    maxActive="5"

    maxIdle="3"

    maxWait="5000"

    removeAbandoned="true"

removeAbandonedTimeout="60"

testOnBorrow="true"

    validationQuery="selectcount(*) from bt_user"

    logAbandoned="true"

       />

  </Context>

4.3参数分步介绍

u  数据库链接相关

username="v10"

   password="v10"

driverClassName="oracle.jdbc.driver.OracleDriver"

url="jdbc:oracle:thin:@127.0.0.1:1521:cahs"

u  jndi相关

name="jdbc/btdb1"

  type="javax.sql.DataSource"

  factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"

factory默认是org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory,tomcat也容许采用其余链接实现,不过默认使用dbcp。

u  链接数控制与链接归还策略

    maxActive="5" 

maxIdle="3" 

minIdle=”2”

    maxWait="5000"

u    应对网络不稳定的策略

testOnBorrow="true"

    validationQuery="selectcount(*) from bt_user"

u  应对链接泄漏的策略

    removeAbandoned="true"

removeAbandonedTimeout="60"

    logAbandoned="true"

  

以下图所示:链接池处于应用程序与数据库之间,一方面应用程序经过它来获取链接,归还链接,另外一方面链接又须要从数据里获取链接,归还链接。

步骤1:系统启动

系统启动时,初始化链接池,因为没有任何请求链接池中链接数为0。

maxActive="5"

表示并发状况下最大可从链接池中获取的链接数。若是数据库不是单独,供一个应用使用,经过设置maxActive参数能够避免某个应用无限制的获取 链接对其余应用形成影响,若是一个数据库只是用来支持一个应用那么maxActive理论上能够设置成该数据库能够支撑的最大链接数。maxActive 只是表示经过链接池能够并发的获取的最大链接数。

从图上咱们能够看到链接的获取与释放是双向,当应用程序并发请求链接池时,链接池就须要从数据库获取链接,那么但应用程序使用完链接并将链接归还给 链接池时,链接池是否也同时将链接归还给数据库呢?很显然答案是否认的,若是那样的话链接池就变得画蛇添足,不但不能提升性能,反而会下降性能,那么但应 用成归还链接后,链接池如何处理呢?

maxIdle="3"

若是在并发时达到了maxActive=5,那么链接池就必须从数据库中获取5个链接来供应用程序使用,当应用程序关闭链接后,因为maxIdle=3,所以并非全部的链接都会归还给数据库,将会有3个链接保持在链接池种中,状态为空闲。

minIdle=”2”

最小默认状况下并不生效,它的含义是当链接池中的链接少有minIdle,系统监控线程将启动补充功能,通常状况下咱们并不启动补充线程。

问题:如何设置maxActive和maxIdle?

理论上讲maxActive应该设置成应用的最大并发数,这样一来即使是在最大并发的状况下,应用依然可以从链接池中获取链接,可是困难时的是咱们 很难准确估计到最大并发数,设置成最大并发数是一种最优的服务质量保证,事实上,若是某个用户登陆提示系统繁忙,那么在他再次登陆时,可能系统资源已经充 足,对于拜特资金管理系统咱们建议将maxActive设置为系统注册人数的十分之一到二十分之一之间。例如系统的注册人数为1000,那么设置成50-100靠近100的数字,例如85或90。

maxIdle对应的链接,其实是链接池保持的长链接,这也是链接池发挥优点的部分,理论上讲保持较多的长链接,在应用请求时能够更快的响应,可是过多的链接保持,反而会消耗数据库大量的资源,所以maxIdle也并非越大越好,同上例咱们建议将maxIdle设置成

50-100中靠近50的数字,例如55。这样就能在兼顾最大并发同时,保持较少的数据库链接,并且在绝大多状况,可以为应用程序提供最快的相应速度。

testOnBorrow="true"

validationQuery="selectcount(*) from bt_user"

咱们知道数据库链接从本质上架构在tcp/ip链接之上,通常状况下web服务器与数据库服务器都不在同一台物理机器上,而是经过网络进行链接,那 么当创建数据库链接池的机器与数据库服务器本身出现网络异常时,保持在链接池中的链接将失效,不可以在次使用,传统的状况下只能经过从新启动,再次创建连 接,经过设置以上两个参数,但应用程序从链接池中获取链接时,会首先进行活动性检测,当获取的链接是活动的时候才会给应用程序使用,若是链接失效,链接将 释放该链接。validationQuery是一条测试语句,没有实际意义,现实中,通常用一条最为简单的查询语句充当。

removeAbandoned="true"

removeAbandonedTimeout="60"

logAbandoned="true"

有时粗心的程序编写者在从链接池中获取链接使用后忘记了链接的关闭,这样连池的链接就会逐渐达到maxActive直至链接池没法提供服务。现代链接池通常提供一种“智能”的检查,但设置了removeAbandoned="true"时,当链接池链接数到达(getNumIdle() < 2) and (getNumActive() > getMaxActive() - 3)时便会启动链接回收,那种活动时间超过removeAbandonedTimeout="60"的链接将会被回收,同时若是logAbandoned="true"设置为true,程序在回收链接的同时会打印日志。removeAbandoned是链接池的高级功能,理论上这中配置不该该出如今实际的生产环境,由于有时应用程序执行长事务,可能这种状况下,会被链接池误回收,该种配置通常在程序测试阶段,为了定位链接泄漏的具体代码位置,被开启,生产环境中链接的关闭应该靠程序本身保证。

strut2ognl

通过一段时间的闭关练习,终于对struts2有所了解.其实struts2并不难, 一看就能明白其中奥妙.我对struts2的验证体系保留怀疑态度,由于它的验证消息使用标签打在页面上,实在太丑,在真实项目中不知道是否有人这么作. 也许是我太菜了,还不知道如何将验证消息显示得更友好,但愿各位不吝拍砖指导.
  然而,我认为struts2最复杂难学的是它内置的ognl表达式.这个ognl在我开始学struts2时,让我云里雾里,不知如何应对.通过几轮 的翻看书籍,与网上资料查询,还算是让我有所明白一点.在此记录,以便往后温习,同时,若是这篇文章对各位有哪怕一点帮助,那即是我最大的荣幸.
  首先,要知道ognl最主要的功能就是取数据,它能够利用一段简短的表达式取出各类各样丰富的数据.其次,它还附带了一些便捷的功能,如:方法调用、 静态方法和属性调用、数值运算……咱们最关心的是如何取数据,所以,接下来我将重点介绍如何取数据,至于附带功能将不作介绍。
  知道了ognl最主要的功能是取数据后,那么数据从哪里取呢!ognl会从两个地方取:一个是Action的实例属性;另外一个是 ValueStack(中文名叫值栈)。ognl会先从前者里面取,若是没取到再到ValueStack里取。Action的实例属性好理解,但这个 ValueStack从字面上看,着实很差理解,以至于我将struts2的源码引进eclipse里,单步调试才算有所启发。能够将 ValueStack初步理解为一个map,在这个map里存储了request、session、application、response、 action实例、parameters数组……还有不少你不知道的对象。有了这个map,还愁数据取不到吗。
  注意:将ValueStack初步理解为一个map,只适于初学struts2的人,其实它内部并没这么简单。因为水平、时间有限,我并不能掌握其内 部精髓,加上表达能力不佳,怕表达不对误导你们,因此咱们姑且理解ValueStack为一个map吧。若是想更深的了解的ValueStack,请查看 struts2的源码。

  接下来,即是取数据。取action实例的属性数据与取ValueStack中的数据不同,先说取action实例的属性数据吧。
  action实例的属性数据能够直接在struts2的标签中经过属性名取到。如:<s:property value="name"/>、<s:property value="user.password"/>
  注意:不要加#号。

  再是取ValueStack中的数据。
  struts2提供三种方式经过ognl表达式来取ValueStack中的数据:#、%{}、${}
  #和%{}须要放到struts2提供的标签里才生效。如:<s:property value="#name"/>、<s:property value="%{'hello struts2'}"/>
  1、最经常使用的方式是:#
  1.#能取request、session、application里的attribute,但须要加前缀。如:<s:property value="#session.name2"/>、<s:property value="#application.name3"/>。若是是取request范围的attribute,那么不须要加request前缀, 加上反而取不到数据,ognl默认从request里取,若是没有取到并不会到session或application里取。 如:<s:property value="#name"/>
  2.#能取request里的请求参数,但必须加parameters前缀,且取到的是一个数组,因此若是你要获得参数的第一项值,那么还要加下标。 如:<s:property value="#parameters.name[0]"/>。这至关于调用 request.getParameterValues("name")[0];
  3.#加attr前缀能按request > session > application顺序获取attribute,这样当在request中取不到时,会自动向session里取,若是session里也取不到,会 再向application里取。若是取到则返回,再也不向上游历。如:<s:property value="#attr.name"/>
  4.#能构造Map,如:<s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" /><s:property value="#foobar['foo1']" />
  5.#能用于过滤和投影(projecting)集合,如:books.{?#this.price<100}
  以上第4、5项功能,我没有作过多介绍,由于目前为止这两项功能我使用并很少。
  2、%{}的用途是在标签的属性为字符串类型时,计算OGNL表达式的值。这个功能目前尚未深入体会,故不介绍。
  3、${}有两个主要的用途。
  1.用于在国际化资源文件中,引用OGNL表达式。
  2.在Struts 2配置文件中,引用OGNL表达式。如 :
  <action name="AddPhoto" class="addPhoto">
        <interceptor-ref name="fileUploadStack" />            
        <result type="redirect">ListPhotos.action?albumId=${albumId}</result>
    </action>

  以上,其实主要介绍了#的使用,大部分状况下咱们只与它打交道,另外两种方式须要在之后的项目中多多使用才能有所体会。
  其实,我是jstl+el的忠实粉丝,在任何项目中,只要能用上jstl标签的,我决不用其它标签。由于它是官方标准,还有它简单且已熟练,我已在众多项目中实战演练过,有了它们,我不想在使用其它标签。
  说到了这里,我仍是有必要再多说两句,是否是使用了struts2,就不能再用el来取数据了呢?答案是否认的,彻底能够使用el来取数据。 struts2会将ValueStack里的session、application里的attribute彻底复制到HttpSession、 ServletContext里,这样el表达式照样能取到这两个Scope里的数据。然而,struts2并无将ValueStack里的 request里的attribute复制到HttpServletRequest,这是否是意味着el表达式就不能取request里的数据了呢?仍是 能够,不仅能够取request里的数据,还能够取action实例的属性值。神奇吧!奥秘就在struts2对request作了封装,这个封装类是 org.apache.struts2.dispatcher.StrutsRequestWrapper,它重写了getAttribute()方法, 该方法先从真实的request类里取attribute,若是取到则返回,若是没有取到则从ValueStack里取,如今明白了吧!

各类数据库默认端口

一 :Oracle

    驱动:oracle.jdbc.driver.OracleDriver
    URL:jdbc:oracle:thin:@<machine_name><:port>:dbname
    注:machine_name:数据库所在的机器的名称,若是是本机则是127.0.0.1或者是localhost,若是是远程链接,则是远程的IP地址;    

     port:端口号,默认是1521


二:SQL Server

    驱动:com.microsoft.jdbc.sqlserver.SQLServerDriver
    URL:jdbc:microsoft:sqlserver://<machine_name><:port>;DatabaseName=<dbname>
    注:machine_name:数据库所在的机器的名称,若是是本机则是127.0.0.1或者是localhost,若是是远程链接,则是远程的IP地址;          
     port:端口号,默认是1433

 

三:MySQL

    驱动:org.gjt.mm.mysql.Driver
    URL:jdbc:mysql://<machine_name><:port>/dbname
    注:machine_name:数据库所在的机器的名称,若是是本机则是127.0.0.1或者是localhost,若是是远程链接,则是远程的IP地址;          
     port:端口号,默认3306  

        
 四:pointbase

    驱动:com.pointbase.jdbc.jdbcUniversalDriver
    URL:jdbc:pointbase:server://<machine_name><:port>/dbname
    注:machine_name:数据库所在的机器的名称,若是是本机则是127.0.0.1或者是localhost,若是是远程链接,则是远程的IP地址;
     port:端口号,默认是9092


 五:DB2

    驱动:com.ibm.db2.jdbc.app.DB2Driver
    URL:jdbc:db2://<machine_name><:port>/dbname
    注:machine_name:数据库所在的机器的名称,若是是本机则是127.0.0.1或者是localhost,若是是远程链接,则是远程的IP地址;
     port:端口号,默认是5000

js函数

1、function概述

   javascript中的函数不一样于其余的语言,每一个函数都是做为一个对象被维护和运行的。经过函数对象的性质,能够很方便的将一个函数赋值给一个变量或者将函数做为参数传递。

   函数对象与其余用户所定义的对象有着本质的区别,这一类对象被称之为内部对象。内置对象的构造器是由JavaScript自己所定义的。

2、function对象的建立

在JavaScript中,函数对象对应的类型是Function,能够经过new Function()来建立一个函数对象,也能够经过function关键字来建立一个对象。

    //使用new Function()方式建立

    var myFunction=new Function("a","b","return a+b");

    //使用function关键字建立

    function myFunction(a,b) {

      return a + b;

    }

   用关键字建立对象的时候,在解释器内部,就会自动构造一个Function对象,将函数做为一个内部的对象来存储和运行。从这里也能够看到,一个函数对象 名称(函数变量)和一个普通变量名称具备一样的规范,均可以经过变量名来引用这个变量,可是函数变量名后面能够跟上括号和参数列表来进行函数调用。

    new Function()的语法规范以下:

    var funcName=new Function(p1,p2,...,pn,body);

  参数的类型都是字符串,p1到pn表示所建立函数的参数名称列表,body表示所建立函数的函数体语句,funcName就是所建立函数的名称。能够不指定任何参数建立一个空函数,不指定funcName建立一个匿名函数。

  须要注意的是,p1到pn是参数名称的列表,即p1不只能表明一个参数,它也能够是一个逗号隔开的参数列表,例以下面的定义是等价的:

  new Function("a", "b", "c", "return a+b+c")

  new Function("a, b, c", "return a+b+c")

  new Function("a,b", "c", "return a+b+c")

   函数的本质是一个内部对象,由JavaScript解释器决定其运行方式。而且可直接在函数声明后面加上括号就表示建立完成后当即进行函数调用,例如:

    var i=function (a,b){

    return a+b;

  }(1,2);

  alert(i);

   这段代码会显示变量i的值等于3。i是表示返回的值,而不是建立的函数,由于括号“(”比等号“=”有更高的优先级。

3、匿名函数和有名函数的区别

   匿名函数必须先定义后调用,有名函数能够先调用,后定义。

A)匿名(这段语句将产生func未定义的错误)

   <script>

      func();

      var func = function() {

        alert(1);

      }

   < /script>

B)有名(输出1)

   <script>

      func();

       function func() {

        alert(1);

      }

   < /script>

这是由于JS解释器是分段分析执行的。而且,在同一段中,有名函数会优先被分析。而且同名函数后面的覆盖前面的。

并且,下面这段代码也是合法的:

<script>

function myfunc ()
    {
        alert("hello");
    };
    myfunc(); //这里调用myfunc,输出yeah而不是hello
   
    function myfunc ()
    {
        alert("yeah");
    };   
    myfunc(); //这里调用myfunc,输出yeah

</script>

若是要让上述代码的第一次调用输出“hello”,能够将它们分为两段:

<script>

function myfunc ()
    {
        alert("hello");
    };
    myfunc(); //这里调用myfunc,输出hello
< /script>

<script>
    function myfunc ()
    {
        alert("yeah");
    };   
    myfunc(); //这里调用myfunc,输出yeah

</script>

下面的代码输出“hello”

<script>

function myfunc ()
    {
        alert("hello");
    };
< /script>

<script>

myfunc(); //输出“hello”

</script>

<script>
    function myfunc ()
    {
        alert("yeah");
    };

</script>

下面的代码输出“yeah”

<script>

function myfunc ()
    {
        alert("hello");
    };
< /script>

<script>
    function myfunc ()
    {
        alert("yeah");
    };

</script>

<script>

myfunc(); //输出“yeah”

</script>

从上面对段的位置变化致使输出变化很清楚的解释了JS解释器分段分析执行的本质。

 

java文件上传下载

JAVA的文件上传遍一直是一个比较关注的问题,并且有几个NB东西提供了这个功能.

用的最多的算是三个(我就知道这三个)比较强的,一个是比较早的jspsmartupload,另外一个是出身名族的commonupload,还有一个就是orellay的了.

我用的比较可能是前两个,总的感受是jspsmartuplod比较灵活,功能上更强一些(一点点吧),可是如今网上也不维护,也不能下载了,特别是 它上传的时候把上传文件放到内存里,因此上传文件的大小会和内存有关系.commonupload虽然没有提供不少API,可是它有比较灵活,它上传的过 程中会把上传的文件先写入磁盘,因此上传的大小只是带宽有关系,我尝试最大的上传文件的大小是700M,固然是本地测试:>

还有是就是在Linux/Unix系统上传文件的中文问题,我在下面的代码有了一些解决.

下面是前两种方式的上传代码:

try{
//取session 用户oid
int pid = userInfo.getUserId();
String sys_user_id = String.valueOf(pid);
//取init配置文件的参数值
String sitePhysicalPath = (String)init.getObject("SitePhysicalPath");
String saveDir = (String)init.getObject("InfoUploadDir");
String tempDir = (String)init.getObject("InfoUploadDir");
String fileMemo = ""; //文件说明
String fileName = null; //存储到数据库的文件名
String saveName = null; //存储到本地的文件名
String filePath = null; //存储到数据库的文件路径
String savePath = null; //存储到本地的文件路径
long fileSize = 0; //文件大小
int maxPostSize = -1; 
int dinfo_upload_id = -1;
%>
<%
//初始化
mySmartUpload.initialize(pageContext);
//上载文件
mySmartUpload.upload();
//循环取得全部上载文件
for(int i=0; i<mySmartUpload.getFiles().getCount(); i++)
{
//取得上载文件
com.jspsmart.upload.File file = mySmartUpload.getFiles().getFile(i);
if(!file.isMissing())
{
fileName = file.getFileName();
//取得文件扩展名file.getFileExt()
try{
saveName = fileName.substring(fileName.lastIndexOf("."));

}catch(Exception e){
saveName = "";
}
//取得文件大小
fileSize = file.getSize();
//存储路径
String sql_id = " SELECT S_INFO_UPLOAD.nextval as seqid FROM dual ";
try{
Statement stmt = con.createStatement();
ResultSet rst = stmt.executeQuery(sql_id);
while(rst.next())
{
dinfo_upload_id = rst.getInt("seqid");
}
}catch(SQLException sqle){
return;
}

filePath = sitePhysicalPath + saveDir + Integer.toString(dinfo_upload_id) + saveName;
savePath = saveDir + Integer.toString(dinfo_upload_id) + saveName;
//存储文件到本地
file.saveAs(filePath);
//存储文件到数据库
switch(i)
{
case 0: fileMemo = (String)mySmartUpload.getRequest().getParameter("memo1"); break;
case 1: fileMemo = (String)mySmartUpload.getRequest().getParameter("memo2"); break;
case 2: fileMemo = (String)mySmartUpload.getRequest().getParameter("memo3"); break;
case 3: fileMemo = (String)mySmartUpload.getRequest().getParameter("memo4"); break;
case 4: fileMemo = (String)mySmartUpload.getRequest().getParameter("memo5"); break;
default: fileMemo = "";
}

String sql = " INSERT INTO info_upload (info_upload_id,sys_user_id,file_size,file_path,utime,deleted) "
+ " VALUES( " + Integer.toString(dinfo_upload_id) + "," + sys_user_id + "," + fileSize + ",'" + savePath + "', SYSDATE , 0 )" ;
sqlcmd cmd = new sqlcmd(con,sql);
//System.out.println(sql);
java.sql.PreparedStatement pstmt = null;
java.sql.Statement stmt = null;
//fileName = fileName.substring(0, fileName.indexOf("."));
String sql_cn = " UPDATE info_upload SET file_name=?,file_memo=? WHERE info_upload_id=? ";
java.io.ByteArrayInputStream bais_name = new java.io.ByteArrayInputStream(fileName.getBytes("ISO-8859-1"));
java.io.InputStreamReader isr_name = new java.io.InputStreamReader((InputStream)bais_name,"GBK");

java.io.ByteArrayInputStream bais_memo = new java.io.ByteArrayInputStream(fileMemo.getBytes("GBK"));
java.io.InputStreamReader isr_memo = new java.io.InputStreamReader((InputStream)bais_memo,"GBK");

try{
stmt = con.createStatement();
stmt.getConnection().setAutoCommit(false);

pstmt = con.prepareStatement(sql_cn);
pstmt.setCharacterStream(1, isr_name, fileName.length());
pstmt.setCharacterStream(2, isr_memo, fileMemo.length());
pstmt.setInt(3, dinfo_upload_id);

//System.out.println(sql_cn);

pstmt.execute();
stmt.executeUpdate("COMMIT");

}catch(Exception exce){
System.out.println(exce);
stmt.executeUpdate("ROLLBACK");
}
}
}
}catch(Exception e){
}


以上是jspsmart的方式,若是想要其它的方式,请下载所有源代码.



//upload_fileUpload.jsp

<%@ include file = "../../backgeneral.jsp"%>
<%@ contentType="text/html;charset=GBK" %>
<jsp:useBean id="userInfo" scope="session" class="com.ges.hbgov.UserInfo"/>
<%@ page import="org.apache.commons.fileupload.*" %>
<%
try{
 //request.setCharacterEncoding("GBK");
//取session 用户oid
    int pid = userInfo.getUserId();
    String sys_user_id = String.valueOf(pid);
//取init配置文件的参数值
 String sitePhysicalPath = (String)init.getObject("SitePhysicalPath");
 String saveDir  = (String)init.getObject("InfoUploadDir");
 String tempDir  = (String)init.getObject("InfoUploadDir");
 String fileMemo = "";    //文件说明
 String fileName = null;  //存储到数据库的文件名
 String saveName = null;  //存储到本地的文件名
 String filePath = null;  //存储到本地的文件路径
 String savePath = null;  //存储到数据库的文件路径
 long   fileSize = 0;     //文件大小
 int maxPostSize = -1;    
 int dinfo_upload_id = -1;
%>
<%
    DiskFileUpload df = new DiskFileUpload();
    //设定上传文件大小
 df.setSizeMax(maxPostSize);
 //设定临时目录
 df.setRepositoryPath(sitePhysicalPath + tempDir);
    //取得request信息
 List items = df.parseRequest(request);
    
 Iterator iter = items.iterator();
    
 int temp = 0;
 FileItem tempItem = null;

 while(iter.hasNext()){
  temp++;
  FileItem item = (FileItem)iter.next();
  if(item.isFormField())    //取得文件说明信息
  {
   fileMemo = item.getString("GBK");
   
  }
  else
  {   //取得上传文件信息
   fileName = (String)item.getName();
   try{
    fileName = fileName.substring(fileName.lastIndexOf("//")+1);
    fileName = fileName.substring(fileName.lastIndexOf("/")+1);
   }catch(Exception e){
    System.out.println(e);
   }
   fileSize = item.getSize();
   tempItem = item;
  }

  if(temp == 2 && fileSize != 0)
   {    //每两个iter存储一个上传文件

             //获得info_title_id
              String SQL_ID="select S_INFO_UPLOAD.nextval as seqid from dual";
           try {
                java.sql.Statement stmt = con.createStatement();
                java.sql.ResultSet rst= stmt.executeQuery(SQL_ID);
                while(rst.next()) 
       {
                       dinfo_upload_id = rst.getInt("seqid");
                }

             }catch(SQLException e1){
                    return;
             }
            //取得文件扩展名
            try{
    saveName = fileName.substring(fileName.lastIndexOf("."));
   }catch(Exception exc){
    saveName = "";
   }

            filePath = sitePhysicalPath + saveDir + Integer.toString(dinfo_upload_id) + saveName;
            //存储文件
   java.io.File uploadFile = new java.io.File(filePath);
   tempItem.write(uploadFile);
   /*try{
       FileOutputStream fos = new FileOutputStream(filePath);
       InputStream is = tempItem.getInputStream();
       byte[] b = new byte[1024];
       int nRead;
       long per = 0;
       double percent = 0;
                while((nRead = is.read(b, 0, 1024))>0){
        fos.write(b, 0, nRead);
        per += nRead;
        percent = (double)per/fileSize;

        session.setAttribute("percent",Double.toString(percent).substring(2,4));
        session.setAttribute("filename",fileName);
                }
       is.close();
    fos.close();    
    }catch(Exception e){
     System.out.println(e);
    }*/
            savePath = saveDir + Integer.toString(dinfo_upload_id) + saveName;
            /*/存储数据库
            String sql = " INSERT INTO info_upload (info_upload_id,sys_user_id,file_name,file_memo,file_size,file_path,utime,deleted) "
              + " VALUES( " + Integer.toString(dinfo_upload_id) + "," + sys_user_id + ",'" + fileName + "','" + fileMemo + "'," + fileSize + ",'" + savePath + "', SYSDATE , 0 )" ;
   sqlcmd cmd = new sqlcmd(con,sql);
   */
            String sql = " INSERT INTO info_upload (info_upload_id,sys_user_id,file_size,file_path,utime,deleted) "
              + " VALUES( " + Integer.toString(dinfo_upload_id) + "," + sys_user_id + "," + fileSize + ",'" + savePath + "', SYSDATE , 0 )" ;
   sqlcmd cmd = new sqlcmd(con,sql);
            //System.out.println(sql);
   java.sql.PreparedStatement pstmt = null;
   java.sql.Statement stmt = null;
   //fileName = fileName.substring(0, fileName.indexOf("."));
   String sql_cn = " UPDATE info_upload SET file_name=?,file_memo=? WHERE info_upload_id=? ";
   
   java.io.ByteArrayInputStream bais_name = new java.io.ByteArrayInputStream(fileName.getBytes("ISO-8859-1"));
   java.io.InputStreamReader isr_name = new java.io.InputStreamReader((InputStream)bais_name,"GBK");

   java.io.ByteArrayInputStream bais_memo = new java.io.ByteArrayInputStream(fileMemo.getBytes("GBK"));
   java.io.InputStreamReader isr_memo = new java.io.InputStreamReader((InputStream)bais_memo,"GBK");
   
   try{
    stmt = con.createStatement();
    stmt.getConnection().setAutoCommit(false);

    pstmt = con.prepareStatement(sql_cn);
    pstmt.setCharacterStream(1, isr_name, fileName.length());
    pstmt.setCharacterStream(2, isr_memo, fileMemo.length());
    pstmt.setInt(3, dinfo_upload_id);

                //System.out.println(sql_cn);

    pstmt.execute();
    stmt.executeUpdate("COMMIT");

   }catch(Exception exce){
    System.out.println(exce);
    stmt.executeUpdate("ROLLBACK");
   }

   temp = 0;
  }
  else if (temp == 2 && fileSize == 0) {temp = 0;}

 }
    //session.setAttribute("percent","ok");
}catch(Exception ex){
 System.out.println(ex);
}
response.sendRedirect("list.jsp");

%>




//upload_jspSmart.jsp

<%@ include file = "../../backgeneral.jsp"%>
<%@ page language="java" import="java.util.*,java.sql.*,java.io.*"%>
<%@ page language="java" import="com.jspsmart.upload.*"%>
<%@ page language="java" import="com.ges.hbgov.*"%>
<jsp:useBean id="userInfo" scope="session" class="com.ges.hbgov.UserInfo"/>
<jsp:useBean id="mySmartUpload" scope="page" class="com.jspsmart.upload.SmartUpload" />
<%
//System.out.println("page=" + (String)session.getAttribute("SYS_USER_ID"));
if(!userInfo.Request(request)){
%>
<script language=javascript>
 function relogin() {
  this.parent.location.href="../../login.jsp";
 }
 relogin();
</script>
<%
}
%>

<%

try{
//取session 用户oid
    int pid = userInfo.getUserId();
    String sys_user_id = String.valueOf(pid);
//取init配置文件的参数值
 String sitePhysicalPath = (String)init.getObject("SitePhysicalPath");
 String saveDir  = (String)init.getObject("InfoUploadDir");
 String tempDir  = (String)init.getObject("InfoUploadDir");
 String fileMemo = "";    //文件说明
 String fileName = null;  //存储到数据库的文件名
 String saveName = null;  //存储到本地的文件名
 String filePath = null;  //存储到数据库的文件路径
 String savePath = null;  //存储到本地的文件路径
 long   fileSize = 0;     //文件大小
 int maxPostSize = -1;    
 int dinfo_upload_id = -1;
%>
<%
 //初始化
 mySmartUpload.initialize(pageContext);
 //上载文件
    mySmartUpload.upload();
 //循环取得全部上载文件
    for(int i=0; i<mySmartUpload.getFiles().getCount(); i++)
 {
  //取得上载文件
  com.jspsmart.upload.File file = mySmartUpload.getFiles().getFile(i);
  if(!file.isMissing())
  {
   fileName = file.getFileName();
   //取得文件扩展名file.getFileExt()
   try{
    saveName = fileName.substring(fileName.lastIndexOf("."));

   }catch(Exception e){
    saveName = "";
   }
   //取得文件大小
   fileSize = file.getSize();
   //存储路径
   String sql_id = " SELECT S_INFO_UPLOAD.nextval as seqid FROM dual ";
   try{
    Statement stmt = con.createStatement();
    ResultSet rst = stmt.executeQuery(sql_id);
    while(rst.next())
    {
     dinfo_upload_id = rst.getInt("seqid");
    }
   }catch(SQLException sqle){
    return;
   }

   filePath = sitePhysicalPath + saveDir + Integer.toString(dinfo_upload_id) + saveName;
   savePath = saveDir + Integer.toString(dinfo_upload_id) + saveName;
   //存储文件到本地
   file.saveAs(filePath);
   //存储文件到数据库
   switch(i)
   {
    case 0: fileMemo = (String)mySmartUpload.getRequest().getParameter("memo1"); break;
    case 1: fileMemo = (String)mySmartUpload.getRequest().getParameter("memo2"); break;
                case 2: fileMemo = (String)mySmartUpload.getRequest().getParameter("memo3"); break;
    case 3: fileMemo = (String)mySmartUpload.getRequest().getParameter("memo4"); break;
    case 4: fileMemo = (String)mySmartUpload.getRequest().getParameter("memo5"); break;
    default: fileMemo = "";
   }

            String sql = " INSERT INTO info_upload (info_upload_id,sys_user_id,file_size,file_path,utime,deleted) "
              + " VALUES( " + Integer.toString(dinfo_upload_id) + "," + sys_user_id + "," + fileSize + ",'" + savePath + "', SYSDATE , 0 )" ;
   sqlcmd cmd = new sqlcmd(con,sql);
            //System.out.println(sql);
   java.sql.PreparedStatement pstmt = null;
   java.sql.Statement stmt = null;
   //fileName = fileName.substring(0, fileName.indexOf("."));
   String sql_cn = " UPDATE info_upload SET file_name=?,file_memo=? WHERE info_upload_id=? ";
   java.io.ByteArrayInputStream bais_name = new java.io.ByteArrayInputStream(fileName.getBytes("ISO-8859-1"));
   java.io.InputStreamReader isr_name = new java.io.InputStreamReader((InputStream)bais_name,"GBK");

   java.io.ByteArrayInputStream bais_memo = new java.io.ByteArrayInputStream(fileMemo.getBytes("GBK"));
   java.io.InputStreamReader isr_memo = new java.io.InputStreamReader((InputStream)bais_memo,"GBK");
   
   try{
    stmt = con.createStatement();
    stmt.getConnection().setAutoCommit(false);

    pstmt = con.prepareStatement(sql_cn);
    pstmt.setCharacterStream(1, isr_name, fileName.length());
    pstmt.setCharacterStream(2, isr_memo, fileMemo.length());
    pstmt.setInt(3, dinfo_upload_id);

                //System.out.println(sql_cn);

    pstmt.execute();
    stmt.executeUpdate("COMMIT");

   }catch(Exception exce){
    System.out.println(exce);
    stmt.executeUpdate("ROLLBACK");
   }
  }
 }
}catch(Exception e){
}

response.sendRedirect("list.jsp");
%>

 

java处理xml方法

最初,XML 语言仅仅是意图用来做为 HTML 语言的替代品而出现的,可是随着该语言的不断发展和完善,人们愈来愈发现它所具备的优势:例如标记语言可扩展,严格的语法规定,可以使用有意义的标记,内容 存储和表现分离等等优点注定了该语言从诞生之日起就会走向辉煌。 XML 语言在成为 W3C 标准以后进入到了一个快速发展的时期,固然它自己所具备的一系列优势和优点也注定了各大技术厂商对它的偏心,Java 做为软件行业的一种开发技术也迅速做出了反应,出现了多种对 XML 支持的工具,本文将会从这个角度对 Java 处理 XML 的几种主流技术进行介绍,但愿能对您有所帮助。在这篇文章中,您将会获得如下信息:
  1. Java 提供了哪些优秀的类库及工具便于程序员对 XML 进行处理 ?
  2. 有了 DOM 了,其它工具类库还有必要么 ?
  3. 几个小例程带你快速了解这三种解析方式

  Java 有哪些优秀的类库及工具便于程序员对 XML 进行处理 ?

  • 大名鼎鼎的 DOM
  • 绿色环保的 SAX
  • 默默无闻的 Digester

  XML 三种解析方式简介

  大名鼎鼎的 DOM

  说它大名鼎鼎但是一点不为过,DOM 是 W3C 处理 XML 的标准 API,它是许多其它与 XML 处理相关的标准的基础,不只是 Java,其它诸如 Javascript,PHP,MS .NET 等等语言都实现了该标准, 成为了应用最为普遍的 XML 处理方式。固然,为了能提供更多更增强大的功能,Java 对于 DOM 直接扩展工具类有不少,好比不少 Java 程序员耳熟能详的 JDOM,DOM4J 等等, 它们基本上属于对 DOM 接口功能的扩充,保留了不少 DOM API 的特性,许多本来的 DOM 程序员甚至都没有任何障碍就熟练掌握了另外二者的使用,直观、易于操做的方式使它深受广大 Java 程序员的喜好。

  绿色环保的 SAX

  SAX 的应运而生有它特殊的须要,为何说它绿色环保呢,这是由于 SAX 使用了最少的系统资源和最快速的解析方式对 XML 处理提供了支持。 但随之而来繁琐的查找方式也给广大程序员带来许多困扰,经常使人头痛不已,同时它对 XPath 查询功能的支持,使人们对它又爱又恨。

  默默无闻的 Digester:XML 的 JavaBean 化

  Digester 是 apache 基金组织下的一个开源项目,笔者对它的了解源于对 Struts 框架的研究,是否有不少程序员想要一解各大开源框架的设计甚至想要本身写一个功能强大的框架时会碰到这样一个难题: 这些形形色色的用 XML 语言标记的框架配置文件,框架底层是用什么技术来解析呢? DOM 解析耗费时间,SAX 解析又过于繁琐,何况每次解析系统开销也会过大, 因而,你们想到须要用与 XML 结构相对应的 JavaBean 来装载这些信息,由此 Digester 应运而生。它的出现为 XML 转换为 JavaBean 对象的需求带来了方便的操做接口,使得更多的相似需求获得了比较完美的解决方法, 再也不须要程序员本身实现此类繁琐的解析程序了。与此同时 SUN 也推出了 XML 和 JavaBean 转换工具类 JAXB,有兴趣的读者能够自行了解。

  三种解析方式比较

  DOM

  优缺点:实现 W3C 标准,有多种编程语言支持这种解析方式,而且这种方法自己操做上简单快捷,十分易于初学者掌握。其处理方式是将 XML 整个做为相似树结构的方式读入内存中以便操做及解析,所以支持应用程序对 XML 数据的内容和结构进行修改,可是同时因为其须要在处理开始时将整个 XML 文件读入到内存中去进行分析,所以其在解析大数据量的 XML 文件时会遇到相似于内存泄露以及程序崩溃的风险,请对这点多加注意。

  适用范围:小型 XML 文件解析、须要全解析或者大部分解析 XML、须要修改 XML 树内容以生成本身的对象模型

  SAX

  SAX 从根本上解决了 DOM 在解析 XML 文档时产生的占用大量资源的问题。其实现是经过相似于流解析的技术,通读整个 XML 文档树,经过事件处理器来响应程序员对于 XML 数据解析的需求。因为其不须要将整个 XML 文档读入内存当中,它对系统资源的节省是十分显而易见的,它在一些须要处理大型 XML 文档以及性能要求较高的场合有起了十分重要的做用。支持 XPath 查询的 SAX 使得开发人员更加灵活,处理起 XML 来更加的驾轻就熟。可是同时,其仍然有一些不足之处也困扰广大的开发人员:首先是它十分复杂的 API 接口使人望而生畏,其次因为其是属于相似流解析的文件扫描方式,所以不支持应用程序对于 XML 树内容结构等的修改,可能会有不便之处。

  适用范围:大型 XML 文件解析、只须要部分解析或者只想取得部分 XML 树内容、有 XPath 查询需求、有本身生成特定 XML 树对象模型的需求

  Digester/JAXB

  优缺点 : 因为其是在上述二者的基础上衍生出来的工具类,为的是知足将 XML 转换为 JavaBean 的特殊需求,故而没有什么特别明显的优缺点。做为大名鼎鼎的开源框架 Struts 的 XML 解析工具 Digester,为咱们带来了将 XML 转换为 JavaBean 的可靠方法。

  适用范围 : 有将 XML 文档直接转换为 JavaBean 需求。

  应用示例

  下面给出一段用于解析的 XML 片断:
  清单 1. XML 片断

 <?xml version="1.0" encoding="UTF-8"?>   <books>     <book id="001">        <title>Harry Potter</title>        <author>J K. Rowling</author>     </book>     <book id="002">        <title>Learning XML</title>        <author>Erik T. Ray</author>     </book>   </books> 

  DOM 解析 XML

  Java 中的 DOM 接口简介: JDK 中的 DOM API 遵循 W3C DOM 规范,其中 org.w3c.dom 包提供了 Document、DocumentType、Node、NodeList、Element 等接口,这些接口均是访问 DOM 文档所必须的。咱们能够利用这些接口建立、遍历、修改 DOM 文档。

  javax.xml.parsers 包中的 DoumentBuilder 和 DocumentBuilderFactory 用于解析 XML 文档生成对应的 DOM Document 对象。

  javax.xml.transform.dom 和 javax.xml.transform.stream 包中 DOMSource 类和 StreamSource 类,用于将更新后的 DOM 文档写入 XML 文件。

  下面给出一个运用 DOM 解析 XML 的例子:
  清单 2. DOM 解析 XML

 import java.io.File;   import java.io.IOException;   import javax.xml.parsers.DocumentBuilder;   import javax.xml.parsers.DocumentBuilderFactory;   import javax.xml.parsers.ParserConfigurationException;   import org.w3c.dom.Document;   import org.w3c.dom.Element;   import org.w3c.dom.Node;   import org.w3c.dom.NodeList;   import org.xml.sax.SAXException;   public class DOMParser {     DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();     //Load and parse XML file into DOM     public Document parse(String filePath) {        Document document = null;        try {           //DOM parser instance           DocumentBuilder builder = builderFactory.newDocumentBuilder();           //parse an XML file into a DOM tree           document = builder.parse(new File(filePath));        } catch (ParserConfigurationException e) {           e.printStackTrace();         } catch (SAXException e) {           e.printStackTrace();        } catch (IOException e) {           e.printStackTrace();        }        return document;     }     public static void main(String[] args) {           DOMParser parser = new DOMParser();           Document document = parser.parse("books.xml");           //get root element           Element rootElement = document.getDocumentElement();           //traverse child elements           NodeList nodes = rootElement.getChildNodes();           for (int i=0; i < nodes.getLength(); i++)           {              Node node = nodes.item(i);              if (node.getNodeType() == Node.ELEMENT_NODE) {                   Element child = (Element) node;                 //process child element              }           }           NodeList nodeList = rootElement.getElementsByTagName("book");           if(nodeList != null)           {              for (int i = 0 ; i < nodeList.getLength(); i++)              {                 Element element = (Element)nodeList.item(i);                 String id = element.getAttribute("id");              }           }     }   } 

  在上面的例子中,DOMParser 的 Parse() 方法负责解析 XML 文件并生成对应的 DOM Document 对象。其中 DocumentBuilderFactory 用于生成 DOM 文档解析器以便解析 XML 文档。 在获取了 XML 文件对应的 Document 对象以后,咱们能够调用一系列的 API 方便的对文档对象模型中的元素进行访问和处理。 须要注意的是调用 Element 对象的 getChildNodes() 方法时将返回其下全部的子节点,其中包括空白节点,所以须要在处理子 Element 以前对节点类型加以判断。

  能够看出 DOM 解析 XML 易于开发,只须要经过解析器创建起 XML 对应的 DOM 树型结构后即可以方便的使用 API 对节点进行访问和处理,支持节点的删除和修改等。 可是 DOM 解析 XML 文件时会将整个 XML 文件的内容解析成树型结构存放在内存中,所以不适合用 DOM 解析很大的 XML 文件。

  SAX 解析 XML

  与 DOM 创建树形结构的方式不一样,SAX 采用事件模型来解析 XML 文档,是解析 XML 文档的一种更快速、更轻量的方法。 利用 SAX 能够对 XML 文档进行有选择的解析和访问,而没必要像 DOM 那样加载整个文档,所以它对内存的要求较低。 但 SAX 对 XML 文档的解析为一次性读取,不建立任何文档对象,很难同时访问文档中的多处数据。

  下面是一个 SAX 解析 XML 的例子:
  清单 3. SAX 解析 XML

 import org.xml.sax.Attributes;   import org.xml.sax.SAXException;   import org.xml.sax.XMLReader;   import org.xml.sax.helpers.DefaultHandler;   import org.xml.sax.helpers.XMLReaderFactory;   public class SAXParser {     class BookHandler extends DefaultHandler {        private List<String> nameList;        private boolean title = false;        public List<String> getNameList() {           return nameList;        }        // Called at start of an XML document        @Override        public void startDocument() throws SAXException {           System.out.println("Start parsing document...");           nameList = new ArrayList<String>();        }        // Called at end of an XML document        @Override        public void endDocument() throws SAXException {            System.out.println("End");         }        /**         * Start processing of an element.         * @param namespaceURI  Namespace URI         * @param localName  The local name, without prefix         * @param qName  The qualified name, with prefix         * @param atts  The attributes of the element         */        @Override        public void startElement(String uri, String localName, String qName,           Attributes atts) throws SAXException {           // Using qualified name because we are not using xmlns prefixes here.           if (qName.equals("title")) {              title = true;           }        }        @Override        public void endElement(String namespaceURI, String localName, String qName)           throws SAXException {           // End of processing current element           if (title) {              title = false;           }        }        @Override        public void characters(char[] ch, int start, int length) {           // Processing character data inside an element           if (title) {              String bookTitle = new String(ch, start, length);              System.out.println("Book title: " + bookTitle);              nameList.add(bookTitle);           }        }     }     public static void main(String[] args) throws SAXException, IOException {        XMLReader parser = XMLReaderFactory.createXMLReader();        BookHandler bookHandler = (new SAXParser()).new BookHandler();        parser.setContentHandler(bookHandler);        parser.parse("books.xml");        System.out.println(bookHandler.getNameList());     }   } 

  SAX 解析器接口和事件处理器接口定义在 org.xml.sax 包中。主要的接口包括 ContentHandler、DTDHandler、EntityResolver 及 ErrorHandler。 其中 ContentHandler 是主要的处理器接口,用于处理基本的文档解析事件;DTDHandler 和 EntityResolver 接口用于处理与 DTD 验证和实体解析相关的事件; ErrorHandler 是基本的错误处理接口。DefaultHandler 类实现了上述四个事件处理接口。上面的例子中 BookHandler 继承了 DefaultHandler 类, 并覆盖了其中的五个回调方法 startDocument()、endDocument()、startElement()、endElement() 及 characters() 以加入本身的事件处理逻辑。

  Digester 解析 XML

  为了知足将 XML 转换为 JavaBean 的特殊需求,Apache 旗下的一个名为 Digester 的工具为咱们提供了这么一个选择。因为最终是将 XML 转化为 JavaBean 存储在内存当中, 故而解析性能等方面其实与使用者并无多大关系。解析的关键在于用以匹配 XML 的模式以及规则等,因为该工具较为复杂,限于篇幅,做者只能给予简单的介绍。

  下面是一个 Digester 解析 XML 的例子片断:
  清单 4. Digester 解析 XML

 // 定义要解析的 XML 的路径,并初始化工具类  File input = new File("books.xml");   Digester digester = new Digester();   // 若是碰到了 <books> 这个标签,应该初始化 test.myBean.Books 这个 JavaBean 并填装相关内容  digester.addObjectCreate("books", "test.myBean.Books");   digester.addSetProperties("books");   // 若是碰到了 <books/book> 这个标签,同上初始化 test.myBean.Book 这个 JavaBean   digester.addObjectCreate("books/book", "test.myBean.Book");   digester.addSetProperties("books/book");   // 经过调用上面已经初始化过的 JavaBean 的 addBook() 方法来把多个 <books/book> 加到一个集合中  digester.addSetNext("books/book", "addBook", "test.myBean.Book");   // 定义好了上面的解析规则后,就能够开始进行解析工做了  Books books = (Books) digester.parse(input); 

  上述代码简单的向读者展现了 Digester 处理 XML 的一些要点,主要是说明了一些模式以及规则的匹配。 简言之,Digester 就是一种用来把一个 XML 转化为一个与该 XML 结构相似的 JavaBean。你能够把 XML 根元素想象成一个 JavaBean, 该根元素的 attribute 就是这个 JavaBean 的各类 Field,当该根元素有其余子 tag 时,又要把这个子 tag 想象成一个个新的 XML,将其视为一个新的 JavaBean, 并做为一个 Field 加入到父 Bean 当中,而后以此类推,经过循环的方式将整个 XML 进行解析。

  结束语

  本文介绍了 Java 解析 XML 的三种经常使用技术,其中 DOM 易于上手,程序易于理解,但缺点在于占用内存大,不适合于解析较大的 XML 文件; SAX 基于事件模型占用系统资源少,可以胜任较大的 XML 文件解析,但解析过程较为繁琐查找元素不方便; Digester/JAXB 基于上述两种技术衍生而来。文中的实例向读者展现了三种 API 的基本使用方法, 在实际开发过程当中使用那种技术解析 XML 更好要依据各自的优缺点视具体状况而定。

 

前段开发10点

 第一日:初尝禁果

  【上帝说:“要有光!”便有了光】

  万物生灵、阳光雨露盖源于造物之初的天工开物,咱们没法想象上帝创造光明以前的世界模样。但幸运的是,前端开发没有神祗般的诡魅。这个技术工种 的孕育、定型、发展自有轨迹,也很有渊源,固然,这很是容易理解。不严格的讲,在杨致远和费罗在斯坦福大学的机房里撺掇出Yahoo!时,Web前端技术 就已经开始进入公众视野,只不过当时没有一个响亮的名字。从那时起,“基于浏览器端的开发”就成了软件开发的新的分支,这也是Web前端技术的核心,即不 论什么时候何地何种系统以及怎样的设备,但凡基于浏览器,都是Web前端开发的范畴(固然,这个定义很狭隘,下文会提到)。

  在2000年以后浏览器技术渐渐成熟,Web产品也愈来愈丰富,中国有大批年轻人开始接触互联网,有一点须要注意,大部分人接触互联网不是始于 对浏览器功能的好奇,而是被浏览器窗口内的丰富内容所吸引,咱们的思惟模式从一开始就被限制在一个小窗口以内,以致于很长时间内咱们将“视觉”认为是一种 “功能”,Web产品无非是用来展示信息之用。起初的入行者无一例外对“视觉”的关注超过了对“内容”的重视,先让页面看起来漂亮,去关注 html/css,沿着“视觉呈现”的思路,继续深刻下去。所以,这类人是被“视觉”所吸引,从切页面入行,着迷于结构化的html和书写工整的css, 喜欢简洁优雅的UI和工整的页面设计,以后开始接触视觉特效,并使用jQuery来实现视觉特效,以此为线索,开始深刻研究Dom、Bom和浏览器的渲染 机制等,html/css在这些人手中就像进攻兵器,而JavaScript则更如防守的盾牌。

  还有另一群人从另外一条道路接触Web前端,即工程师转行作前端,他们有较多的后台语言开发背景,从读写数据开始,渐渐触及浏览器端,接触 JavaScript库,起初是在html代码上加js逻辑,后来开始涉及html和css,他们喜欢OO、逻辑清晰、结构悦目的代码,更关注界面背后的 “程序语言”和数据逻辑。html/css在这些人手中则更像盾牌,而JavaScript更如进攻的兵器。

  应当说这两类人是互补的,他们各自了解浏览器本质的一部分,一拨人对渲染引擎了如指掌,另外一拨人则将JS引擎奉为至宝,其实任何一部分的优点发 挥出来都能作出精品。大部分前端工程师都能从这两条渊源中找到本身的影子。但,这两类人的思惟模式和观点是如此不一样,以致于造成了一些没必要要的对抗,好比 在某些公司,干脆将Web前端技术一分为二,“切页面的”和“写js的”。这样作看上去明确了分工提升了效率,但他对员工的职业发展带来巨大伤害。在第二 日“科班秀才”中会有进一步讨论。

  我应该属于第二类,即在学校订儿八经的学习C/Java和C#之类,觉得大学毕业后能去作ERP软件、桌面软件或者进某些通讯公司写TCP /IP相关的程序。校园招聘时选择了中国雅虎,由于当年(08年)雅虎仍是有一点儿名气,并且我据说雅虎比较算技术流的公司……自此就上了贼船,一发不可 收拾。

  在雅虎的这段时间,我有幸接触到一股正气凛然的技术流派,也造成了我对前端技术的一些基本见解,这些基本观点一直影响我至今。

  【优雅的学院派】

  当年雅虎的技术流派正如日中天,拥有众多“之父”级的高人,所营造出的Hack氛围实在让人陶醉的没法自拔,那段时间我甚至宁愿加班到深夜阅读 海量的文档和源代码,感受真的很舒服,我深深的被雅虎工程师这种低调务实、精工细琢的“服务精神”所打动,而这种不起眼的优秀品质很大程度的影响雅虎产品 的用户体验和高质量的技术输出。那么,何谓“服务精神”?即你所作的东西是服务于人的,要么是产品客户、要么是接手你项目的人、要么是使用你开发的功能的 人,因此技术文档成为伴随代码的标配。所以,工程师之间经过代码就能作到心有灵犀的沟通。这是工程师的一项基本素质,即,思路清晰的完成项目,且配备了有 价值的技术文档,若是你的程序是给其余程序员用的,则更要如此,就比如你制造一款家电都要配备说明书同样。所以,YDN成了当时最受全球程序员最喜好的技 术文档库,这种优雅务实的“学院气息”让人感受独具魅力。

  让人感受奇怪的是,在中文社区始终未见这种学院派。甚至在具备先天开源优点的Web前端技术社区里也是波澜不惊,可见写一篇好的技术文案真的比 登天还难。我所见到的大部分所谓文档索性把代码里输出数据的语句块拷贝粘贴出来,至于为何数据格式要设计成这样、若是字段有修改怎么作、编码解码要求如 何等等关键信息只字不提,或者开发者也没想过这些问题呢。所以,咱们一直在强调代码的质量和可维护性,但一直以来都未见效,盖源于缺乏这种“服务”意识的 灌输。这种意识在下文中还会屡次提到,由于它能影响你作事的每一个细节,是最应当首先突破的思想纠结。

  除了意识问题,另外一方面是技术问题,即文笔。这也是工程师最瞧不上眼的问题,难以置信这居然是阻碍工程师突破瓶颈的关键所在。我已看到过数不清 的人在晋升这道关卡吃了大亏,不少工程师技术实力很强,但就是表达不出来,要么罗列一大堆信息毫无重点、要么毫无趣味的讲代码细节,不知云云。除非你走狗 屎运碰到一个懂技术的老板,不然真的没办法逃脱码农的宿命。但大部分人还振振有词不觉得然。而在Web前端开发领域状况更甚。前端工程师是最喜欢搞重构 的,但在快节奏的需求面前,你很难用“提升了可维护性”、“提高了性能”这类虚无缥缈的词藻为本身争取到时间来搞重构,说的露骨一点,可能你真的对某次重 构带来的实际价值没法量化,只是“感受代码更整洁了”而已。我会在下文的“伪架构”中会展开分析前端工程师的这种浮躁献媚的技术情结。而这正是前端工程师 最欠缺的素质之一:用数听说话,用严谨科学的论据来支撑你的观点,老板不傻,有价值的东西固然会让你去作。

  固然,状况不老是这么糟糕,咱们看到中文社区中已经锻炼出了不少写手,他们在用高质量的文字推销本身的技术理念,这是一个好兆头,好的文笔是可 以锻炼出来的。而在职场,特别是对前端工程师这个特殊职位来说,这种基本技能能够帮你反思梳理需求的轻重缓急,从凌乱的需求中把握七寸所在。由于当你开始 认真写一封邮件的时候,这种思考已经包含其中了。

  因此,雅虎技术的推销是相对成功和远播的。关键在于两方面,扎实的技术功底和高超的写手。而真正的技术大牛必定是集二者与一身,不只钻研剑道,还能产出秘籍。这也是Yahoo!优雅的学院派气息的动力源泉。国内不少技术团体想在这方面有所建树,应当首先想清楚这一点。

  【规范的破与立 1】

  雅虎的技术运做很是规范,刚才已经提到,包括技术、组织、文化,一切看起来有模有样,也堪称标杆,天然成了国内不少技术团队和社区的效仿对象。一时间各类“规范“成风、各色“标准“大行其道,结果是质量良莠不齐。

  咱们到底须要什么样的规范?雅虎的技术规范到底有何种魔力?以何种思路构建的规范才是货真价实的?规范有着怎样的生命周期?想清楚这些问题,能很大程度减轻不少Web前端工程师的思想负担,看清一部分技术本质,避免盲目跟风。

  咱们的确须要规范,但好的规范必定是务实的,必定是“解决问题“的。好比针对项目构建的DPL能够收纳公用的视觉元件以减小重复开发、规定某 OPOA项目的事件分发原则以确立增量开发的代码惯性。反之,糟糕的规范却显得过于“抽象“,好比页面性能指标、响应式设计原则。另外,尽管他山之石能够 攻玉,但拿来主义有一个大前提,就是你了解你的项目的关键问题,你要优先解决的是些关键问题,而外来规范正好能解决你的问题。所以规范是一本案头手册,是 一揽子问题的解决方案,应当是“字典”,而不是“教程“。可见规范的源头是“问题”。因此,当你想用CoffeeScript重构你的项目时、当你想引入 CommonJS规范时、当你想在页面中揉进Bootstrap时、当你打算重复造轮子搞一套JS库时、当你想重写一套assets打包工具时,想一想这些 东东解决了你的什么问题?会不会带来新的问题、把事情搞复杂了?仍是为了尝鲜?或者为了在简历中冠冕堂皇的写上使用并精通各类新技术?

  规范之立应当有动因,动因来源于项目需求,项目需求则来自对产品的理解和把握,这是Web前端初级工程师走向中级甚至高级的一次重要蜕变,软件 工程领域早就有“架构师”角色,而架构师每每存在于项目需求分析和概设、详设阶段。我看到的状况是,Web前端工程师的思惟过多的限制在“界面”以内,向 前和产品需求离的太远(认为这是视觉设计师的事)、向后和数据逻辑又隔离开来(认为这是后台工程师该干的事),所以前端规范也大都泛泛,无关项目痛痒,成 了玩具。

  雅虎技术规范的优秀之初在于它们解决问题。因此,学习使用规范应当多问一句,“他们为何这样作?”其实,想清楚这些问题时,脑海中天然造成了一种“遇山开山”的创造性思惟。

  【规范的破与立 2】

  若是说新技术的尝鲜缺乏针对性,但至少知足程序员的某种洁癖和快感,那么“负担”从何而来呢?对于初学者来讲,有价值学习资料可能只有这些规范,若是说规范价值不大,那又当从何入手呢?

  刚才我说的不是依赖于规范,而是对规范的反思,摆脱规范灌输给咱们的思惟定势。新人们大概是看了Wiki中的不少指标、结论、实践,在作项目之 初就附加了很多“八股式”的负担,甚至影响咱们对项目关键需求和关键问题的洞察力和判断力,负担太重就没法轻装上阵,Wiki中提到的这些指标和规范是结 论性的,是大量的实践以后得出的,也只有经历过大量实践才会真正理解这些结论,好比DomReady时间和http请求数是否有因果关系,http请求数 增长是否真的会致使页面性能降低,什么条件下会致使性能降低?咱们从那些条文和结论中没法找到答案。

  举个具体的例子,Kissy刚刚出了DPL,也是一大堆结论,好比他的布局就采用了经典的双飞翼,使用容器浮动来实现,那么,这种作法就是不可 撼动的“标准”吗?看看淘宝车险首页,布局容器齐刷刷的inline-block,只要顶层容器去掉宽度,布局容器自身就能根据浏览器宽度调整天然水平/ 垂直排列,轻易的适应终端宽度了。

  再好比,淘宝旅行计划项目中的部署方式,也没有彻底使用Loader管理依赖,而是将依赖层级作的不多,业务逻辑使用脚原本合并,这样就能够更容易在build环节加入语法检查和代码风格检查。

  相似这种摆脱原有编程思惟,有针对性的用新思路新方法解决问题的作法显然让人感受更加清爽,编程的乐趣也正体如今打破常规的快感之中,小马曾经 说过:“制造规范是为了打破规范”,万不要由于这些规范标准加剧负担,致使开始作一个简单页面时也显得缩手缩脚,没法放开身手。大胆的动手实践,才能真正 得出属于本身的“结论 “和“标准“,才会真正深入理解那些“结论”的意义所在。代码写的多了,天然熟能生巧,也容易造成成熟的技术观点。

  在这个过程当中,咱们惟一的对手是懒惰,惰于思考,就没法真正发现问题,天然形不成本身的观点。仍是那句话,任何规范、方法、结论、实践都是为了 解决项目中的问题的,因此,咱们所接触到那些看似“八股文”式的规范标准也是为了解决某些问题而提出的,想清楚这些问题,理解方法论背后的“因“,心里自 然有“果”。

  所以,“着眼当下、对症下药”的品质就显得弥足珍贵了,好比,双飞翼布局方法是为了解决一套(html)代码适应多种布局设计,这里的布局相对 于固定的产品来讲也是固定的,而无针对终端的自适应(适用于移动端的榻榻米布局彷佛尚未最佳实践)。这是双飞翼产生的背景,现在终端环境较之5年前已经 翻天覆地,问题早已不在“多种布局”上,而在“终端适应“上,这才是咱们面临的问题,须要咱们给出新的技术方案。

  因此,勤于思考,轻装上阵,大胆实践,敢于创新,发掘问题所在,实打实的解决(潜在)问题,这才是咱们真正须要的能力。放下思惟定势枷锁,也会有一种豁然开朗的感受。

  第二日:科班秀才

  【秀才仕途】

  Web前端工程师是一个特别的岗位,只存在于互联网领域。最近几年随着互联网产业的火爆,对前端工程师的需求量暴增,兵源几近枯竭。各大公司技术掌门必定都有过相似的苦恼:“招一个靠谱的前端工程师、难于上青天”。

  我想,一部分缘由是,当前很多入道的前端工程师大都是转行而来,毕竟,正儿八经的学校里也不会教这玩意,以为“切页面”有啥好教的,甚至不以为 html/css是一门语言。转行这事自没必要详说,你们也各自瞄准当前市场需求,形成的现象是,初级前端工程师堆成山,中高级人才却一将难求,计算机系的 科班出身就更加百里挑一了。一方面反映了教育部门的后知后觉,另外一方面也体现了大部分人急功近利的跟风。固然最重要的缘由是,所谓中国“第一代前端工程 师”并未作好布道的工做。致使你们对于基础和潜力的态度从以前的忽视演变为现在的蔑视。所谓基础,就是在大学上的那些计算机基础课。所谓潜力,就是戒骄戒 躁的务实做风。这些会在后文中屡次提到。

  对于科班出身的莘莘学苗来讲,根正苗红自己就是一种优点,事实证实,这些人在前端技术上的成长轨迹有必定的套路,并且大都能如期的突破技能瓶颈。从一我的大学毕业到他最满意的工做状态,中间会通过几个阶段。

  前2年是学习技能的阶段,这个阶段主要精力放在专业技能的提高上,2年内起码要遇上平均水平,即所谓“中级“,在这个阶段的人一般对软技能不怎 么关注,沟通能力达不到平均水平,基本上是来啥活干啥活,干不完就加班的这种,对需求的合理性不甚理解,对项目也没什么把控,尽管在技能上有提升的空间, 也不是公司最须要的人,但有很多成长空间。

  工做2-3年的人在前端技能上趋于稳定,也就是技能上的第一次瓶颈,这种人干活熟练,切页面可能也很快,代码看上去也比较规范,属于熟练工,开 始注重沟通技巧和一些职业技能的积累,好比带人带项目,至少有这方面的意识,并有过推进项目、和业务方pk需求的经历,这就达到了中级应当具有的职业技 能,但应当注意的是,这时最容易出现偏科的状况,特别是对于那些“专门切页面的“和“专门写脚本的“人,毕竟html/css/js三者不分彼此,三者是 一个合格前端工程师都必需要掌握的。若是你觉察到自身有偏废的嫌疑,则要当心了,要清楚的了解自身的差距,并意识到瓶颈的存在,为过渡到“中级“的打下基 础。

  过了这道坎以后,工做3年以上的人大部分技能也趋稳,有些人对前端新技术有钻研,可以熟练应对平常工做,软技能也ok,具有有针对性的“拿来主 义“,代码也具备必定的架构性,开始突破“代码民工”的这一层瓶颈,对团队气氛、培训、工做环境有个性化的要求,通常来说,这种人是典型的具备潜力的“中 级”工程师,但很快会遇到职业发展中的第二个技术瓶颈。

  有少数工做3年或4年以上,在不断寻求新的技能上的突破,最明显的一点体现是,开始关注“底层协议”,即HTTP、第三方应用、系统对接、制造 工具、工做流程等,这时思考的重点已经脱离了“切页面”,变为“出方案“,好比要架设一个站点,可以搭建站点框架,预见站点后续(前端)开发中的全部风 险,并一一给出解决方案。项目后续开发遇到问题只要翻阅你提供的“手册”即能找到答案。这种人是标准的“高级”Web前端工程师。

  出方案是一件挺难的事情,它要求一个工程师同时具有经验、技术、气场等诸多硬技能。尤为是对技术底子的要求很是高。

  【半路出家】

  那么,转行作前端的人又当如何呢?其实发展轨迹和科班秀才们很是相似,只是时间跨度可能会长一些,你要花更多的精力、作更多的项目、更多的反思和总结才能理解某个知识点的本质(好比HTTP协议)。固然这只是通常状况。

  此外,这些人还须要摆脱不少思惟定势的禁锢。这里我推荐你们阅读阿当的《Web前端开发修炼之道》。固然,若是你有一个靠谱的师兄带你入道,天然幸运万倍。

  但无论怎样,我始终认为应当秉承兴趣第一的原则,无论你是误打误撞、仍是意欲为之,无论你是科班秀才、仍是半路出家,兴趣始终应当是第一原则, 而后才是你“想作好“。我对本身的要求没法强加于人,因此不少业界大牛在回顾本身成功之路时,提到最多的是:“热爱你的工做、拥抱它给你带来的挑战”。 N.C.Zakas曾经这样勉励你们:

  “我对Web开发人员最大的建议就是:热爱你的工做。热爱跨浏览器开发带来的挑战、热爱互联网技术的种种异端,热爱业内的同行,热爱你的 工 具。互联网发展太快了,若是你不热爱它的话,不可能跟上它的步伐。这意味着你必须多阅读,多动手,保证本身的才能与日俱增。下了班也不能闲着,要作一 些对本身有用的 事儿。能够参与一些开源软件的开发,读读好书,看看牛人的博客。常常参加一些会议,看看别人都在干什么。要想让本身快速成长,有不少事儿 能够去作,并且付出必定会有回报。“

  第三日,幸福感

  【先精通十行?!】

  兴趣第一,听上去很美,但现实却不老是这么酷。练就了一身本领,那也要找到对口的怪物来打一打才过瘾。

  天然,每一个人都想作出好东西,每一个工程师也都渴求这样的机遇,用井井有条的设计、漂亮优雅的代码、精妙的细节雕琢,作出美观、安全、实用耐用的 产品,不过现实是如此残酷,以致于工程师们一直都缺少对产品的归属感。做为前端工程师,如何才能在江湖中把握住前进方向、步步走高?毕竟,在职位繁杂的大 公司,缺少人性化的工做流程影响着工程师的工做幸福感。产品从设计之初、到技术方案评审、再到实现,到处充满了妥协,大部分产品都是杂交的产物,人与人相 互掣肘,每一个人都对产品不满意……,大跃进式的敏捷开发早就被证实百害无一利。但,或许这就是成长的代价。年轻的工程师须要更多的了解需求和设计、产品经 理更要懂得软件迭代规律。对于前端工程师来说更是如此,多学习交互设计和UI,多了解网络协议和软件迭代模型,更能帮助前端工程师和需求方沟通、和后台的 衔接、以及控制版本的迭代。

  说来奇怪,前端工程师不是写html/css/js的吗,搞懂那些边缘知识有什么用?《Web前端开发修炼之道》中也提到,精通一行须要先精通十行。这里我来解释一下缘由。

  做为交互设计师的下游,前端工程师学须要习设计知识是很容易理解的,由于它能帮助你更准确的理解设计师的意图,在原型不完整的时候也能正确的反 馈设计缺陷,将问题阻挡在设计的环节,会大大减小UI bug数量,好比说,设计师会给出理想状态下的容器样式,却每每忽略了文字溢出折行、长连续字符、 容器宽高是否适应内容尺寸变化而变化,溢出部分是做截字仍是隐藏等诸多细节,由于设计师不懂“边界值测试”的道理,而这些问题每每在测试阶段才被发现,所 以,若是能在拿到UI设计稿时就提醒设计师补充完整这些场景,天然减小测试回归次数。

  另外,前端工程师必需要了解网络协议,缘由很简单,咱们作的产品运行在Web上。不少依赖于Ajax的实现,只有前端工程师才会提出实现方案, 产品经理不了解技术瓶颈,后台工程师更不会在乎客户端的用户体验,举个简单的例子:经过JS实现一个Ajax,若是Ajax抓取的数据源是一个302跳 转,则须要在JS程序中多作一些事情,这就须要前端工程师了解一些HTTP协议。应当说,这是很常见的一个场景。

  那么,为何说前端工程师也要关注代码版本控制呢?由于web开发和软件开发本质无异,一样具备迭代周期,需求不是一揽子提完、一口气开发完 的,是有步骤的开发,所以,每次上线开发哪些功能、为后续扩展功能留足哪些接口、代码在可扩展和可维护性上应看成哪些考虑……,这些应当是每一个工程师关注 的事情,所谓迭代就是指这种需求的叠加,这是软件开发的常态,也是web开发的常态,刚开始,前端工程师总会不断抱怨没完没了的需求,代码起初还算干净, 但很快就愈来愈乱,代码的版本管理对于Web前端工程师来讲有些困难,这也使得大部分前端工程师很难上档次,从这个角度讲,前端工程师是须要向后台工程师 学习的,他们的开发量不比前端少,维护代码的能力要超过前端工程师。另外,对于刚入行的前端工程师,心态要放对,提需求是产品经理的职责所在,整理出有价 值的需求是交互设计师的职责所在,将需求做版本控制分步实现是前端工程师的职责所在,前端工程师不必去抱怨产品经理提一大堆没规律的需求,而更应当去理 解需求原因,将需求提炼成UC(用例),让需求在本身手中可控制。只是多数前端工程师缺少提炼、整理需求的能力,一味的在接需求,才会搞的手忙脚乱,带着 情绪堆代码。

  因此,只有练就了一身本领,才会更有目标的去寻找对产品的责任感和对团队的归属感,不要误觉得能切出漂亮的页面就是能力的提升,纯粹的写代码每 我的都差很少的,要成为合格的工程师,眼界要进一步放开,前端工程师能作的,不只仅是切页面而已,做一个精品项目,必定不乏专业的过程把控,这也是大多数 人最易忽略的地方。

  【励志之本】

  其实,除了我的须要明确努力的方向,每一个人都更渴望身处一个好团队,谁都不但愿有猪同样的队友。咱们都很羡慕处身这样的团队,能够放心的将精力 放在纯粹的技术上,身边每一个人都自觉的补充文档注释,代码也层次清晰解偶充分重用率高,精妙的设计实现能够更快的传播,bug获得的改进建议也是务实专业 的,技术在这种良性互动中价值倍增。我想这也算是好团队的一种境界了,这有赖于团队成员水平水涨船高。不过,反观Yahoo的成长之路,他们的技术积淀也 是靠点滴的积累,其实他们当初的情况不比如今的咱们好哪去,10年的进化,才造就了Yahoo技术团队的专业性和Hack精神,咱们每一个人才刚刚起步而 已。为了积攒工做中的幸福感,多付出一些是值得的。

  但我猜,你如今的处境必定不会太过乐观,产品乱提需求、一句话的PRD、不被重视,被生硬的看成“资源“……反正,状况就是这么个状况,要么你 选择抱怨下去,要么想办法去改变。“积极主动“是源自心里的一种坚韧品质,也是励志之本,有些人在现实中被磨平了理想,有些人却在黑暗森林中找到了方向, 这就是犬儒主义和英雄气概之间的差异。这自没必要详说,由于这让我想起了“大长今”,这简直就是前端工程师的励志典范:“这是一个可怕的环境,足以消磨任何 人的斗志和信念,全部来这里的人都变得麻木和无所做为,‘多栽轩‘恶劣的环境没有改变长今,但长今却改变了‘多栽轩‘全部的人“。

  若是你想作到“资深”,就必定要想清楚这一点,由于你是团队的顶梁柱(业务),也是幸福感的源头(士气)。

  第四日,架构和伪架构

  【代码设计的本质】

  读到这里,你不由会问,前端领域存在“架构师”吗?这个问题会在后面的“码农的宿命”中展开解释。这里先说下代码架构的一些杂事吧。

  什么是架构?架构是由“架”和“构”组成,架,即元件,构,即链接件。所以,架构便是将整体分解为单元,而后定义单元之间的链接方式。架构的含 义源自禅宗,而禅宗的基本信条则之一就是真理是没法用语言来描述的。这个基本信条有其背景,即语言具备某种抽象性。而人们对这种抽象性的悟道则直接影响对 事物的见解,进而决定了对客观世界的分解方法。

  而在编程语言中,一样存在这种禅宗所隐喻的悖论。在面向对象的教科书中,一般举一些显而易见的例子,好比“水果”是一个类,包含有苹果、桔子、 香蕉等实例,“蔬菜”也是一个类,包含白菜、冬瓜、茄子等实例。这两个类之间并没有交集,所以很容易理解。但实际项目中状况要复杂的多,好比两个图书类目 “文学”和“历史”,那么“明朝那些事”应当是“文学”类的实例仍是“历史”类的实例呢?即一旦用语言说出了某一事物,即人为的割裂了世界,因而就会陷入 迷途。这在程序设计领域状况更甚,也是形成混乱的主要根源,也就是说,若是你的程序可扩展性很差,必定是程序做者对“单元”的定义不够准确,即单元的概念 之间不够“正交”。而这种架构终是徒有其形,根基不稳。

  所以,变量和类的命名才是真正考验架构功力的关键(命名是否准确清晰、单元之间是否有概念重叠或盲区),而和所谓“组合”、“继承”、“桥接”等模式化的“外表”无本质联系。

  【伪架构】

  实际状况是,程序员早早的就想让本身和“架构”扯上关系,并自封xx架构师。在项目中应用各类模式分层、解耦方法,每一个项目均可以产出一套看上 去很复杂的“架构图”,感受很牛逼的样子,没错,实践这些方法论总不是坏事,但世界观才是方法论的基础,只有在概念上对产品模块有科学的定义,方法论便自 然造成了,《编程珠玑》中一再说起数据结构就是静态的算法,在Web前端领域亦是如此,在页面的建模过程当中,定义分解维度要比分解方法更加基础和重要。我 想阿当能够在《Web前端开发修炼之道》的第二版里加上这部份内容。

  真正的高手用记事本就能写出高质量的代码、用cvs就能作到完美的版本控制、用字典式的分解就能作好系统架构,我想,这正是剑宗一派的最高境界吧。

  第五日:寻找突破

  【动心忍性】

  技术流派看上去是如此吸引人,高手就像侠客通常,来去如风潇洒自如。但反观本身怎么看怎么没有侠客那股范儿。尽管上文提到了一些道理,了解这些 尽管不是坏事,但缺乏实践总感受是纸上谈兵。更况且,平常的工做又是枯燥无味、繁杂单调。每一个人都盼望更高的目标、接触新鲜技术、将新技术运用到平常,在 探索尝试之中寻找成就感。这种感受能够理解,但却缺乏更深层次的思考。由于越到最后越会发现一线的工做才是最有挑战的。固然,我说这话的前提是,你能如前 文所说具有合格的软技能,须要一些技巧让工做变得工整有序、节奏健康,这样你才能将注意力放在纯粹的代码中,摆脱了外界的烦扰,方能从技术的角度思考突 破。这也是从初级到高级的进化过程须要大量的历练的缘由。正如玉伯所说,“枯燥是创新的源泉。若是你发现本身没什么新想法,作事缺乏激情,极可能是由于你 还不曾体验过真正的枯燥的工做”。

  关于如何寻找突破,个人建议是立刻动手作、不要等,相信本身的直觉(这里和上文提到的先思后行是两码事)。好比,Slide幻灯控件理应支持触 屏事件以更好的适应移动终端,或许你在用的Slide幻灯版本很旧、或者时间不容许、再或者你惧怕对Slide改造而引入bug,不要担忧,大不了多花业 余时间,只要想,只要感受合理和必要,就去作。由于这个过程带来的编程体验才是工程师们独有的美妙体味。我如今还时常深夜写代码,没有打扰、思如泉涌、代 码也更加工整严谨,不失为一种享受。所以,用眼睛去观察,用心去感触,“因此动心忍性,才会增益其所不能”啊。

  【得与失】

  互联网的发展的确太快,Web前端技术也在花样翻新,有人经不起诱惑,开始作新的尝试。前端技术虽然范围广,但各个分支都还比较容易入门,好比 服务器端脚本编程、再好比纯粹的WebApp,我认为这二者都是前端技术的范畴,毕竟他们都没有脱离“浏览器”,或者说相似浏览器的环境。NodeJS依 赖于V8,WebApp更是软件化的WebPage。只要打好基础,这些方向都是值得深刻钻研的,由于,互联网的形态愈加多元,新的技术总能找到用武之 地,这就要凭借本身的技术嗅觉和产品直觉,寻找技术和业务的契合点。

  这看上去是一种放弃,放弃了本身赖以生存的铁饭碗(熟练的切页面至少不会失业),实则否则。这种想法是一种误区,新的选择并不会让你放弃什么, 就像学会了开车,并不意味着就不会骑车了。其实改变的是思惟方式而已,是一种进步,若是你能想通这一点,你也能跟得上互联网发展的脚步了,打开你的思惟, 让技术变成你的金刚钻,而不是包袱。

  因此,所谓得失之间的权衡,其实就是“解放思想”。作到了这一点,那么你已经在作“技术驱动”了。

  【误区】

  可是,不要高兴的太早,“技术驱动”是须要大量的积累和经验的。在入行初期,不少人过于着迷与此,从而陷入了迷途。好比有人纠结因而否将dt、 dd的样式清除从reset.css中拿掉,缘由是以为这两个标签的清除样式会耗费一些渲染性能;或者是否须要将for循环改成while循环以提升js 执行速度。尽管这些考虑看上去是合理的,但并非性能的瓶颈所在,也就是说,你花了很大力气重构的代码带来的页面性能提高,每每还不如将两个css文件合 成一个带来的提高明显。就比如用一把米尺量东西,不必精确到小数点后10位,由于精确到小数点后2位就已是不许确的了。这种技术误区经常让人捡了芝麻 丢了西瓜。

  话说回来,这里提到的怀疑权威的精神是绝对应当鼓励的,但不该当止于表象,若是怀疑dt的清除样式会对性能带来影响,就应当想办法拿到数据,用事实来证实本身的猜想。数据是不会骗人的。而求证过程自己就是一种能力的锻炼。

  【技术驱动】

  说到这里,你大概对“技术驱动”有那么一点点感受了。身边太多人在抱怨“公司不重视前端”、公司不是技术驱动的、技术没机会推进产品业绩、个人价值得不到体现?

  什么是技术驱动?简单讲,就是技术对业务有积极推进做用。更多的是工程师发起、工程师影响、工程师负责。刚才提到的用数听说话只是一种“驱动”技巧,那么我须要何种数据,数据从哪里来?我来分享一个实际的场景吧。

  工程师A被委派一个重要的频道首页,由于是新年版,因此要赶在年前上线。A学了一点点响应式设计,想在此次重构中加上,但谁也没作过响应式设 计,需求方根本不懂,设计师也懵懵懂懂,交互设计师太忙,作完交互稿就忙别的去了。A纠结了,循序渐进的把项目作完上线发布,尽管不会出什么问题,但总觉 少点什么。这时A作了两个决定,1,我要按时完成项目,2,趁机实践我在响应式设计中的想法和思考,若成功,做为附加值赠送给需求方,若失败,权当技术玩 具耍一耍罢了。因此A熟练的提早完成了项目,剩下的时间开始考虑如何将首页适应到各个平台中,视觉设计是一大难题,他用吃饭的时间找了设计师收集建议,对 窄屏中的内容模块作了看似合理的编排,代码上hack一下,可以正确适配,就发布上线了。这件事情需求方不知道,视觉设计师也不了解,交互设计师更没工夫 操心。A感受挺爽,开始给工程师弟兄们处处炫耀这个好玩的功能,B看了问,手机端访问量如何,A以为这个问题有道理,就去部署埋点,一周后拿到数据出奇的 意外,首先,移动段的访问量稳步增长,趋势健康,再者,移动端首屏焦点广告位的点击率较PC端高了近一倍,这个数据让A喜出望外,兴奋的拿着报表找到交互 设计师C和市场研究的同事D,D看了报表以后当即启动一个项目,专门调研公司全站响应式设计页面在PC端和移动端的点击率、PV、UV趋势方面的影响…… 后来发生的事情就都水到渠成了,设计师C开始注意设计页面交互时(至少是有条件的考虑)对移动端的适配,D的调研报告也放到了UED老大的案头……接下来 的事情,你懂得。A被指派要出一套响应式最佳实践和规范,最终,A走在了技术的前沿,也所以拿到了好绩效。

  这件事情就是一个典型的技术驱动的例子。谁不让你玩技术了,谁不重视你了,谁把你当工具了,谁以为你的代码没价值?这世界只有本身把本身看扁,谁想跟你这个蝇头小卒过不去?用实力说话,用数听说话,用独到的看法说话,想不作技术驱动都难。

  第六日:码农的宿命

  【青春饭】

  “码农”是IT从业者一个自嘲的称号,也有从事没有发展前景的软件开发职位,靠写代码为生的意思。但我认为码农是一个爱称,编码的农民,和农民 同样有着执着纯真朴实豪爽的共性,仅仅分工不一样而已。就比如农业社会对粮食的依赖,工业化进程对计算机应用也有着很强的依赖,大量的需求催生出这样一群 人。他们有智慧的大脑,对于编程,设计,开发都有着熟练的技巧,但多数人看来,码农的特色是:

  1,收入低
  2,工做单调
  3,工做时间长

  实际上这个描述很是片面,或者说是外行看热闹。第一,全行业比较来看,软件开发领域收入为中等偏上;第二,程序员通常都是有癖好的,沉浸在本身 的癖好中是不会感受单调的;第三,程序员有必定的时间自由度(若是你是一名合格的程序员的话),至少不会像流水生产线工人同样。其实,经过几十年的发展, 咱们对程序员的定义更加科学,好比不少IT企业都开始创建详细的JM(Job Module),即职级模型,程序员沿着专业方向能够走到很高,甚至能够 说,程序员是能够被当成一辈子的事业的。

  然而,有一个很是广泛的观点是,程序员和作模特同样是吃青春饭的,到了三十岁就要考虑转行或者转管理。尽管这种观点颇具欺骗性,但至少它对一种 人是适用的,即入错了行的人。若是你骨子里不想写程序,就算年纪轻轻为了生计写几年代码,以后确定会另有他途。心非所属则没必要勉强,但问题是,即使如此, 你知道你的心之所属吗?

  咱们知道,一个成熟的产业必定须要各色岗位来支撑,若要成熟,则须要时间的沉淀,好比实体经济制造业,创意、生产线、高级技工、技术管理四个方 面都产出大量的高级人才。由于历史悠久,咱们能看获得。而软件产业则否则,九成以上是刚出道的新手,并无太多“高级”和“资深”的具体样板可供参照,在 前端开发领域中状况更甚,绝大部分人根本搞不清楚什么样才是“资深”前端工程师,相比传统软件行业近四十年的进化,我不相信仅有几年光景的前端技术岗位能 产出多少货真价实的“资深”。但互联网崛起速度太快,尚未等技术基础打牢,互联网形态就又花样翻新了,这种变化是一种常态,而岗位的设定也在这种变化之 中天然的优胜劣汰,好比两年前可能还不可思议数据部门会须要前端工程师,他们甚至不直接和浏览器打交道。前端工程师须要适应这种变化带来的观念冲击,不要 觉得本身只能作切页面、或者只会给页面搞重构、只会搞兼容性,要把本身放在整个软件行业来看。

  因此,因为历史“不悠久”致使的岗位模糊自己不是什么大问题,岗位的演化自己就包含在互联网的发展轨迹之中。因此,当今的互联网IT情况,就好 比移动终端的大哥大时代、云计算的肉鸡时代、或者桌面操做系统的DOS时代。所以,前端工程师当前要务是要想清楚看清楚,在互联网中我能作什么,而不是做 为前端工程师我能作什么,因此,从这个角度讲,技术是一个工具,放大来看,技术也只是你职业生涯中很小的组成部分,而你的从业积累、和知识面的广度深度才 是你随着时间的推移慢慢步入“资深”的缘由所在,而不是写了个什么框架就变“资深”了。若是有一天互联网形态固定了,它的岗位可能真正就定型了,才会有真 正清晰的职能边界,就像蓝色巨人IBM中的各色岗位同样,边界清晰,权责分明,普通程序员只能实现接口而无机会设计接口、低层级的工程师也无机会跃进式的 接触项目架构、技术经理人也不能轻易对产品有决策性影响,到这时,人的能力才真正的被限制在方圆以内,容不得越界,这种环境下人的成长很是缓慢。根本不会 有像今天互联网乱局之中所提倡的创新、革命、成长和思想解放。简单讲,一旦产业定型,就不太须要不少“创造”了,更多的是“维护”。因此,我我的宁愿互联 网IT“黑暗”的中世纪越久越好,至少对于年轻气盛程序员来讲,黑暗的丛林环境才是真正的天然进化最理想的土壤,这时我想起了狄更斯在“双城记”中的开 篇。

  “这是最好的时代,这是最坏的时代;这是智慧的时代,这是愚蠢的时代;这是信仰的时期,这是怀疑的时期;这是光明的季节,这是黑暗的季节;这是但愿之春,这是失望之冬;人们面前有着各样事物,人们面前一无全部;人们正在直登天堂,人们正在直下地狱”。

  【半路出家的危与机】

  然而,无论怎样,信心的树立不是一蹴而就的,对于转行作前端的人来讲更是如此。俗话说,隔行入隔山。每一个行业自有其道,天然不是想作就作。前端 技术领域半路出家者很是多,咱们来分析一下转行的心理。第一,看到前端技术入门简单、互联网对前端技术的需求缺口巨大;第二,前端技术所见即所得、感受学 习起来很快;第三,我身边的某某转行做前端看上去不错、我彷佛也能够;第四,我不喜欢我如今作的工做、想换行业、正好前端技术上手较快,就选他吧;第五, 我真的喜欢作Web前端,为它付出再多都是值得的。

  转行者的心态比较容易走两个极端,一是只看到新行业的好,二是只以为原工做很糟糕。但无论是什么行业的转行,对本身的职业规划的思考都应当先行一步。即务必首先清晰的回答这些问题:

  1,我能作什么?
  2,我不能作什么?
  3,个人优点是什么?
  4,个人劣势是什么?
  5,作新行业对我有何好处?
  6,换行会让我付出何种代价?
  7,如何定义转行成功?

  由于面试的时候必定会被这些问题所挑战。若是支支吾吾说不清楚,要么是对本身将来不负责任,要么骨子里就是草根一族,习惯作什么都走马观花浅尝 辄止,也难让人信服你的转行是一个权衡再三看起来合理的选择。我没法帮每一个人回答这些问题,但至少有两点是肯定的,第一,Web前端技术是一个朝阳行业, 绝对值得义无反顾的坚持下去;第二,你将经历从未有过的枯燥、苛刻的历练,所谓痛苦的“行弗乱其所为“阶段。不过话说回来,经历太高考的人,还怕个屁啊。

  有心之人自有城府、懂得放弃,看得清大势中的危机、识得懂繁华里的机遇。尤为当立足于Web前端技术时,这种感受就愈发强烈。由于国内外前端技 术领域从2000年至今一直很是活跃,前端技术前进的步伐也很快,对于一些人来讲,无论你是在大公司供职仍是创业,无论你是在接外包项目仍是本身写开源项 目,从转行到跟得上新技术的脚步是有一些方法和“捷径”的。

  第一,梳理知识架构

  咱们知道知识积累有两种思路,第一种是先构建知识面、创建技术体系的大局观,即构建树干,而后分别深刻每个知识点,即构建枝叶,最终造成大 树。第二种是先收集知识点,越多越好,最后用一根线索将这些知识点串接起来,一样造成大树。第一种方法比较适合科班秀才,第二种方法则更适合转行做前端的 人,即实践先行,理论升华在后。好比对“IE6怪异模式“这条线索来讲,要首先将遇到的IE6下的样式bug收集起来,每一个bug都力争写一个简单的 demo复现之,等到你收集到第100个bug的时候,再笨的人都能看出一些规律,这时就会天然的理解IE的hasLayout、BFC和各类bug的原 因、你就成为了IE6的hack专家了,当你成为100个知识线索的专家的时候,你已经能够称得上“资深”的水平了。咱们知道,10我的中有9个是坚持不 下来的,他们会以项目忙等各类理由万般推托,将本身硬生生的限制在草根一族,坐等被淘汰。因此,对于立志做前端的人来讲,这种点滴积累和梳理知识很是重 要。

  第二,分解目标

  将手头的工做分解为几部分来看待,1,基本技能,2,项目经验,3,沟通能力,4,主动性和影响力。想清楚作一件事情你想在哪方面获得历练,比 如,我以前在作第一次淘宝彩票常规性重构的时候(正好是一次视觉和交互上的全新设计),我清楚的明白此次重构的目的是锻炼本身在架构准富应用时的模块解偶 能力,寻找在其余项目中架构的共通之处,因此我宁愿加班或花更多精力作这个事情,固然更没打算向业务方多解释什么,这件事情对我来讲纯粹是技能的锻炼。而 通过这一次重构以后,我意外的发现对业务的理解更透彻深刻、更清晰的把握用户体验上的瓶颈所在。若是一开始就把此次常规改版当成一个普通的项目循序渐进的 作,我只能说,你也能按时完成项目,按时发布,但真真浪费了一次宝贵的锻炼机会,项目总结时也难有“动心忍性”的体会。

  因此,每一个项目的每一个事情都应当认真对待,甚至要超出认真的对待,想清楚作好每件事对于本身哪方面有所提高?哪怕是一个bug的解决,即使不是 本身的问题也不要草草踢出去了事,而是分析出问题缘由,给出方案,有目的involve各方知晓……,正规的对待每一个不起眼的小事,时间久了历练了心智, 这时若是忽然遇到一个p0级的严重线上bug(好比淘宝首页白屏,够严重的了吧)也不会当即乱了方寸,这也是我上文提到的心有城府天然淡定万倍,而这种淡 定的气场对身边浮躁的人来讲也是一种震慑和疗伤,影响力天然而然就造成了。

  第三,做分享

  作分享这事儿真的是一本万利。有心的人必定要逼着本身作分享,并且要作好。首先,本身了解的知识不叫掌握,只有理解并表达出来能让别人理解才叫 掌握,好比若是你解释不清楚hasLayout,多半说明本身没理解,若是你搞不懂双飞翼的使用场景,可能真的不知道布局的核心要素。再者,做分享绝对锻 炼知识点的提炼能力和表达能力,咱们做为工程师不知道多少次和强硬的需求方pk,被击败的一塌糊涂。也反映出工程师很难提炼出通俗易懂的语言将技术要点表 述清楚。而作ppt和分享正是锻炼这种能力,将本身的观点提炼出要点和线索,分享次数多了,天然熟能生巧。档次也再慢慢提升。另外一方面,逼迫本身站在公众 场合里大声讲话,原本就是提升自信的一种锻炼。

  这时,你或许会问,我讲的东西你们都明白,我讲的是否是多余,我第一次讲讲很差怎么办,你们会不会像看玩猴似的看我“这SB,讲这么烂还上来说”?要是讲很差我之后再讲没人听怎么办,我从此怎么作人啊?

  老实说,这是一道坎,任何人都要跨过去的,谁都同样,你敢鼓起勇气在大庭广众之下向爱人表白,就没勇气对本身的职业宿命说不?其实勇敢的跨越这 一步,你会意外的收获他人的掌声和赞许,这些掌声和赞许不是送给你所分享的内容,而是送给你的认真和勇气。这个心结过不去,那就老老实实呆在本身的象牙塔 里遗老终生,当一生工程师里的钻石王老五吧。

  【匠人多福】

  若是你能耐心读到这里,内心必定有一个疑问,上面说的都是技术上能力上怎样怎样,那我所作项目不给力又当如何?若是项目不挣钱、黄了、裁了,个人努力不就白费了吗?我又有什么绩效和价值呢?

  没错,有这种想法的人不在少数。特别是刚出道的校招同窗每每更加心高气傲,觉得本身有改变世界的本事,必定要参与一个牛逼的团队作一款光鲜靓丽受人追捧能给本身脸上贴金的项目。若是你有这种想法,趁早打消掉这个念头,固然,咱们这里先不讨论创业的情形。

  第一,若是你刚毕业就加入一个牛逼团队,说难听点,你就是团队中其余人眼中的“猪同样的队友”,不创造价值且拖项目后腿(显然你们都要照顾你的成长啊),按照271理论,你没有理由不是这个1。至少至关长一段时间内是这样。

  第二,你在所谓牛逼团队中的创造性受限,由于创新多来自于团队中的“资深“和大牛们,你参与讨论但观点一般不会被采纳,他们只会给你这个菜鸟分活干,想一想看,你如何能花两到三年就超越身边的大牛们?甚至连拉近与他们的距离都难。

  第三,若是身在牛逼团队,天然心理对周围的牛人们有所期待,但愿他们能灌输给你一些牛逼的知识和牛逼的理念。这种思想上的惰性在职场生涯之初是很是危险的。要知道技术和知识自己是很简单和淳朴的,只不过披上了一个光鲜项目的外衣而让人感受不同凡响。

  第四,由简入奢易,由奢入简难,作过一个看似光彩的项目,心理再难放平稳,去踏实的作一个看上去不那么酷的产品。这种浮躁心态会严重影响从此的职业发展和成长。

  第五,光鲜靓丽的项目被各类老大关注,是难容忍犯错误的,傻瓜都知道犯错误在成长之初的重要性。

  就我所看到的情形看,一开始加入看似很牛的项目组,三年后获得的成长,比那些开始加入一个不被重视的项目的同窗要小不少,然后者在能力上的弹性 却更大。因此,道理很简单,你是要把一个很酷的项目作的和以前差很少酷,仍是把一个不酷的项目作的很酷?项目是否是由于你的加入而变得不同凡响了?

  从这个角度讲,无论是转行的新人仍是刚出道的秀才,最好将本身看成“匠人”来对待,你的工做是“打磨”你的项目,并在这个过程当中收获经验和成 长。付出的是勤奋,锻炼的是手艺,磨练的是心智。所以,你的价值来自于你“活儿“的质量,“活儿”的质量来自于你接手的项目以前和以后的差异。作好活儿是 匠人应有的职业心态。想通这一点,心里天然少一些纠结,才会对本身对项目的贡献度有客观的认识,不会感受被项目所绑架。

  作一名多福的匠人,拥有了金刚钻、就不怕揽不到瓷器活儿。但对于人的成长来讲,若是说“项目”重要但不关键,那么什么才是关键呢?这个话题还会在接下来的“伯乐与千里马”这篇中给出答案。 

  【若干年后】

  如今,让咱们回过头回答一下“青春饭”的问题。在“青春饭”小节中提到,“程序员到三十岁以后须要转行或者转管理吗?”

  上文提到,工业化生产的四个领域,1,创意,2,生产线,3,高级技工,4,技术管理。Web前端技术也是如此,能够在这四个领域找到各自的归宿。

  第一,“创意“

  即和产品需求越走越近,拥有良好的产品感,对产品需求、设计交互把握准确,可以用适当的技术方案推进产品用户体验,属于“架构师”的范畴,由于 职能更加靠前,偏“出主意”型的。这种人更贴近用户,须要活跃的思惟、广阔眼界、厚实的项目经验。更多的影响产品体验方面的决策。

  第二,“生产线“

  即前端基础设施建设,优化前端开发流程,开发工具,包括开发环境、打包上线自动化、和各类监控平台和数据收集等,属于“技术支持”的范畴,相比于不少企业粗犷难用的平台工具,前端技术方面的基础设施建设基础还需更加夯实,由于这是高效生产的基本保证。

  第三,“高级技工“

  即高级前端开发工程师,专职作项目,将产品作精作透,用代码将产品用户体验推向极致,偏“实战”型的,是项目的中坚力量,直接产出成果,影响产品效益。属于项目里的“资深”。

  第四,“技术管理“

  即作技术经理,这才是多数人所理解的“管理”,其实就是带团队、靠团队拿成果。这类人具备敏感的技术情结,在技术风潮中把握方向,可以指导培训新人,为各个业务输出前端人才,偏“教练”型的,促进新技术对业务的影响。并有意识的开辟新的技术领域。

  可见,转管理可不是想固然,也不是所谓作项目变资深了就能转管理,转了也不必定能作好。根据“彼得原理”,即人老是倾向于晋升到他所不能胜任的岗位,这时就又陷入“帕金森”定律所隐喻的恶性循环之中,直到你带的团队整个垮掉。

  因此,转管理应当是一件很是慎重的事情,不是所谓程序员混不下去就转管理这么简单。但无论怎样,有一件事情是须要尤为要想清楚,即,转了管理,技术就丢了吗?咱们在第七日“伯乐与千里马”中再深刻聊聊这个事儿。

  第七日,伯乐与千里马

  【师兄们的抉择 1】

  千里马常有,而伯乐不常有。——韩愈,“马说”。

  一我的这辈子能遇到一个好师兄是一种缘分,可遇不可求。不少人工做中的幸福感彷佛也源自这种被认同,被师兄的了解和认同,有人能直言不讳的指出 你的不足,帮你发现机会,并将最适合你作的事情分配给你,这是莫大的幸运,但如此幸运的人十之一二,大多数人由于缺乏伯乐的提点,渐渐辱于“奴隶人之手 “,潜力渐失,毁于中庸。

  在前端技术领域,这种状况很广泛也很特殊,固然有不少客观缘由。即前端技术进入公众视野时间不长,有实力的伯乐更加是百里挑一。更况且,Web 前端技术还有着一些江湖气,知识点过于琐碎,技术价值观的博弈也难分伯仲,即全局的系统的知识结构并未成体系,这些因素也客观上影响了“正统“前端技术的 沉淀,奇技淫巧被滥用,前端技术知识的传承也过于泛泛,新人很难看清时局把握主次,加之业务上的压力,未免过早致使技术动做变形。而这些问题也没法全赖自 己全盘消化,如有人指点迷津,状况要好上万倍。所以,前端技术领域,为本身觅得一个靠谱的师兄,重要性要盖过项目、团队、公司、甚至薪水。

  这也是上文所说的“项目不重要,师兄才重要“的缘由。说到这里就有一个问题,每一个人都问下本身,你是想当师弟呢仍是想当师兄呢?当师兄有什么好处呢?

  没错,不少师兄都是被师兄,甚至没有作好当师兄的准备,更进一步说,很多经理人也都是“被经理人“,没有作好准备就被推到了管理岗位。带人是耗 精力的,师兄要作不少思想斗争才舍得把这些宝贵的精力放在那些菜鸟身上,这不是一个技术问题,而是一个道德问题。要记住,没有谁应该平白无故把本身所掌握 技能给你倾囊相授,如此皆命也。读到这里,做为菜鸟,做为学徒,做为新人,做为师弟,你作到对这份命运的足够尊重了吗?

  尊师重教的传统美德并无在技术领域得以很好的延续。也正由于此,人才梯队难创建起来,但对于师兄来讲,倒是有更多机遇的。

  【师兄们的抉择 2】

  做为师兄,无论是主动仍是被动,确定会想当师兄对我有什么提高?对于初次作师兄的人来讲,最大的提高在于两方面,1,任务分解,2,问题分析。

  第一,任务分解,做为师兄要给师弟派分任务,就涉及到任务分解,分解这事儿往低了说,就是派活,往高了说,其实就是作“架构”,好比一个页面, 按照什么思路进行模块划分,模块划分是否适合单人开发,如何控制共用样式和共用脚本,我须要为他提供什么接口,如何控制他的代码并入整个页面时不会影响整 体页面代码的熵值,这些都是实打实的“架构“应该包含的问题,而从小页面开始就作这种锻炼,作的多了,“架构感”天然就造成了。

  第二,问题分析,在以前本身写代码都是单打独斗,什么都是用代码解决问题,但一旦涉及协做,就要强迫本身分析问题,或者说给徒弟分析问题,告诉 他应当用什么方法来解决问题,当说到“方法”时,脑子里定造成了一个方案,按照这个方案路子走必定能解决问题。分析问题比写代码要更抽象、更高效,由于在 脑子里构建方案要比写代码要快,思考也会更加缜密,当锻炼的多了,思考愈来愈快,代码的草稿也很快就在脑海中造成了,这也是咱们说为何不少人不写代码但 编码思路和水平都很高的缘由。

  这些工做方法对了,积累多了,就是提升。对于技术经理人来讲,也是一样的道理。因此,就像在第五日的“得与失”部分提到的那样,转身师兄、变身管理并不意味着“失“掉技术饭碗,而是一种进步。

  【作本身的伯乐】

  那么,在前端技术领域里什么样的人才算千里马,其实人人都是千里马,人人均可以发掘本身的潜力,若是上面的文字你能读懂,能承认,这种自我发掘已经开始了,没有一个好伯乐又何妨呢?作一个勤快的小码农,少一些势利的纷争,很快会发现,本身才是最好的伯乐。

  但这并非说,他人对本身的观点不重要,有时甚至要综合各类声音,因此,多找身边的大牛们聊聊天,多找你的师兄和主管,无论他们给你的建议是多么形而上,总有一些声音对你是有益的,多收集,有好处。

  第八日,作地球上最牛的UED

  【谁推进了历史前进,英雄?仍是人民?】

  “作地球上最牛的UED!”,这是淘宝UED创立之初的口号,如今被渐渐淡忘了,由于微博上的一些讨论,又想起了这份曾经美好的初衷。玉伯也感 叹道:“这愿景曾吸引了多少好汉前往投奔呀。只惋惜短短几年间,这愿景好像愈来愈远了”。问题是,要作好一个团队,靠的是我的、仍是总体?愿景是愈来愈远 了吗?

  是谁推进了历史的前进,是英雄?仍是人民?微观来看,是英雄,宏观来看,是人民。再放大了看,是互联网大潮之崛起推进了前端技术的进步,时势须要UED、须要用户体验。

  因此,UED团队的创立发展受这些积极的外因影响,遇上了好时候,成员也跟着沾光。然而,我并不关心这个口号,我只关心体制内的关键人物,那些 带动整个团队水涨船高的人们。每每咱们发现,某些人的高度表明了整个团队的高度,个体的影响力表明了整个团队的影响力,某我的的水平表明了整个团队的水 平。支付宝、淘宝、腾讯、百度、盛大,都是如此。而咱们做为普通的个体,正是要励志成为这种人,成为真真用技术推进用户体验前进的尖刀人物。

  这时我想起了不少人在知乎上的问题,关于跳槽、关于转行、关于创业、关于各类UED团队。我想,读得懂我上面的文字,你心理也许会有本身的答案。

  【归宿】

  最后,还有一个不得不说的问题,即归属问题,前端开发应当归属于UED仍是技术部门?应当说,当前Web前端技术的价值体如今“用户体验“上。 是用户体验这块阵地最后一道坎。也就是说,前端工程师应当重点考虑我所做的页面的感官体验。这是须要一些灵感和感性的,应当看到帅气优雅的界面会心有所 动、或者实现一款精巧的小组件时萌生一阵快意。这种所见即所得的美妙编程体验正是其余后端工程师没法体验到的。所以,这种精确到像素级的精工雕琢虽然不直 接决定产品生死,但倒是提高产品品味和时尚感的要素。物质愈来愈丰富的今天,大众的更高诉求不就是品味和时尚吗?

  若是将前端归到技术部门,一方面和“设计“离的更远,代码写的规规矩矩但渐缺乏了灵性,另外一方面做为工程师又缺乏计算机专业课的功底,才真正丧 失了优点所在,若是有一天,前端工程师的平均水平足够高,清一色的计算机科班出身,彷佛更合适纳入到技术部门。因此,Web前端工程师是“工程师“,须要 科学严谨的编程能力,但身处UED所应当具有的美感和灵性是万不可被剥夺去的。

  还有一点,Web前端工程师做为UED之中最具实践精神和逻辑思惟的工种,是可以将技术对设计的影响发挥到最大,能够催生出大量的创造和革新的,这一点也是传统后端工程师所不具有的。

  第九日,前端技术体系

  如今愈来愈感受到前端技术须要成体系的积累,一方面能够规范咱们的前端技术培训,另外一方面,做为知识线索为新人作指引,省的走弯路,避免陷入奇技淫巧的深坑之中不能自拔。

  以前我整理了一下“前端技术知识结构”,罗列的比较散,但也基本表述清楚了个人观点。今年上半年也在整个研发中心组织了一次前端技术培训,对于前端技术的演化规律也有过整理,都放在了这个ppt中,但愿对你们有所帮助。

js面向对象

【一】 面向对象的基本概念

  面向对象的英文全称叫作Object Oriented,简称OO。OO其实包括OOA(Object Oriented Analysis,面向对象分析)、OOD(Object Oriented Design,面向对象设计)和OOP(Object Oriented Programming,面向对象的程序设计)。

  一般所说的面向对象是指OOP, OOP是一种围绕真实世界的概念来组织模型的程序设计方法,它采用对象来描述问题空间的实体。在使用计算机解决问题时,对象是做为计算机模拟真实世界的一个抽象,一个对象就是一个物理实体或逻辑实体,它反映了系统为之保存信息和(或)与它交互的能力。使其具备本身的属性和行为, 从而简化对复琐事物的描述,更有利于工程的可维护性和扩展性。

  OOP同结构化程序设计相比最大的区别就在于: 前者首先关心的是所要处理的数据,然后者首先关心的是功能。

  【二】 面向对象三个基本特征

  封装 (Encapsulation) 将数据以及相关的操做组织在一块儿,成为独立的构件。外部没法直接访问这些封装了的数据,从而保证了这些数据的正确性。封装的目的是为了内部数据表现形式和实现细节的隐藏,信息隐藏是为了减小系统各部分间的依赖性,各部分间必须经过明确的通道传送信息,也就是对象间的接口.这样一来,隐藏了部份内部的细节,极大方便系统的开发,维护和扩展。

  继承 (Inheritance) 继承是一种联结类的层次模型,而且容许和鼓励类的重用,它提供了一种明确表述共性的方法。一个新类能够从现有的类中派生,这个过程称为类的继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类能够从它的基类那里继承方法和实例变量,而且派生类能够修改或增长新的方法使之更适合特殊的需求。继承性很好地解决了软件的可重用性问题。

  多态 (Polymorphism) 多态是容许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值以后,父对象就能够根据当前赋值给它的子对象的特性以不一样的方式运做。简单的说,就是容许类与类之间相同方法名的指针得以调用, 这样很好地解决了应用程序函数同名问题。实现多态,有二种方式,覆盖,重载。

  【三】 Javascript 面向对象

  javascript自己是一种基于对象(object-based)的语言,咱们平常编码过程当中用到的全部东西几乎都是对象(Number, String, Boolean, etc.)。可是,相对于一些流行的面向对象语言(C++, C#, java),它又不是一种真正的面向对象编程(OOP)语言,由于它的语法中没有class的概念。

  Keyword: class, object, `this`, closure, constructor, prototype

  几种对象封装的方法

  • 继承
  • 多态体现

  之1、几种对象封装的方法

  1. 对象封装 – 原始模式

  假定咱们把猫当作一个对象,它有”name”和”color”两个属性, “etc” 行为。

var Cat = {     name: ''     color: '',     eat: function() {} }; 

  如今,咱们须要根据这个原型对象的规格(schema),生成两个实例对象。

function eat() {     console.log('I\'m eta fish'); } var cat1 = {name: 'Kitty', color: 'white', eat: eat}; var cat2 = {name: 'Smokey', color: 'black', eat: eat};  // var cat3, cat4 ,... 

  不方便建立多个实例对象,扩展性差, 实例(cat1, cat2)之间找不到联系。…

  2. 对象封装 – 构造函数模式

  “构造函数”,就是一个普通函数,可是内部使用了 `this` 变量。对函数使用 `new` 运算符,就能生成实例,而且 `this` 变量会绑定在实例对象上。

  使用构造器建立出来的对象会有一个 `constructor` 属性,指向它们的构造函数。

  `Class` 只是一个模板,建立出来的来实例都是由模板生成。

  好比,猫的原型对象如今能够这样写:

function Cat(name,color){     this.name = name;     this.color = color;     this.eat = function() { console.log('eat fish'); }; } var cat1 = new Cat('Kitty', 'black'); console.log(cat1.name); // Kitty console.log(cat1 instanceof Cat); // TRUE // 这时 cat1 实例会自动含有一个 `constructor` 属性,指向它们的构造函数 `Cat`。 var cat2 = Cat('Smokey', 'white'); console.log(cat2); // undefined 

  3. 对象封装 – Prototype 模式

  `prototype` 是 `Function` 对象的一个属性,这个属性指向另外一个对象。 这个对象的全部属性和方法,都会被构造函数的实例继承。

  同时 `prototype` 又存在一个指向构造函数的引用 `constructor`,这样就成功的构成一个循环引用的原型链结构。

  咱们能够把那些不变的属性和方法,直接定义在 `prototype` 对象上, 节省内存开销。

function Cat(name, color) {     this.name = name;     this.color = color; } Cat.prototype.type = 'mammal'; Cat.prototype.eat = function() { console.log('eat fish'); }; var cat1 = new Cat('Kitty', 'white'); var cat2 = new Cat('Smokey', 'black'); console.log(cat1.type); // mammal console.log(cat1.eta === cat2.eta);     // TRUE, same reference console.log(cat1.constructor === Cat)   // TRUE, from Person.prototype 

  之2、继承 (Inheritance)

  将持有共性特色的属性或行为抽象出一个基本类, 能够按不一样层次结构的业务分组抽象出多个基础类。

  Cat, Bird

  1. 继承 – 构造函数绑定

  使用call或apply方法,将父对象的构造函数绑定在子对象上。

function Animal() {     this.species = 'animal';     this.sleep = function() { console.log('I\'m sleep at night'); }; } function Cat(name, color) {     this.name = name;     this.color = color; } 

  让`Cat` 继承 `Animal` 的特性:

/** @class Cat */ function Cat(name, color) {     Animal.apply(this);     this.name = name;     this.color = color; } var cat1 = new Cat('Kitty', 'white'); cat1.sleep(); // I am sleep at night 

  2. 继承 – 原型链继承

  若是”猫”的prototype对象,指向一个Animal的实例,那么全部”猫”的实例,就能继承Animal了。

/** @class Cat */ function Cat(name, color) {     this.name = name;     this.color = color; } Cat.prototype = new Animal; Cat.prototype.eta = function() { console.log('fish is my delicious'); }; 

  它至关于彻底删除了prototype 对象原先的值,而后赋予一个新值

// 任何一个prototype对象都有一个constructor属性,指向它的构造函数 Cat.prototype.constructor = Cat; // fix prototype chains var cat = new Cat('Kitty', 'fish'); cat.eat();      // fish is my delicious cat.sleep();    // I'm sleep at night' console.log(cat instanceof Cat);    // TRUE console.log(cat instanceof Animal); // TRUE 

  须要建立父类实列来实现 `prototype` 继承

  3. 继承 (Inheritance) – 利用空对象做为中介实现原型继承

var F = function() {}; F.prototype = Animal.prototype; Cat.prototype = new F(); Cat.prototype.constructor = Cat; 

  咱们将上面的方法,封装成一个函数,便于使用。

function extend(ctor, superctor, px) {     if (!superctor || !ctor) throw Error('extend failed, verify dependencies');     var F = function() {};     F.prototype = superctor.prototype;     ctor.prototype = new F();     ctor.prototype.constructor = ctor;     ctor.superclass = superctor.prototype; // cache super class proto reference.     if (px) { // extend class implements         for (var k in px) {             if (px.hasOwnProperty(k)) ctor.prototype[k] = px[k];         }     }     return ctor; } 

  4 继承 – 借住工具方法实现继承

/** @class Mammal */ extend(Cat, Animal, {     eat: function() {         Cat.superclass.eat.call(this); // call super method         console.log('Also i like some ofther food, such as beef and more.');     } }); var cat = new Cat('Smokey', 'fish'); cat.sleep(); cat.eat(); console.log(cat instanceof Animal); console.log(cat instanceof Cat); 

  之3、多态

  1. 多态 – 经过重写原型方法来实现方法重名调用

/** @class Cat */ extend(Cat, Animal, {     eat: function() {         Cat.superclass.eat.call(this); // call super method         console.log('Also i like some ofther food, such as beef and more.');     } }); 

  2. 多态 (Polymorphism) – 原型继承 `prototype` 链上的方法、属性查找

  【四】总结 Summary

  Constructor

  Prototype

  Inheritance

 

js日期类

/**
* 日期处理工具类
*/

var DateUtil = function(){

    /**
     * 判断闰年
     * @param date Date日期对象
     * @return boolean true 或false
     */
    this.isLeapYear = function(date){
        return (0==date.getYear()%4&&((date.getYear()%100!=0)||(date.getYear()%400==0))); 
    }
    
    /**
     * 日期对象转换为指定格式的字符串
     * @param f 日期格式,格式定义以下 yyyy-MM-dd HH:mm:ss
     * @param date Date日期对象, 若是缺省,则为当前时间
     *
     * YYYY/yyyy/YY/yy 表示年份  
     * MM/M 月份  
     * W/w 星期  
     * dd/DD/d/D 日期  
     * hh/HH/h/H 时间  
     * mm/m 分钟  
     * ss/SS/s/S 秒  
     * @return string 指定格式的时间字符串
     */
    this.dateToStr = function(formatStr, date){
        formatStr = arguments[0] || "yyyy-MM-dd HH:mm:ss";
        date = arguments[1] || new Date();
        var str = formatStr;   
        var Week = ['日','一','二','三','四','五','六'];  
        str=str.replace(/yyyy|YYYY/,date.getFullYear());   
        str=str.replace(/yy|YY/,(date.getYear() % 100)>9?(date.getYear() % 100).toString():'0' + (date.getYear() % 100));   
        str=str.replace(/MM/,date.getMonth()>9?(date.getMonth() + 1):'0' + (date.getMonth() + 1));   
        str=str.replace(/M/g,date.getMonth());   
        str=str.replace(/w|W/g,Week[date.getDay()]);   
      
        str=str.replace(/dd|DD/,date.getDate()>9?date.getDate().toString():'0' + date.getDate());   
        str=str.replace(/d|D/g,date.getDate());   
      
        str=str.replace(/hh|HH/,date.getHours()>9?date.getHours().toString():'0' + date.getHours());   
        str=str.replace(/h|H/g,date.getHours());   
        str=str.replace(/mm/,date.getMinutes()>9?date.getMinutes().toString():'0' + date.getMinutes());   
        str=str.replace(/m/g,date.getMinutes());   
      
        str=str.replace(/ss|SS/,date.getSeconds()>9?date.getSeconds().toString():'0' + date.getSeconds());   
        str=str.replace(/s|S/g,date.getSeconds());   
      
        return str;   
    }

    
    /**
    * 日期计算  
    * @param strInterval string  可选值 y 年 m月 d日 w星期 ww周 h时 n分 s秒  
    * @param num int
    * @param date Date 日期对象
    * @return Date 返回日期对象
    */
    this.dateAdd = function(strInterval, num, date){
        date =  arguments[2] || new Date();
        switch (strInterval) { 
            case 's' :return new Date(date.getTime() + (1000 * num));  
            case 'n' :return new Date(date.getTime() + (60000 * num));  
            case 'h' :return new Date(date.getTime() + (3600000 * num));  
            case 'd' :return new Date(date.getTime() + (86400000 * num));  
            case 'w' :return new Date(date.getTime() + ((86400000 * 7) * num));  
            case 'm' :return new Date(date.getFullYear(), (date.getMonth()) + num, date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());  
            case 'y' :return new Date((date.getFullYear() + num), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());  
        }  
    }  
    
    /**
    * 比较日期差 dtEnd 格式为日期型或者有效日期格式字符串
    * @param strInterval string  可选值 y 年 m月 d日 w星期 ww周 h时 n分 s秒  
    * @param dtStart Date  可选值 y 年 m月 d日 w星期 ww周 h时 n分 s秒
    * @param dtEnd Date  可选值 y 年 m月 d日 w星期 ww周 h时 n分 s秒 
    */
    this.dateDiff = function(strInterval, dtStart, dtEnd) {   
        switch (strInterval) {   
            case 's' :return parseInt((dtEnd - dtStart) / 1000);  
            case 'n' :return parseInt((dtEnd - dtStart) / 60000);  
            case 'h' :return parseInt((dtEnd - dtStart) / 3600000);  
            case 'd' :return parseInt((dtEnd - dtStart) / 86400000);  
            case 'w' :return parseInt((dtEnd - dtStart) / (86400000 * 7));  
            case 'm' :return (dtEnd.getMonth()+1)+((dtEnd.getFullYear()-dtStart.getFullYear())*12) - (dtStart.getMonth()+1);  
            case 'y' :return dtEnd.getFullYear() - dtStart.getFullYear();  
        }  
    }

    /**
    * 字符串转换为日期对象
    * @param date Date 格式为yyyy-MM-dd HH:mm:ss,必须按年月日时分秒的顺序,中间分隔符不限制
    */
    this.strToDate = function(dateStr){
        var data = dateStr;  
        var reCat = /(\d{1,4})/gm;   
        var t