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);
}

@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();
 }
 
 
 
}

public class MyServer {

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

}



--

 

@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"));
 }

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

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

 @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("");
 }

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

}

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);
   //4、封装相应的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
  
01package com.think.cla;
02  
03import java.io.BufferedReader;
04import java.io.IOException;
05import java.io.InputStreamReader;
06  
07public 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();
    }

}
 

设计模式之命令模式

 命令模式就是将一组对象的相似行为,进行了抽象,将调用者与被调用者之间进行解耦,提
高了应用的灵活性。命令模式将调用的目标对象的一些异构性给封装起来,通过统一的方式来为调用者提供服务。
适用场景
    1、当一个应用程序调用者与多个目标对象之间存在调用关系时,并且目标对象之间的操作很类似的时候。
      2、例如当一个目标对象内部的方法调用太复杂,或者内部的方法需要协作才能完成对象的某个特点操作时。
      3、有时候调用者调用目标对象后,需要回调一些方法。
例子:
命令接口:
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 事件)来接收处理的。
第一、简单介绍一下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

六、避免不需要的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"); } }
七、避免不需要的造型操作 所有的类都是直接或者间接继承自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; } }
八、如果只是查找单个字符的话,用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)) { // ... } } }
九、使用移位操作来代替'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; // 不能转换成位移操作 } }
十、使用移位操作代替'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; // 不能转换 } }
十一、在字符串相加的时候,使用 ' ' 代替 " ",如果该字符串只有一个字符的话 例子: 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' } }
十二、将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) {} }
十三、对于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"); } }
十四、对于常量字符串,用'string' 代替 'stringbuffer' 常量字符串并不需要动态改变长度。 例子: public class usc { string method () { stringbuffer s = new stringbuffer ("hello"); string t = s + "world!"; return t; } } 更正: 把stringbuffer换成string,如果确定这个string不会再变的话,这将会减少运行开销提高性能。
十五、使用条件操作符替代"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); } }
十六、不要在循环体中实例化变量 在循环体中实例化临时变量将会增加内存消耗 例子: 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

一、避免在循环条件中使用复杂表达式 在不做编译优化的情况下,在循环中,循环条件会被反复计算,如果不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快。 例子: 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++) ; //   } }
二、为'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);

三、在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块

四、使用'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); } }

五、让访问实例内变量的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.#能取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项功能,我没有做过多介绍,因为目前为止这两项功能我使用并不多。
  二、%{}的用途是在标签的属性为字符串类型时,计算OGNL表达式的值。这个功能目前还没有深刻体会,故不介绍。
  三、${}有两个主要的用途。
  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函数

一、function概述

   javascript中的函数不同于其他的语言,每个函数都是作为一个对象被维护和运行的。通过函数对象的性质,可以很方便的将一个函数赋值给一个变量或者将函数作为参数传递。

   函数对象与其他用户所定义的对象有着本质的区别,这一类对象被称之为内部对象。内置对象的构造器是由JavaScript本身所定义的。

二、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是表示返回的值,而不是创建的函数,因为括号“(”比等号“=”有更高的优先级。

三、匿名函数和有名函数的区别

   匿名函数必须先定义后调用,有名函数可以先调用,后定义。

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、不被重视,被生硬的当作“资源“……反正,情况就是这么个情况,要么你 选择抱怨下去,要么想办法去改变。“积极主动“是源自内心的一种坚韧品质,也是励志之本,有些人在现实中被磨平了理想,有些人却在黑暗森林中找到了方向, 这就是犬儒主义和英雄气概之间的差别。这自不必详说,因为这让我想起了“大长今”,这简直就是前端工程师的励志典范:“这是一个可怕的环境,足以消磨任何 人的斗志和信念,所有来这里的人都变得麻木和无所作为,‘多栽轩‘恶劣的环境没有改变长今,但长今却改变了‘多栽轩‘所有的人“。

  如果你想做到“资深”,就一定要想清楚这一点,因为你