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>[email protected]</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);
    //judgment node Whether the type is a start or end or a text node, and then process it according to the situation
    if(type==XMLStreamConstants.START_ELEMENT) {//==1, indicating that the event is a start element
     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() {//test object conversion xml string   try {    JAXBContext ctx = JAXBContext.newInstance(Student.class);    Marshaller marshaller = ctx.createMarshaller();    Student stu = new Student(1,"Zhang San",21,new Classroom(1,"10 Computer Application Technology",2010));    marshaller.marshal(stu, System.out);   } catch (JAXBException e) {    e.printStackTrace();   }  }  @Test  public static void test02() {//Test xml string conversion object   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: Start the service



public class MyServer {



 



      public
static void main(String[] args) {



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



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



      }



 



}



Enter in the address bar of the browser;  http://localhost:8888/ns?wsdl , and see the xml file appear on the page.



(2) Client establishment:



public class TestClient {



      public
static void main(String[] args) {



           try
{



Create a url to access the wsdl service address



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



      Specify the specific information of the service through qname



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



      create service



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



                                                 implement the interface



                 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>

type of 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 tricks

1 Javascript array conversion to CSV format


First consider the following application scenario, there is a Javscript character (or numeric) array, and now it needs to be converted into a comma-separated CSV format file. Then we can use the following tricks, the code is as follows:

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

 


Output: apples, peaches, oranges, mangoes


Among them, the valueOf() method will convert the Javascript array into a string separated by commas. It should be noted that if you do not want to use commas to separate, for example, use | to separate, please use the join method, as follows:

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

Output: apple|peaches|oranges|mangoes


2 Reconvert CSV format back to Javscript array


So how do you convert a CSV-formatted string back into a Javascript array? You can use the split() method, you can use any specified character to separate, the code is as follows:

   
   
    
    
  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 Select all and not select all in Listbox


For the specified listbox, the following method can pass in true or false according to the needs of the user, representing whether to select all items in the listbox or not to select all items, the code is as follows:

   
   
    
    
  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 Up and down movement of items in Listbox

The following code shows how to move items up and down in a 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 Remove duplicate elements in Javscript array

The following code can remove duplicate elements in the Javascript array, as follows:

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

 

19 Remove extra spaces in String

The following code will add a trim() method to String, the code is as follows:

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

 

20 Redirects in Javascript

In Javascript, redirection can be implemented as follows:

   
   
    
    
  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 many-to-many query hql statement

Tasks and contacts are in a many-to-many relationship. Now query all related tasks by contact id
"SELECT t from Task t join t.contacts c where c.id = ?1"

For example:

One teacher teaches many students, one student is taught by many teachers, one student has many books, and the same book is owned by many classmates. 
To query the teacher who teaches the student who has book "a"!

Hql statement:

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

Explanation: The s in t.students s does not mean a set, but the table alias of the students object of t. The hql of join t.students s will be translated into the inner connection relationship of the two tables by hibernate

Wrong way:

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];//Get the array of all forms in the page   alert(form);   var form = document.fm1;//Get it according to the form name attribute array
  //var form = document.forms['fm1'];//Get the array according to the form name attribute


  </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();//Prevent the event from happening
    }
    }
    document.getElementById('btn').onclick = function(event){
    //alert(1);
    event.stopPropagation(); //Prevent propagation of events
    
    }
    document.body.onclick=function(){
    //alert(2);
    }
  </script>
 </body>
</html>
In 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 bubbling event and capturing event

JavaScript  events exist in the form of a stream, and multiple elements respond to an event at the same time. Sometimes this is not what we want, we just need a specific element to respond to our binding events. 

Event classification
Capturing events (non- IE ), bubbling events (supported by all browsers)
Capturing events are top-down, while bubbling events are bottom-up. Below I use a diagram to visually represent:



We may encounter more bubbling events in our work, but how can capture events be executed? If we want to create capture events in non-  IE  browsers, we only need to add  the third of addEventListener  Just set the parameter to true .


The third parameter false means to run when bubbling, and true means to run when capturing.

The two elements with IDs div1 and div2 are bound to the event handling function of the capture phase, so:

When clicking # div1 (blue area), it should alert "div1"  . When clicking #div2 (yellow area), it should alert "div1" first , and then alert "div2" , because in the event capture phase , The event is propagated downward from the root element, #div1 is the parent element of #div2 , and the click event bound to #div1 will also be executed before the click event on #div2 .

<!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 manipulation css

In the javascript operation css , if the css attribute is such as background-color with a horizontal line in the middle, the javascript operation must follow the camel case naming method, such as 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) { // exchange data through temporary variables
      int tmp = a[i];
      a[i] = a[j];
      a[j] = tmp;
    } // first exchange analysis
    public static void quicksort(int a[], int low, int high) { // assumption Pass in low=0; high=a.length-1;
      if (low < high) { // conditional judgment
       int pivot, p_pos, i; // declare variable
          p_pos = low; // p_pos points to low, that is, the bit index is 0 Location;
          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

In the design of the java language I/O library, two structural patterns are used, namely the decoration pattern and the adapter pattern.
      In any computer language, input/output is a very important part. Compared with general computer languages, java has greatly expanded the functions and scope of input/output. Therefore, input and output occupy an extremely important position in the java language.
      The Java language uses a stream mechanism to implement input/output. The so-called stream is the orderly arrangement of data. The stream can come from a certain source (called the source of stream, or Source of Stream) and go to a certain destination (Sink of Stream). Depending on the direction of the flow, the flow can be divided into an output flow and an input flow. A program reads data from an input stream and writes data to an output stream.
     For example: A java program can use the FileInputStream class to read data from a disk file, as shown in the figure below:       Processors like FileInputStream are called stream processors. A stream processor is like a stream pipeline, ingesting some type of data from a stream source and outputting some type of data. The above diagram is called the pipeline diagram of the flow.      Similarly, you can also use the FileOutputStream class to write data to a disk file, as shown in the figure below:      In practical applications, such a simple mechanism is not very useful. What the program needs to write is often very structured information, so these Byte type data are actually some numbers, text, source code, etc. Java's I/O library provides a mechanism called Chaining, which can connect one stream processor to another stream processor end to end, and use the output of one of them as input to form a link of a stream pipeline.

                                      




                                           



      例如,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代表的等级结构内部,有一些流处理器是对其他类型的流处理器的适配。这就是适配器的应用。



装饰模式的应用


      The most famous application of the decoration pattern in java is the design of the java I/O standard library.

      Because the java I/O library requires various combinations of many functions, if these functions are implemented by inheritance, then each combination requires a class, which will cause a large number of classes with repeated lines. If the decoration mode is used, the number of classes will be greatly reduced, and the duplication of performance can be minimized. Therefore, the decoration pattern is the basic pattern of the java I/O library.

      The introduction of the decorator pattern resulted in increased flexibility and complexity. Therefore, when using the java I/O library, it must be understood that the java I/O library is composed of some basic primitive stream processors and decorative stream processors around them.

Decorator pattern in InputStream type

       InputStream has seven direct concrete subclasses, and four concrete subclasses belong to FilterInputStream, as shown in the figure below:       All the classes in the above figure are called stream processors, and this figure is called (InputStream type) stream processor diagram. Depending on the type of source of the input streams, these streams can be classified into two types, primitive stream classes and linked stream processors.

               



raw stream processor


      原始流处理器接收一个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流处理器仍属于原始流处理器。 


抽象结构图

          


     The stream processor diagram above has obvious similarities with the structure diagram of the decoration mode. In fact the stream processor structure of type InputStream does conform to the decorator pattern, and this can be discerned from the role they play in the structure.



The various roles of the decoration mode


      在所有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 role: played by CharArrayReader, InputStreamReader, PiPedReader, StringReader, etc., they all implement the interface declared by Reader.
     (3) Abstract decoration (Decorator) role: played by BufferedReader and FilterReader. These two have the same interface as Reader, and they respectively give the hierarchical structure of two decoration roles, the first one gives LineNumberReader as the concrete decoration role, and the other gives PushbackReader as the concrete decoration role.
     (4) Concrete Decorator role: LineNumberReader is the concrete decoration role of BufferedReader, and BufferedReader is the concrete decoration role of FilterReader.
       As shown in the figure below, the abstract decoration role is marked with an aggregation line:
      
   

Decorator pattern in Writer type

       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 adapts a Char array to an input stream of Reader type, so it is an adapter application in the form of an object, as shown in the figure below:       StringReader is an adapter class       StringReader inherits the Reader type and holds a reference to the String type. It adapts the String interface to the Reader type interface, as shown in the figure below:       Adapter mode in the Writer type       The original stream processor in the Writer type is the specific application of the adapter mode.       CharArrayWriter is an adapter class.       CharArrayWriter adapts a Char array to a Writer interface, as shown in the figure below:       PipedWriter is an adapter class       PipedWriter is always used with PiPedReader, it adapts the interface of a PipedReader object into a Writer type interface, as shown in the figure below:        StringWriter is an adapter class.        StringWriter inherits the Writer type and holds a StringBuffer object at the same time. It adapts the interface of the StringBuffer object into a Writer type interface. It is an application of the adapter mode in the form of an object, as shown in the following figure:
                              


                        
        




                                            


                             



                                    
       

      Adaptation from byte stream to char stream

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

     InputStreamReader

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

poi读取excel

package com.scpii.ent.util;

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

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

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

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

 public static void readExcelJXL() {

 }

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

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

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

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

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

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

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


package com.scpii.ent.mode.bean;

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

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

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

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

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

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

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

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

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

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

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

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

 

jquery对象和javascript的dom对象转换

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

Jquery objects and dom objects can be converted to each other, because the objects they operate are all dom elements, but the jquery object contains multiple dom elements, and the dom object itself is a dom element. Simply put, the jquery object is dom An array of elements is called a class array, and a dom object is a single dom element.

1. Convert jquery object to dom object

(1) Use the array subscript to read a dom element object in the jquery object collection .

Var $li = $('li');//jquery object

Var li = $li[0];//dom object

(2) With the help of the get() method of the jquery object

Var $li = $('li');//jquery object

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

2. Dom object is converted to jquery object

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

Var $li = $(li[o]);// Encapsulate the first div element as a jquery object

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

Var $li = $(li);// Encapsulate all div elements as jquery objects

The Load event must wait until all the content in the web page is loaded before executing.

When there is a lot of content in the webpage, the load event will be delayed

Jquery 's ready event is executed after the dom structure is drawn, that is to say, it is executed before the external file is loaded, and the ready event precedes the load event.

The Load event can only be written once, but the ready event can be defined multiple times in the same document.

<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">
        //Inherited object impersonation method, can inherit multiple parent classes
            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();
            
            
            //prototype chain Ways to achieve inheritance
            //1. Put the properties or methods set by the prototype used in the parent class into the subclass
            //2. And override all the prototype settings in the subclass
            //3. So all the prototypes of the subclass itself The setting should be placed under the inherited parent class
            //4. The disadvantage is that multiple inheritance is not supported, and the constructor cannot have parameters
            
            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 simulates the StringBuffer connection string in java

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

Five ways to create objects in javascript object-oriented

<html>
    <head>
    
    </head>
    <body>
        <script type="text/javascript">
        //The factory mode creates objects, the disadvantage is that you can't know the type of the object
            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();
            
            //constructor + prototype mode, construction method construction property, Prototype mode construction method
            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 note 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)) ;   //The first type of closure    function test(){     var num = 10;     function inner(){      alert(num);     }     inner();    }    //test();    //The second type of closure    function add( n1,n2){     return function(){      return n1+n2;     }    }   //alert(add(2,3)());   </script>  </head> </html>





   



















 
 

The method of adding, deleting, modifying and checking 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("The operation is successful!");
  }
  
  //5. Release the connection
  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;   
/**  
*Get information about the constructor of the specified class  
*/   
public class ConstructorTest    
{   
 private int i;   
 private double j;   
 //The default constructor   
 public ConstructorTest (){   
 }   
 //Overloaded constructor   
 public ConstructorTest(int i,double j)throws IOException{   
  this.i=i;   
  this.j=j;   
 }   
 public static void main(String[] args) throws Exception   
 {   
  / /Get the class object of this class   
  Class<?> cls=Class.forName("com.fanshe.obj.ConstructorTest");   
  //Get all the constructors declared in this class   
  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.*;   
/**  
*Create new objects of class through reflection  
*/   
class CreateNewObj    
{   
 //Explicit default constructor   
 public CreateNewObj(){   
 }   
 //Overload constructor   
 public CreateNewObj(int a ,int b){   
  System.out.println("a= "+a+" b="+b);   
 }   
  
 public static void main(String[] args) throws Exception   
 {   
  //Get the class object of this class   
  Class<? > c=Class.forName("com.fanshe.obj.CreateNewObj");   
  //declare the parameter type set of the constructor   
  Class<?> []paramTypes=new Class[2];   
  //all are int type   
  paramTypes[0 ]=Integer.TYPE;   
  paramTypes[1]=Integer.TYPE;   
        //Determine which constructor to get according to the parameter 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.*;   
/**  
*Create and use more complex arrays through reflection  
*/   
class UserArrayComplex   
{   
 public static void main(String[] args) throws Exception   
 {   
  //declare the dimension of the array is 5X10X15   
  int dims[]=new int []{5,10,15};   
  //Create an array of this type, the element type is Integer   
  Object arr=Array.newInstance(Integer.TYPE,dims);   
  //Get the third 10X15 Two-dimensional array   
  Object arrObj=Array.get(arr,3);   
  //Class c=arrObj.getClass().getComponentType();   
  //System.out.println(c);   
  //Get the second dimension The second 15-bit array   
  arrObj=Array.get(arrObj,5);   
        //Then set the value of the 10th element in the array to 37   
  Array.set(arrObj,10,37);   
  //Then set the array reduction   
  int [][][]arrCast=(int [][][])arr;   
  //Print the value just now   
  System.out.println(arrCast[3][5][10]);   
     
 }   
}  

 

Facade pattern of design pattern

Facade mode is the structural mode of the object, and the communication between the outside and a subsystem must be carried out through a unified facade object. The Facade pattern provides a high-level interface that makes the subsystem easier to use.
A side benefit of using the facade pattern is the ability to selectively expose methods. The method defined in a module can be divided into two parts, one part is used outside the subsystem, and the other part is used when the internal modules of the subsystem call each other. With the Facade class, the methods used to call each other between the internal modules of the subsystem do not need to be exposed to the outside of the subsystem.
public interface ServiceA {
 void methodA() ;
}

public class ServiceAImpl implements ServiceA{

 @Override
 public void methodA() {   System.out.println("This is service A");    } }



public interface ServiceB {
 void methodB() ;
}

public class ServiceBImpl implements ServiceB{

 @Override
 public void methodB() {    System.out.println("This is service B");    } }




public interface ServiceC {
 void methodC() ;
}


public class ServiceCImpl implements ServiceC{

 @Override
 public void methodC() {    System.out.println("This is service 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)
  Hardware management information system source code (18M)
  network classroom system source code (network version) source code (58M)
  Tianmou ERP system source code (281M)
  hospital medical records management system source code (26M)
  VOD song system source code (59M)
  foreign financial software source code ( 126M)
  Tourism company information system source code (43M)
  Human resource management system source code (24M)
  POS supermarket management system source code (60M)
  POS system source code (43M)
  Hospital charging and information management system source code (122M)
  Anmou sales system source code (10M)
  GIS system - cable TV network equipment management system source code (30M)
  ICQ (customer service server) source code (55M)
  office automation system source code source code (27M)
  warehousing logistics information management system source code (137M)
  legendary game source code (178M)
  energy meter carrier copy Table soft source code (44M)
  electronic test paper generation system source code (30M)
  beauty salon management system source code (16M)
  Thai project management software source code (40M)
  ring beauty salon management system source code (23M)
  computer room charge management source code (78M)
  family planning Management system source code (21M)
  Driver test source code (40M)
  Jin cloth inspection system source code (82M)
  Invoicing system source code (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)
  Huasi Trade Domestic Sales Management System (30M)
  Hot Pot City Management System Version 1.0 (10M)
  Motor Vehicle Driver Paperless Theory Examination System (38M)
  Local Area Network Instant Messaging System (52M)
  Guest Room Management System (Online Version) (100M)
  Clients Relationship Management System (CRM) (11M)
  Lixin Consumption Management System 2000 (12M)
  Longbang Invoicing Source Code (16M)
  Beauty Salon Management System Revised Version (ADO) (21M)
  A Company Salary Management System (17M)
  An Enterprise ERP Enterprise management system (32M)
  A general purchase, sales and storage system (20M)
  Parts warehouse management (24M)
  Enterprise management Erp (commercial source code) (64M)
  Global digital warehouse warehouse management information system (110M)
  Sunnet (sunnet) property management information System (232M)
  An ERP management system made by a Taiwan company (235M)
  Wanjiayuan hotel sauna bathing management system (20M)
  Network marketing expert (25M)
  Maintenance management tool (15M)
  Hardware material commercial purchase, sales and inventory (23M)
  Property management ( 22M)
  Campus Network Multimedia Automatic Playing System (10M)
  Xinyi VOD System (59M)
  Glasses Industry Financial Invoicing Background Management Code V1.0v (72M)
  Yizhou hotel (catering) management system delphi source code (delphi+sql) (20M)
  P2P instant messaging source code Delphi (46M)
  POS consumption management system 2000delhi source code (12M)
  large supermarket sales chain management system (16M)
  electronic change source program delphi (20M)
  Remote Control DELPHI Source Code (17M)
  College Entrance Examination Online Enrollment Provincial Recruitment and File System (11M)
  Hunan Jiamou Software Company Commercial POS System Delphi Source Code (98M)
  Chemical Pigment Production Management Source Code (30M)
  Science and Technology Plan Information Management System delphi Source code (22M)
  Video conferencing system delphi source code(45M)
  A hospital HIS management system delphi source code(86M)
  Shun certain fingerprint attendance management system delphi source code(64M)
  Delphi supermarket management system source code(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>[email protected]</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?

Theoretically, maxActive should be set to the maximum concurrency of the application, so that even under the maximum concurrency, the application can still obtain connections from the connection pool, but the difficulty is that it is difficult for us to accurately estimate the maximum concurrency. Setting it to the maximum number of concurrency is an optimal quality of service guarantee. In fact, if a user logs in to indicate that the system is busy, then when he logs in again, the system resources may be sufficient. We recommend setting maxActive Set between one-tenth and one-twentieth of the number of system registrants. For example, if the number of registered users in the system is 1000, then set it to 50-100 close to 100, such as 85 or 90.

The connection corresponding to maxIdle is actually a long connection kept by the connection pool, which is also the part where the connection pool takes advantage. In theory, more long connections can be kept, which can respond faster when application requests are made, but too many connections are kept , but it will consume a lot of resources in the database, so maxIdle is not as big as possible. In the same example as above, we recommend setting maxIdle to

A number close to 50 in the range of 50-100, such as 55. In this way, fewer database connections can be maintained while taking into account the maximum concurrency, and in most cases, the fastest response speed can be provided for the application.

testOnBorrow="true"

validationQuery="selectcount(*) from bt_user"

我们知道数据库连接从本质上架构在tcp/ip连接之上,一般情况下web服务器与数据库服务器都不在同一台物理机器上,而是通过网络进行连接,那 么当建立数据库连接池的机器与数据库服务器自己出现网络异常时,保持在连接池中的连接将失效,不能够在次使用,传统的情况下只能通过重新启动,再次建立连 接,通过设置以上两个参数,但应用程序从连接池中获取连接时,会首先进行活动性检测,当获取的连接是活动的时候才会给应用程序使用,如果连接失效,连接将 释放该连接。validationQuery是一条测试语句,没有实际意义,现实中,一般用一条最为简单的查询语句充当。

removeAbandoned="true"

removeAbandonedTimeout="60"

logAbandoned="true"

Sometimes careless programmers forget to close the connection after obtaining the connection from the connection pool, so that the connection pool will gradually reach maxActive until the connection pool cannot provide services. Modern connection pools generally provide a "smart" check, but when removeAbandoned ="true" is set , when the number of connections in the connection pool reaches (getNumIdle() < 2) and (getNumActive() > getMaxActive() - 3) Connection recycling will be started, and the connection whose activity time exceeds removeAbandonedTimeout="60" will be recycled. At the same time, if logAbandoned="true" is set to true, the program will print the log while recycling the connection. removeAbandoned is an advanced function of the connection pool. In theory, this configuration should not appear in the actual production environment, because sometimes the application executes long transactions. In this case, it may be mistakenly recycled by the connection pool. This configuration is generally used in program testing. stage, in order to locate the specific code location of the connection leak, it is opened, and the closing of the connection in the production environment should be guaranteed by the program itself.

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,还愁数据取不到吗。
  Note: The initial understanding of ValueStack as a map is only suitable for beginners of struts2. In fact, it is not so simple inside. Due to the limited level and time, I can't grasp its internal essence, coupled with my poor expression ability, I am afraid that the expression will mislead everyone, so let's understand ValueStack as a map. If you want a deeper understanding of ValueStack, please check the source code of struts2.

  Next, is to fetch data. Getting the attribute data of the action instance is different from getting the data in the ValueStack. Let’s talk about getting the attribute data of the action instance first.
  The attribute data of the action instance can be obtained directly through the attribute name in the struts2 tag. Such as: <s:property value="name"/>, <s:property value="user.password"/>
  Note: Do not add #.

  Then take the data in ValueStack.
  Struts2 provides three ways to get data in ValueStack through ognl expressions: #, %{}, ${}
  # and %{} need to be placed in the tags provided by struts2 to take effect. Such as: <s:property value="#name"/>, <s:property value="%{'hello struts2'}"/> 1. The
  most commonly used method is: #
  1.# can take request, session, application The attribute in , but needs to be prefixed. Such as: <s:property value="#session.name2"/>, <s:property value="#application.name3"/>. If the attribute in the request range is taken, then there is no need to add the request prefix, and the data cannot be fetched instead. Ognl fetches it from the request by default. If it is not fetched, it will not fetch it from the session or application. Such as: <s:property value="#name"/>
  2. # can get the request parameters in the request, but must add parameters prefix, and get an array, so if you want to get the first value of the parameter, Then add the subscript. Such as: <s:property value="#parameters.name[0]"/>. This is equivalent to calling 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

    Driver: oracle.jdbc.driver.OracleDriver
    URL: jdbc:oracle:thin:@<machine_name><:port>:dbname
    Note: machine_name: the name of the machine where the database is located, if it is local it is 127.0.0.1 or localhost , if it is a remote connection, it is the remote IP address;    

     port: port number, the default is 1521


Two: SQL Server

    Driver: com.microsoft.jdbc.sqlserver.SQLServerDriver
    URL: jdbc:microsoft:sqlserver://<machine_name><:port>;DatabaseName=<dbname>
    Note: machine_name: the name of the machine where the database is located, if it is local It is 127.0.0.1 or localhost, if it is a remote connection, it is the remote IP address;          
     port: port number, the default is 1433

 

Three: MySQL

    Driver: org.gjt.mm.mysql.Driver
    URL: jdbc:mysql://<machine_name><:port>/dbname
    Note: machine_name: the name of the machine where the database is located, if it is local, it is 127.0.0.1 or localhost, if it is a remote connection, it is the remote IP address;          
     port: port number, default 3306  

        
 Four: point base

    Driver: com.pointbase.jdbc.jdbcUniversalDriver
    URL: jdbc:pointbase:server://<machine_name><:port>/dbname
    Note: machine_name: the name of the machine where the database is located, if it is local, it is 127.0.0.1 or localhost, if it is a remote connection, it is the remote IP address;
     port: port number, the default is 9092


 Five: DB2

    Driver: com.ibm.db2.jdbc.app.DB2Driver
    URL: jdbc:db2://<machine_name><:port>/dbname
    Note: machine_name: the name of the machine where the database is located, if it is the machine, it is 127.0.0.1 Or localhost, if it is a remote connection, it is the remote IP address;
     port: port number, the default is 5000

js function

1. Function overview

   Functions in javascript are different from other languages, each function is maintained and executed as an object. Through the nature of the function object, it is very convenient to assign a function to a variable or pass the function as a parameter.

   Function objects are essentially different from other user-defined objects, and this type of object is called an internal object. Constructors for built-in objects are defined by JavaScript itself.

Second, the creation of function objects

In JavaScript, the type corresponding to a function object is Function, and a function object can be created through new Function(), or an object can be created through the function keyword.

    //Use new Function() to create

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

   This code will display the value of the variable i equal to 3. i is to indicate the returned value, not the created function, because the brackets "(" have a higher priority than the equal sign "=".

3. The difference between anonymous functions and named functions

   Anonymous functions must be defined first and then called, and named functions can be called first and then defined.

A) Anonymous (this statement will generate func undefined error)

   <script>

      func();

      var func = function() {

        alert(1);

      }

   < /script>

B) Famous (output 1)

   <script>

      func();

       function func() {

        alert(1);

      }

   < /script>

This is because the JS interpreter executes segment analysis. And, in the same section, well-known functions will be analyzed first. And the function with the same name behind overrides the previous one.

Also, the following code is legal:

<script>

function myfunc ()
    {         alert("hello");     };     myfunc(); //call myfunc here, output yeah instead of hello     function myfunc ()     {         alert("yeah");     };        myfunc(); //here call myfunc, output yeah



   




</script>

If you want the first invocation of the above code to output "hello", you can break them into two pieces:

<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);
//Upload files
mySmartUpload.upload();
//Loop to get all uploaded files
for(int i=0; i<mySmartUpload.getFiles().getCount(); i++)
{ //Get uploaded File com.jspsmart.upload.File file = mySmartUpload.getFiles().getFile(i); if(!file.isMissing()) { fileName = file.getFileName(); //Get file extension 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){
}


The above is the way of jspsmart, if you want other ways, please download all the source code.



//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; //The file name stored locally
 String filePath = null; //The file path stored locally
 String savePath = null; //The file path stored in the database
 long fileSize = 0; //File size
 int maxPostSize = -1;    
 int dinfo_upload_id = -1;
%>
<%
    DiskFileUpload df = new DiskFileUpload();
    //Set upload file size
 df.setSizeMax(maxPostSize);
 //Set temporary directory
 df.setRepositoryPath(sitePhysicalPath + tempDir) ;
    //Get request information
 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;              }             //Get file extension             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{ //Get the session user oid     int pid = userInfo.getUserId();     String sys_user_id = String.valueOf(pid); //Get the parameter value of the init configuration file  String sitePhysicalPath = (String)init.getObject("SitePhysicalPath") ;  String saveDir = (String)init.getObject("InfoUploadDir");  String tempDir = (String)init.getObject("InfoUploadDir");  String fileMemo = ""; //File Description  String fileName = null; //Save to The file name of the database  String saveName = null; //The file name stored locally  String filePath = null; //The file path stored in the database  String savePath = null; //The file path stored locally  long fileSize = 0; // file size  int maxPostSize = -1;      int dinfo_upload_id = -1; %> <%  //initialization


















 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

  Introduction to the three XML parsing methods

  The famous DOM

  It is not an exaggeration to say that it is famous. DOM is the standard API of W3C for XML processing. It is the basis of many other standards related to XML processing. Not only Java, but other languages ​​such as Javascript, PHP, MS .NET, etc. are implemented This standard has become the most widely used XML processing method. Of course, in order to provide more and more powerful functions, Java has many tools for directly extending DOM, such as JDOM, DOM4J, etc., which are familiar to many Java programmers. They basically belong to the expansion of DOM interface functions and retain a lot of DOM Due to the characteristics of the API, many original DOM programmers have mastered the use of the other two without any obstacles. The intuitive and easy-to-operate method makes it popular among Java programmers.

  Green SAX

  The emergence of SAX has its special needs. Why is it called green? This is because SAX uses the least system resources and the fastest parsing method to provide support for XML processing. But the ensuing cumbersome search method also brings a lot of troubles to the majority of programmers, and it is often a headache. At the same time, its support for XPath query function makes people love and hate it.

  Obscure Digester: JavaBeanization of XML

  Digester is an open source project under the apache foundation organization. The author's understanding of it comes from the research on the Struts framework. Are there many programmers who want to understand the design of major open source frameworks or even write a powerful framework by themselves? You will encounter such a difficult problem: What technology is used to parse the various framework configuration files marked with XML language? DOM parsing is time-consuming, SAX parsing is too cumbersome, and the system overhead for each parsing will be too large. Therefore, everyone thought that JavaBean corresponding to the XML structure should be used to load the information, so Digester came into being. Its appearance brings a convenient operation interface for the requirement of converting XML into JavaBean objects, and makes more perfect solutions for more similar requirements, and programmers no longer need to implement such cumbersome parsing programs by themselves. At the same time, SUN also launched JAXB, an XML and JavaBean conversion tool class, interested readers can learn by themselves.

  Comparison of three analysis methods

  DOM

  Advantages and disadvantages: implement the W3C standard, there are many programming languages ​​that support this analysis method, and this method itself is simple and quick to operate, very easy for beginners to master. Its processing method is to read the entire XML into memory as a tree-like structure for operation and analysis, so it supports applications to modify the content and structure of XML data, but at the same time, because it needs to read the entire XML file at the beginning of processing Into memory for analysis, so when parsing XML files with a large amount of data, it will encounter risks similar to memory leaks and program crashes, please pay more attention to this point.

  Scope of application: parsing of small XML files, requiring full parsing or most parsing of XML, needing to modify the content of the XML tree to generate its own object model

  SAX

  SAX fundamentally solves the problem that DOM consumes a lot of resources when parsing XML documents. Its implementation is to read through the entire XML document tree through a technology similar to stream parsing, and respond to programmers' needs for XML data parsing through event handlers. Because it does not need to read the entire XML document into the memory, it saves system resources very obviously, and it plays a very important role in some occasions that need to process large XML documents and have high performance requirements. SAX, which supports XPath query, makes developers more flexible and more handy when dealing with XML. But at the same time, it still has some deficiencies that bother the majority of developers: firstly, its very complex API interface is daunting, and secondly, because it belongs to the file scanning method similar to stream analysis, it does not support applications for XML trees. There may be inconvenience due to modification of the content structure, etc.

  Scope of application: large XML file parsing, only partial parsing or only part of the XML tree content, XPath query requirements, and the need to generate a specific XML tree object model

  Digester/JAXB

  Advantages and disadvantages: Since it is a tool class derived from the above two, in order to meet the special needs of converting XML to JavaBean, there are no particularly obvious advantages and disadvantages. Digester, the XML parsing tool of the famous open source framework Struts, brings us a reliable way to convert XML into JavaBean.

  Scope of application: There is a need to convert XML documents directly into JavaBean.

  Application example

  Here's an XML fragment for parsing:
  Listing 1. XML fragment

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

  In the above example, the Parse() method of DOMParser is responsible for parsing the XML file and generating the corresponding DOM Document object. Among them, DocumentBuilderFactory is used to generate a DOM document parser for parsing XML documents. After obtaining the Document object corresponding to the XML file, we can call a series of APIs to conveniently access and process the elements in the document object model. It should be noted that when the getChildNodes() method of the Element object is called, all child nodes under it will be returned, including blank nodes, so it is necessary to judge the node type before processing the child Element.

  It can be seen that DOM parsing XML is easy to develop, only need to establish the DOM tree structure corresponding to XML through the parser, then you can conveniently use API to access and process nodes, and support node deletion and modification. However, when DOM parses an XML file, it parses the content of the entire XML file into a tree structure and stores it in memory, so it is not suitable for parsing a large XML file with DOM.

  SAX parsing XML

  Different from the way DOM builds a tree structure, SAX uses an event model to parse XML documents, which is a faster and lighter-weight method for parsing XML documents. With SAX, XML documents can be selectively parsed and accessed without having to load the entire document like DOM, so it has lower memory requirements. However, SAX parses the XML document for one-time reading without creating any document object, so it is difficult to access multiple data in the document at the same time.

  Here's an example of SAX parsing XML:
  Listing 3. SAX parsing 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());     }   } 

  The SAX parser interface and event handler interface are defined in the org.xml.sax package. The main interfaces include ContentHandler, DTDHandler, EntityResolver and ErrorHandler. Among them, ContentHandler is the main processor interface, which is used to handle basic document parsing events; DTDHandler and EntityResolver interfaces are used to handle events related to DTD verification and entity resolution; ErrorHandler is a basic error handling interface. The DefaultHandler class implements the above four event handling interfaces. In the above example, BookHandler inherits the DefaultHandler class, and overrides the five callback methods startDocument(), endDocument(), startElement(), endElement() and characters() to add its own event processing logic.

  Digester parsing XML

  In order to meet the special needs of converting XML to JavaBean, a tool called Digester under Apache provides us with such a choice. Since the final XML is converted into JavaBean and stored in the memory, the parsing performance and other aspects actually have little to do with the user. The key to parsing lies in the patterns and rules used to match XML. Due to the complexity of the tool and limited space, the author can only give a brief introduction.

  Here is an example snippet of Digester parsing XML:
  Listing 4. Digester parsing XML

// Define the path of the XML to be parsed, and initialize the tool class File input = new File("books.xml"); Digester digester = new Digester(); // If you encounter the <books> tag, you should initialize the test. myBean.Books JavaBean and fill related content digester.addObjectCreate("books", "test.myBean.Books"); digester.addSetProperties("books"); // If you encounter the tag <books/book>, ditto Initialize test.myBean.Book this JavaBean digester.addObjectCreate("books/book", "test.myBean.Book"); digester.addSetProperties("books/book"); // By calling addBook of the JavaBean that has been initialized above () method to add multiple <books/book> to a collection digester.addSetNext("books/book", "addBook", "test.myBean.Book"); // After defining the above parsing rules , you can start parsing 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前端开发的范畴(当然,这个定义很狭隘,下文会提到)。

  After 2000, browser technology gradually matured, and Web products became more and more abundant. A large number of young people in China began to use the Internet. Attracted by the rich content in the browser window, our thinking mode has been limited to a small window from the beginning, so that for a long time we have considered "vision" as a "function", and Web products are nothing more than Used to display information. The initial entrants, without exception, pay more attention to "visual" than "content". First, let the page look beautiful, pay attention to html/css, and continue to deepen along the idea of ​​"visual presentation". Therefore, this kind of people are attracted by "vision", start from cutting pages, are fascinated by structured html and neatly written css, like simple and elegant UI and neat page design, and then start to touch visual effects and use jQuery To achieve visual effects, use this as a clue to start in-depth research on the rendering mechanism of Dom, Bom, and browsers. HTML/CSS is like an offensive weapon in the hands of these people, while JavaScript is more like a defensive shield.

  There is another group of people who come into contact with the Web front-end from another path, that is, engineers switch to the front-end. They have more background in background language development. They start from reading and writing data, and gradually touch the browser side, and come into contact with JavaScript libraries. At first, they are in HTML code Added js logic, and later began to involve html and css, they like OO, clear logic, and pleasing structure code, and pay more attention to the "program language" and data logic behind the interface. HTML/css is more like a shield in the hands of these people, while JavaScript is more like an offensive weapon.

  It should be said that these two types of people are complementary. They each understand part of the essence of the browser. One group of people knows the rendering engine well, and the other group of people regards the JS engine as a treasure. In fact, any part of the advantages can be used to make Boutique. Most front-end engineers can find their own shadows from these two sources. However, the thinking patterns and viewpoints of these two types of people are so different that some unnecessary confrontations have been formed. of". This seems to clarify the division of labor and improve efficiency, but it will cause great harm to the career development of employees. There will be further discussions on the second day of "Scholars from the Class".

  I should belong to the second category, that is, I learned C/Java and C# seriously at school, thinking that I could do ERP software, desktop software or enter some communication companies to write TCP/IP related programs after graduating from university. I chose China Yahoo when recruiting on campus, because Yahoo was still a bit famous back then (2008), and I heard that Yahoo was considered a relatively technical company... Since then, it has been on the bandit ship and it has been out of control.

  During my time at Yahoo, I was fortunate to come into contact with an upright technical school, and also formed some basic views on front-end technology, which have influenced me to this day.

  【Elegant academic school】

  At that time, Yahoo’s technical genre was in full swing, with many "father"-level experts, and the Hack atmosphere created was really intoxicating. During that time, I even preferred to work overtime until late at night to read massive documents and source codes. I feel really comfortable. I was deeply moved by the low-key, pragmatic, and meticulously crafted "service spirit" of Yahoo engineers, and this humble and excellent quality greatly affects the user experience and high quality of Yahoo products. technical output. So, what is the "spirit of service"? That is, what you do serves people, either product customers, people who take over your project, or people who use the functions you develop, so technical documentation becomes the standard configuration accompanying the code. Therefore, engineers can communicate with each other through code. This is a basic quality of an engineer, that is, to complete the project with clear thinking and equipped with valuable technical documents, especially if your program is for other programmers, just like you make a home appliance All come with an instruction manual. Therefore, YDN became the most popular technical documentation library for programmers all over the world at that time. This elegant and pragmatic "academic atmosphere" makes people feel uniquely charming.

  让人感觉奇怪的是,在中文社区始终未见这种学院派。甚至在具有先天开源优势的Web前端技术社区里也是波澜不惊,可见写一篇好的技术文案真的比 登天还难。我所见到的大部分所谓文档索性把代码里输出数据的语句块拷贝粘贴出来,至于为什么数据格式要设计成这样、如果字段有修改怎么做、编码解码要求如 何等等关键信息只字不提,或者开发者也没想过这些问题呢。因此,我们一直在强调代码的质量和可维护性,但一直以来都未见效,盖源于缺少这种“服务”意识的 灌输。这种意识在下文中还会多次提到,因为它能影响你做事的每个细节,是最应当首先突破的思想纠结。

  除了意识问题,另一方面是技术问题,即文笔。这也是工程师最瞧不上眼的问题,难以置信这竟然是阻碍工程师突破瓶颈的关键所在。我已看到过数不清 的人在晋升这道关卡吃了大亏,很多工程师技术实力很强,但就是表达不出来,要么罗列一大堆信息毫无重点、要么毫无趣味的讲代码细节,不知云云。除非你走狗 屎运碰到一个懂技术的老板,否则真的没办法逃脱码农的宿命。但大部分人还振振有词不以为然。而在Web前端开发领域情况更甚。前端工程师是最喜欢搞重构 的,但在快节奏的需求面前,你很难用“提高了可维护性”、“提升了性能”这类虚无缥缈的词藻为自己争取到时间来搞重构,说的露骨一点,可能你真的对某次重 构带来的实际价值无法量化,只是“感觉代码更整洁了”而已。我会在下文的“伪架构”中会展开分析前端工程师的这种浮躁献媚的技术情结。而这正是前端工程师 最欠缺的素质之一:用数据说话,用严谨科学的论据来支撑你的观点,老板不傻,有价值的东西当然会让你去做。

  当然,情况不总是这么糟糕,我们看到中文社区中已经锻炼出了很多写手,他们在用高质量的文字推销自己的技术理念,这是一个好兆头,好的文笔是可 以锻炼出来的。而在职场,特别是对前端工程师这个特殊职位来讲,这种基本技能可以帮你反思梳理需求的轻重缓急,从凌乱的需求中把握七寸所在。因为当你开始 认真写一封邮件的时候,这种思考已经包含其中了。

  所以,雅虎技术的推销是相对成功和远播的。关键在于两方面,扎实的技术功底和高超的写手。而真正的技术大牛一定是集两者与一身,不仅钻研剑道,还能产出秘籍。这也是Yahoo!优雅的学院派气息的动力源泉。国内很多技术团体想在这方面有所建树,应当首先想清楚这一点。

  【规范的破与立 1】

  雅虎的技术运作非常规范,刚才已经提到,包括技术、组织、文化,一切看起来有模有样,也堪称标杆,自然成了国内很多技术团队和社区的效仿对象。一时间各种“规范“成风、各色“标准“大行其道,结果是质量参差不齐。

  我们到底需要什么样的规范?雅虎的技术规范到底有何种魔力?以何种思路构建的规范才是货真价实的?规范有着怎样的生命周期?想清楚这些问题,能很大程度减轻很多Web前端工程师的思想负担,看清一部分技术本质,避免盲目跟风。

  我们的确需要规范,但好的规范一定是务实的,一定是“解决问题“的。比如针对项目构建的DPL可以收纳公用的视觉元件以减少重复开发、规定某 OPOA项目的事件分发原则以确立增量开发的代码惯性。反之,糟糕的规范却显得过于“抽象“,比如页面性能指标、响应式设计原则。另外,尽管他山之石可以 攻玉,但拿来主义有一个大前提,就是你了解你的项目的关键问题,你要优先解决的是些关键问题,而外来规范正好能解决你的问题。因此规范是一本案头手册,是 一揽子问题的解决方案,应当是“字典”,而不是“教程“。可见规范的源头是“问题”。所以,当你想用CoffeeScript重构你的项目时、当你想引入 CommonJS规范时、当你想在页面中揉进Bootstrap时、当你打算重复造轮子搞一套JS库时、当你想重写一套assets打包工具时,想想这些 东东解决了你的什么问题?会不会带来新的问题、把事情搞复杂了?还是为了尝鲜?或者为了在简历中堂而皇之的写上使用并精通各种新技术?

  The establishment of the specification should have a motivation, which comes from the project requirements, and the project requirements come from the understanding and grasp of the product. This is an important transformation from the junior web front-end engineer to the intermediate or even advanced level. The software engineering field has long had the role of "architect". , and architects often exist in the project requirements analysis and general design, detailed design phase. What I see is that the thinking of Web front-end engineers is too limited within the "interface", the forward is too far away from the product requirements (think this is a matter for visual designers), and the backward is separated from the data logic. Kailai (I think this is what background engineers should do), so the front-end specifications are mostly general, irrelevant to the project, and become toys.

  The great thing about Yahoo's technical specifications is that they solve problems. Therefore, when learning and using norms, you should ask one more question, "Why did they do this?" In fact, when thinking about these questions clearly, a creative thinking of "breaking mountains and breaking mountains" naturally formed in my mind.

  【Breaking and establishing norms 2】

  If it is said that early adopters of new technologies lack pertinence, but at least satisfy programmers' cleanliness and pleasure, then where does the "burden" come from? For beginners, the only valuable learning materials may be these norms. If the norms are of little value, where should we start?

  What I said just now is not relying on norms, but reflecting on norms and getting rid of the mindset instilled in us by norms. The newcomers probably read many indicators, conclusions, and practices in the Wiki, and added a lot of "stereotyped" burdens at the beginning of the project, which even affected our insight and judgment on the key requirements and key issues of the project. If the burden is too heavy, you can’t go lightly. The indicators and specifications mentioned in the Wiki are conclusive and come after a lot of practice. Only after a lot of practice can you really understand these conclusions, such as DomReady time and http request Is there a causal relationship between the numbers, will the increase in the number of http requests really lead to a decrease in page performance, and under what conditions will it cause a decrease in performance? We cannot find an answer from those articles and conclusions.

  To give a specific example, Kissy has just released DPL, and there are also a lot of conclusions. For example, his layout adopts the classic double flying wings and uses container floating to realize. So, is this approach an unshakable "standard"? Take a look at the homepage of Taobao Auto Insurance. The layout containers are inline-block. As long as the width of the top-level container is removed, the layout container itself can adjust the natural horizontal/vertical arrangement according to the width of the browser, and easily adapt to the width of the terminal.

  For another example, the deployment method in the Taobao travel plan project does not fully use Loader to manage dependencies, but does very little dependency level, and uses scripts to merge business logic, so that it is easier to add grammar checks and codes in the build process Style check.

  This kind of practice of getting rid of the original programming thinking and using new ideas and methods to solve problems is obviously more refreshing, and the fun of programming is also reflected in the pleasure of breaking the rules. Xiao Ma once said: "Making Specifications are to break the norms", don't be burdened by these norms and standards, so that when you start to make a simple page, you also seem to be timid and unable to let go of your skills. Only by bold hands-on practice can we truly draw our own "conclusions" and "standards" and truly understand the meaning of those "conclusions". If you write a lot of code, practice makes perfect, and it is easy to form a mature technical point of view.

  In this process, our only opponent is laziness. If we are lazy in thinking, we will not be able to really discover problems, and naturally we will not be able to form our own opinions. Again, any norms, methods, conclusions, and practices are designed to solve problems in the project. Therefore, those seemingly "eight-part essay"-style norms and standards we have come into contact with are also proposed to solve certain problems. If you think about these issues clearly and understand the "cause" behind the methodology, you will naturally have "effects" in your heart.

  Therefore, the quality of "focusing on the present and prescribing the right medicine" is very precious. For example, the double-flying wing layout method is to solve a set of (html) codes to adapt to multiple layout designs. Compared with fixed products, the layout here is also fixed. , without terminal-specific adaptation (it seems that there is no best practice for the tatami layout on the mobile terminal). This is the background of the double-flying wing. Today, the terminal environment has been turned upside down compared to 5 years ago. The problem is no longer in "multiple layouts", but in "terminal adaptation". This is the problem we face, and we need to give new solutions. technical solutions.

  Therefore, thinking diligently, traveling lightly, practicing boldly, being brave in innovation, discovering the problem, and solving (potential) problems in a real way are the abilities we really need. Let go of the shackles of fixed thinking, and there will also be a feeling of enlightenment.

  Day 2: Academic Talents

  【Scholar career】

  Web front-end engineer is a special position that only exists in the Internet field. In recent years, with the explosion of the Internet industry, the demand for front-end engineers has skyrocketed, and the source of soldiers has almost dried up. The technical heads of major companies must have had similar distress: "It is difficult to recruit a reliable front-end engineer."

  我想,一部分原因是,当前不少入道的前端工程师大都是转行而来,毕竟,正儿八经的学校里也不会教这玩意,觉得“切页面”有啥好教的,甚至不觉得 html/css是一门语言。转行这事自不必详说,大家也各自瞄准当前市场需求,造成的现象是,初级前端工程师堆成山,中高级人才却一将难求,计算机系的 科班出身就更加凤毛麟角了。一方面反映了教育部门的后知后觉,另一方面也体现了大部分人急功近利的跟风。当然最重要的原因是,所谓中国“第一代前端工程 师”并未做好布道的工作。导致大家对于基础和潜力的态度从之前的忽视演变为如今的蔑视。所谓基础,就是在大学上的那些计算机基础课。所谓潜力,就是戒骄戒 躁的务实作风。这些会在后文中多次提到。

  对于科班出身的莘莘学苗来说,根正苗红本身就是一种优势,事实证明,这些人在前端技术上的成长轨迹有一定的套路,而且大都能如期的突破技能瓶颈。从一个人大学毕业到他最满意的工作状态,中间会经过几个阶段。

  前2年是学习技能的阶段,这个阶段主要精力放在专业技能的提升上,2年内起码要赶上平均水平,即所谓“中级“,在这个阶段的人通常对软技能不怎 么关注,沟通能力达不到平均水平,基本上是来啥活干啥活,干不完就加班的这种,对需求的合理性不甚理解,对项目也没什么把控,尽管在技能上有提高的空间, 也不是公司最需要的人,但有不少成长空间。

  工作2-3年的人在前端技能上趋于稳定,也就是技能上的第一次瓶颈,这种人干活熟练,切页面可能也很快,代码看上去也比较规范,属于熟练工,开 始注重沟通技巧和一些职业技能的积累,比如带人带项目,至少有这方面的意识,并有过推动项目、和业务方pk需求的经历,这就达到了中级应当具备的职业技 能,但应当注意的是,这时最容易出现偏科的情况,特别是对于那些“专门切页面的“和“专门写脚本的“人,毕竟html/css/js三者不分彼此,三者是 一个合格前端工程师都必须要掌握的。如果你觉察到自身有偏废的嫌疑,则要小心了,要清楚的了解自身的差距,并意识到瓶颈的存在,为过渡到“中级“的打下基 础。

  过了这道坎之后,工作3年以上的人大部分技能也趋稳,有些人对前端新技术有钻研,能够熟练应对日常工作,软技能也ok,具备有针对性的“拿来主 义“,代码也具有一定的架构性,开始突破“代码民工”的这一层瓶颈,对团队气氛、培训、工作环境有个性化的要求,一般来讲,这种人是典型的具有潜力的“中 级”工程师,但很快会遇到职业发展中的第二个技术瓶颈。

  有少数工作3年或4年以上,在不断寻求新的技能上的突破,最明显的一点体现是,开始关注“底层协议”,即HTTP、第三方应用、系统对接、制造 工具、工作流程等,这时思考的重点已经脱离了“切页面”,变为“出方案“,比如要架设一个站点,能够搭建站点框架,预见站点后续(前端)开发中的所有风 险,并一一给出解决方案。项目后续开发遇到问题只要翻阅你提供的“手册”即能找到答案。这种人是标准的“高级”Web前端工程师。

  出方案是一件挺难的事情,它要求一个工程师同时具备经验、技术、气场等诸多硬技能。尤其是对技术底子的要求非常高。

  【半路出家】

  那么,转行做前端的人又当如何呢?其实发展轨迹和科班秀才们非常类似,只是时间跨度可能会长一些,你要花更多的精力、做更多的项目、更多的反思和总结才能理解某个知识点的本质(比如HTTP协议)。当然这只是一般情况。

  此外,这些人还需要摆脱很多思维定势的禁锢。这里我推荐大家阅读阿当的《Web前端开发修炼之道》。当然,如果你有一个靠谱的师兄带你入道,自然幸运万倍。

  但不管怎样,我始终认为应当秉承兴趣第一的原则,不管你是误打误撞、还是意欲为之,不管你是科班秀才、还是半路出家,兴趣始终应当是第一原则, 然后才是你“想做好“。我对自己的要求无法强加于人,所以很多业界大牛在回顾自己成功之路时,提到最多的是:“热爱你的工作、拥抱它给你带来的挑战”。 N.C.Zakas曾经这样勉励大家:

  "My biggest advice to web developers is this: Love what you do. Love the challenges of cross-browser development, love the heresies of Internet technology, love your peers, love your tools. The Internet is moving too fast, if If you don't love it, you can't keep up with it. This means that you have to read more and do more to ensure that your talents grow day by day. You can't be idle after work, and do something that is useful to you. Yes Participate in the development of some open source software, read good books, and read the blogs of talented people. Frequently attend some conferences to see what other people are doing. If you want to grow yourself quickly, there are many things you can do, and you will definitely pay return."

  Day three, happiness

  【Proficient in ten elements first? !

  Interest comes first, it sounds beautiful, but the reality is not always so cool. Once you have developed a skill, you have to find a monster to beat it to enjoy.

  Naturally, everyone wants to make good things, and every engineer is eager for such an opportunity to make beautiful, safe, practical and durable products with well-defined design, beautiful and elegant code, and exquisite details. However, the reality So brutal that engineers have always lacked a sense of belonging to the product. As a front-end engineer, how can we grasp the direction of progress and step up step by step in the rivers and lakes? After all, in a large company with many positions, the lack of humanized workflow affects the work happiness of engineers. Products are full of compromises from the beginning of design, to technical solution review, to realization, and most of the products are the product of crossbreeding. People are constrained by each other, and everyone is dissatisfied with the product... Great Leap Forward Agile Development has long been proven to be harmless. But maybe this is the price of growth. Young engineers need to know more about requirements and design, and product managers need to understand the laws of software iteration. This is especially true for front-end engineers. Learning more about interaction design and UI, network protocols and software iteration models can help front-end engineers communicate with demanders, connect with the background, and control version iterations.

  Strange to say, don't front-end engineers write html/css/js, what's the use of understanding those fringe knowledge? "The Way of Web Front-End Development Practice" also mentioned that to be proficient in one line, you need to be proficient in ten lines first. Here I will explain why.

  As the downstream of interaction designers, it is easy to understand that front-end engineers need to learn design knowledge, because it can help you understand the designer's intentions more accurately, and can correctly feedback design defects when the prototype is incomplete, and solve problems Blocking in the design process will greatly reduce the number of UI bugs. For example, the designer will give the ideal container style, but often ignores the overflow of text, long continuous characters, and whether the width and height of the container adapt to the change of the content size. Changes, whether the overflow part is truncated or hidden, and many other details, because the designer does not understand the principle of "boundary value testing", and these problems are often discovered during the testing phase, so if you can get the UI design draft Reminding designers to complete these scenarios will naturally reduce the number of test regressions.

  In addition, front-end engineers must understand network protocols for the simple reason that the products we make run on the Web. Many implementations rely on Ajax, and only front-end engineers can propose implementation solutions. Product managers don’t understand technical bottlenecks, and background engineers don’t care about the user experience of the client. Let’s take a simple example: implement Ajax through JS. If Ajax captures If the data source is a 302 redirect, you need to do more things in the JS program, which requires front-end engineers to understand some HTTP protocols. It should be said that this is a very common scenario.

  So, why should front-end engineers pay attention to code version control? Because the essence of web development and software development are the same, they also have an iterative cycle. Requirements are not developed in a package and developed in one go, but are developed step by step. Therefore, which functions are developed each time online and which interfaces are reserved for subsequent expansion functions , What considerations should be made in terms of code scalability and maintainability... These should be the concerns of every engineer. The so-called iteration refers to the superposition of such requirements. This is the normal state of software development, and it is also the normal state of web development. At the beginning, front-end engineers always complained about the endless requirements. The code was clean at first, but it soon became more and more chaotic. Code version management is a bit difficult for Web front-end engineers, which also makes most front-end engineers It is difficult to improve. From this perspective, front-end engineers need to learn from background engineers. Their development volume is not less than that of front-end engineers, and their ability to maintain code is better than that of front-end engineers. In addition, for front-end engineers who have just entered the industry, the mentality must be correct. It is the responsibility of the product manager to raise requirements, and it is the responsibility of the interaction designer to sort out valuable requirements. It is the responsibility of the front-end engineer to implement version control step by step. Therefore, front-end engineers don't need to complain about the product manager's a lot of irregular requirements, but should understand the reasons for the requirements, refine the requirements into UC (use cases), and make the requirements controllable in their own hands. It's just that most front-end engineers lack the ability to refine and sort out requirements, and when they are blindly receiving requirements, they will be in a hurry and pile up code with emotions.

  Therefore, only when you have developed a whole body of skills, you will be more targeted to find a sense of responsibility for the product and a sense of belonging to the team. Don’t mistakenly think that being able to cut out beautiful pages is the improvement of your ability. Purely writing code is almost the same for everyone. Yes, to become a qualified engineer, you need to open your horizons further. Front-end engineers can do more than just cut pages. For a high-quality project, there must be a lot of professional process control. This is what most people tend to ignore. .

  【The book of inspiration】

  其实,除了个人需要明确努力的方向,每个人都更渴望身处一个好团队,谁都不希望有猪一样的队友。我们都很羡慕处身这样的团队,可以放心的将精力 放在纯粹的技术上,身边每个人都自觉的补充文档注释,代码也层次清晰解偶充分重用率高,精妙的设计实现可以更快的传播,bug得到的改进建议也是务实专业 的,技术在这种良性互动中价值倍增。我想这也算是好团队的一种境界了,这有赖于团队成员水平水涨船高。不过,反观Yahoo的成长之路,他们的技术积淀也 是靠点滴的积累,其实他们当初的状况不比现在的我们好哪去,10年的进化,才造就了Yahoo技术团队的专业性和Hack精神,我们每个人才刚刚起步而 已。为了积攒工作中的幸福感,多付出一些是值得的。

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

  如果你想做到“资深”,就一定要想清楚这一点,因为你是团队的顶梁柱(业务),也是幸福感的源头(士气)。

  第四日,架构和伪架构

  【代码设计的本质】

  读到这里,你不禁会问,前端领域存在“架构师”吗?这个问题会在后面的“码农的宿命”中展开解释。这里先说下代码架构的一些琐事吧。

  什么是架构?架构是由“架”和“构”组成,架,即元件,构,即连接件。因此,架构即是将总体分解为单元,然后定义单元之间的连接方式。架构的含 义源自禅宗,而禅宗的基本信条则之一就是真理是无法用语言来描述的。这个基本信条有其背景,即语言具有某种抽象性。而人们对这种抽象性的悟道则直接影响对 事物的看法,进而决定了对客观世界的分解方法。

  而在编程语言中,同样存在这种禅宗所隐喻的悖论。在面向对象的教科书中,通常举一些显而易见的例子,比如“水果”是一个类,包含有苹果、桔子、 香蕉等实例,“蔬菜”也是一个类,包含白菜、冬瓜、茄子等实例。这两个类之间并无交集,因此很容易理解。但实际项目中情况要复杂的多,比如两个图书类目 “文学”和“历史”,那么“明朝那些事”应当是“文学”类的实例还是“历史”类的实例呢?即一旦用语言说出了某一事物,即人为的割裂了世界,于是就会陷入 迷途。这在程序设计领域情况更甚,也是造成混乱的主要根源,也就是说,如果你的程序可扩展性不好,一定是程序作者对“单元”的定义不够准确,即单元的概念 之间不够“正交”。而这种架构终是徒有其形,根基不稳。

  因此,变量和类的命名才是真正考验架构功力的关键(命名是否准确清晰、单元之间是否有概念重叠或盲区),而和所谓“组合”、“继承”、“桥接”等模式化的“外表”无本质联系。

  【伪架构】

  实际情况是,程序员早早的就想让自己和“架构”扯上关系,并自封xx架构师。在项目中应用各种模式分层、解耦方法,每个项目都可以产出一套看上 去很复杂的“架构图”,感觉很牛逼的样子,没错,实践这些方法论总不是坏事,但世界观才是方法论的基础,只有在概念上对产品模块有科学的定义,方法论便自 然形成了,《编程珠玑》中一再提及数据结构就是静态的算法,在Web前端领域亦是如此,在页面的建模过程中,定义分解维度要比分解方法更加基础和重要。我 想阿当可以在《Web前端开发修炼之道》的第二版里加上这部分内容。

  真正的高手用记事本就能写出高质量的代码、用cvs就能做到完美的版本控制、用字典式的分解就能做好系统架构,我想,这正是剑宗一派的最高境界吧。

  第五日:寻找突破

  【动心忍性】

  技术流派看上去是如此吸引人,高手就像侠客一般,来去如风潇洒自如。但反观自己怎么看怎么没有侠客那股范儿。尽管上文提到了一些道理,了解这些 尽管不是坏事,但缺少实践总感觉是纸上谈兵。更何况,日常的工作又是枯燥无味、繁杂单调。每个人都盼望更高的目标、接触新鲜技术、将新技术运用到日常,在 探索尝试之中寻找成就感。这种感觉可以理解,但却缺少更深层次的思考。因为越到最后越会发现一线的工作才是最有挑战的。当然,我说这话的前提是,你能如前 文所说具备合格的软技能,需要一些技巧让工作变得工整有序、节奏健康,这样你才能将注意力放在纯粹的代码中,摆脱了外界的烦扰,方能从技术的角度思考突 破。这也是从初级到高级的进化过程需要大量的历练的原因。正如玉伯所说,“枯燥是创新的源泉。如果你发现自己没什么新想法,做事缺少激情,很可能是因为你 还未曾体验过真正的枯燥的工作”。

  关于如何寻找突破,我的建议是马上动手做、不要等,相信自己的直觉(这里和上文提到的先思后行是两码事)。比如,Slide幻灯控件理应支持触 屏事件以更好的适应移动终端,或许你在用的Slide幻灯版本很旧、或者时间不允许、再或者你害怕对Slide改造而引入bug,不要担心,大不了多花业 余时间,只要想,只要感觉合理和必要,就去做。因为这个过程带来的编程体验才是工程师们独有的美妙体味。我现在还时常深夜写代码,没有打扰、思如泉涌、代 码也更加工整严谨,不失为一种享受。因此,用眼睛去观察,用心去感触,“所以动心忍性,才会增益其所不能”啊。

  【得与失】

  互联网的发展的确太快,Web前端技术也在花样翻新,有人经不起诱惑,开始做新的尝试。前端技术虽然范围广,但各个分支都还比较容易入门,比如 服务器端脚本编程、再比如纯粹的WebApp,我认为这两者都是前端技术的范畴,毕竟他们都没有脱离“浏览器”,或者说类似浏览器的环境。NodeJS依 赖于V8,WebApp更是软件化的WebPage。只要打好基础,这些方向都是值得深入钻研的,因为,互联网的形态越发多元,新的技术总能找到用武之 地,这就要凭借自己的技术嗅觉和产品直觉,寻找技术和业务的契合点。

  这看上去是一种放弃,放弃了自己赖以生存的铁饭碗(熟练的切页面至少不会失业),实则不然。这种想法是一种误区,新的选择并不会让你放弃什么, 就像学会了开车,并不意味着就不会骑车了。其实改变的是思维方式而已,是一种进步,如果你能想通这一点,你也能跟得上互联网发展的脚步了,打开你的思维, 让技术变成你的金刚钻,而不是包袱。

  所以,所谓得失之间的权衡,其实就是“解放思想”。做到了这一点,那么你已经在做“技术驱动”了。

  【误区】

  但是,不要高兴的太早,“技术驱动”是需要大量的积累和经验的。在入行初期,很多人过于着迷与此,从而陷入了迷途。比如有人纠结于是否将dt、 dd的样式清除从reset.css中拿掉,原因是觉得这两个标签的清除样式会耗费一些渲染性能;或者是否需要将for循环改为while循环以提高js 执行速度。尽管这些考虑看上去是合理的,但并不是性能的瓶颈所在,也就是说,你花了很大力气重构的代码带来的页面性能提升,往往还不如将两个css文件合 成一个带来的提升明显。就好比用一把米尺量东西,没必要精确到小数点后10位,因为精确到小数点后2位就已经是不准确的了。这种技术误区常常让人捡了芝麻 丢了西瓜。

  话说回来,这里提到的怀疑权威的精神是绝对应当鼓励的,但不应当止于表象,如果怀疑dt的清除样式会对性能带来影响,就应当想办法拿到数据,用事实来证明自己的猜测。数据是不会骗人的。而求证过程本身就是一种能力的锻炼。

  【技术驱动】

  说到这里,你大概对“技术驱动”有那么一点点感觉了。身边太多人在抱怨“公司不重视前端”、公司不是技术驱动的、技术没机会推动产品业绩、我的价值得不到体现?

  什么是技术驱动?简单讲,就是技术对业务有积极推动作用。更多的是工程师发起、工程师影响、工程师负责。刚才提到的用数据说话只是一种“驱动”技巧,那么我需要何种数据,数据从哪里来?我来分享一个实际的场景吧。

  工程师A被委派一个重要的频道首页,因为是新年版,所以要赶在年前上线。A学了一点点响应式设计,想在这次重构中加上,但谁也没做过响应式设 计,需求方根本不懂,设计师也懵懵懂懂,交互设计师太忙,做完交互稿就忙别的去了。A纠结了,按部就班的把项目做完上线发布,尽管不会出什么问题,但总觉 少点什么。这时A做了两个决定,1,我要按时完成项目,2,趁机实践我在响应式设计中的想法和思考,若成功,作为附加值赠送给需求方,若失败,权当技术玩 具耍一耍罢了。所以A熟练的提前完成了项目,剩下的时间开始考虑如何将首页适应到各个平台中,视觉设计是一大难题,他用吃饭的时间找了设计师收集建议,对 窄屏中的内容模块做了看似合理的编排,代码上hack一下,能够正确适配,就发布上线了。这件事情需求方不知道,视觉设计师也不了解,交互设计师更没工夫 操心。A感觉挺爽,开始给工程师弟兄们到处炫耀这个好玩的功能,B看了问,手机端访问量如何,A觉得这个问题有道理,就去部署埋点,一周后拿到数据出奇的 意外,首先,移动段的访问量稳步增加,趋势健康,再者,移动端首屏焦点广告位的点击率较PC端高了近一倍,这个数据让A喜出望外,兴奋的拿着报表找到交互 设计师C和市场研究的同事D,D看了报表之后立即启动一个项目,专门调研公司全站响应式设计页面在PC端和移动端的点击率、PV、UV趋势方面的影响…… 后来发生的事情就都水到渠成了,设计师C开始注意设计页面交互时(至少是有条件的考虑)对移动端的适配,D的调研报告也放到了UED老大的案头……接下来 的事情,你懂得。A被指派要出一套响应式最佳实践和规范,最终,A走在了技术的前沿,也因此拿到了好绩效。

  这件事情就是一个典型的技术驱动的例子。谁不让你玩技术了,谁不重视你了,谁把你当工具了,谁觉得你的代码没价值?这世界只有自己把自己看扁,谁想跟你这个蝇头小卒过不去?用实力说话,用数据说话,用独到的见解说话,想不做技术驱动都难。

  第六日:码农的宿命

  【青春饭】

  “码农”是IT从业者一个自嘲的称号,也有从事没有发展前景的软件开发职位,靠写代码为生的意思。但我认为码农是一个爱称,编码的农民,和农民 一样有着执着纯真朴实豪爽的共性,仅仅分工不同而已。就好比农业社会对粮食的依赖,工业化进程对计算机应用也有着很强的依赖,大量的需求催生出这样一群 人。他们有智慧的大脑,对于编程,设计,开发都有着熟练的技巧,但多数人看来,码农的特点是:

  1,收入低
  2,工作单调
  3,工作时间长

  实际上这个描述非常片面,或者说是外行看热闹。第一,全行业比较来看,软件开发领域收入为中等偏上;第二,程序员一般都是有癖好的,沉浸在自己 的癖好中是不会感觉单调的;第三,程序员有一定的时间自由度(如果你是一名合格的程序员的话),至少不会像流水生产线工人一样。其实,通过几十年的发展, 我们对程序员的定义更加科学,比如很多IT企业都开始建立详细的JM(Job Module),即职级模型,程序员沿着专业方向可以走到很高,甚至可以 说,程序员是可以被当成一生的事业的。

  然而,有一个非常普遍的观点是,程序员和做模特一样是吃青春饭的,到了三十岁就要考虑转行或者转管理。尽管这种观点颇具欺骗性,但至少它对一种 人是适用的,即入错了行的人。如果你骨子里不想写程序,就算年纪轻轻为了生计写几年代码,之后肯定会另有他途。心非所属则不必勉强,但问题是,即便如此, 你知道你的心之所属吗?

  We know that a mature industry must be supported by various positions. To mature, it needs time to settle. For example, the manufacturing industry of the real economy has produced a large number of senior talents in four aspects: creativity, production line, senior technicians, and technology management. Because of its long history, we can see it. This is not the case in the software industry. More than 90% of them are novices who have just debuted. There are not many specific examples of "advanced" and "senior" for reference. The situation is even worse in the field of front-end development. What is a "senior" front-end engineer? Compared with the nearly 40-year evolution of the traditional software industry, I don't believe that there are only a few years of front-end technical positions that can produce many real "senior". However, the rise of the Internet is too fast. Before the technical foundation is firmly established, the form of the Internet has been refurbished again. This kind of change is a normal state, and the setting of positions is also a natural survival of the fittest in this change, such as two years. It may have been hard to imagine that the data department would need front-end engineers before, and they didn't even deal directly with the browser. Front-end engineers need to adapt to the conceptual impact brought about by this change. Don’t think that you can only cut pages, or only refactor pages, or only engage in compatibility, but put yourself in the perspective of the entire software industry.

  Therefore, the ambiguity of the position due to the "not long history" is not a big problem in itself, and the evolution of the position itself is included in the development track of the Internet. Therefore, today's Internet IT situation is like the era of mobile terminals, the age of bots in cloud computing, or the era of DOS in desktop operating systems. Therefore, the current priority for front-end engineers is to see clearly what I can do on the Internet, not what I can do as a front-end engineer. Therefore, from this perspective, technology is a tool. A very small part of your career, and your professional accumulation and the breadth and depth of knowledge are the reasons why you slowly become "senior" over time, rather than just writing a framework. "Senior" too. If the form of the Internet is fixed one day, its positions may be truly finalized, and then there will be truly clear functional boundaries, just like the various positions in the blue giant IBM, with clear boundaries and clear rights and responsibilities. Ordinary programmers can only Realize the interface but have no chance to design the interface, low-level engineers have no chance to get in touch with the project architecture in a leap forward, and technical managers cannot easily have a decision-making influence on the product. At this time, the ability of people is really limited within a radius In this environment, human growth is very slow. There will be no innovation, revolution, growth, and emancipation of the mind as advocated in today's Internet chaos. Simply put, once the industry is finalized, there is less need for "creation" and more "maintenance". Therefore, I personally would rather the "dark" Middle Ages of Internet IT last as long as possible. At least for young and energetic programmers, the dark jungle environment is the most ideal soil for real natural evolution. At this time, I think of Dickens in "A Tale of Two Cities" "In the beginning.

  "It was the best of times, it was the worst of times; it was the epoch of wisdom, it was the epoch of foolishness; it was the epoch of faith, it was the epoch of doubt; it was the season of light, it was the season of darkness ; it is the spring of hope, it is the winter of despair; men have everything before them, men have nothing before them; men are going straight to heaven, and men are going straight to hell."

  【The dangers and opportunities of becoming a monk halfway】

  However, in any case, the establishment of confidence is not achieved overnight, especially for those who switch careers to be front-end. As the saying goes, every line enters a mountain. Every industry has its own way, and naturally it is not just what you want to do. There are a lot of half-way monks in the field of front-end technology. Let's analyze the psychology of changing careers. First, I saw that front-end technology is easy to get started, and there is a huge gap in Internet demand for front-end technology; second, what you see is what you get in front-end technology, and I feel that I can learn it quickly; I seem to be able to do the same; fourth, I don’t like the job I’m doing now, and I want to change industries, and it’s just that the front-end technology is quick to get started, so I’ll choose him; is worth it.

  The mentality of career changers tends to go to two extremes. One is that they only see the good in the new industry, and the other is that they only think that the original job is bad. But no matter what industry you are changing careers, you should think about your career planning one step ahead. That is, be sure to answer these questions clearly first:

  1. What can I do?
  2. What can't I do?
  3. What are my strengths?
  4. What are my weaknesses?
  5. What are the benefits to me of starting a new industry?
  6. What price will I pay for the new line?
  7. How to define career change success?

  Because you will definitely be challenged by these questions during the interview. If you hesitate to explain clearly, you are either irresponsible for your own future, or you are a grassroots person in your bones, and you are used to doing everything in a superficial way. I can't answer these questions for everyone, but at least two points are certain. First, Web front-end technology is a sunrise industry, and it is absolutely worth sticking to it without hesitation; second, you will experience unprecedented boring and harsh experience, the so-called painful stage of "doing what you don't do." But having said that, people who have gone through the college entrance examination are still afraid of shit.

  有心之人自有城府、懂得放弃,看得清大势中的危机、识得懂繁华里的机遇。尤其当立足于Web前端技术时,这种感觉就愈发强烈。因为国内外前端技 术领域从2000年至今一直非常活跃,前端技术前进的步伐也很快,对于一些人来说,不管你是在大公司供职还是创业,不管你是在接外包项目还是自己写开源项 目,从转行到跟得上新技术的脚步是有一些方法和“捷径”的。

  第一,梳理知识架构

  我们知道知识积累有两种思路,第一种是先构建知识面、建立技术体系的大局观,即构建树干,然后分别深入每一个知识点,即构建枝叶,最终形成大 树。第二种是先收集知识点,越多越好,最后用一根线索将这些知识点串接起来,同样形成大树。第一种方法比较适合科班秀才,第二种方法则更适合转行作前端的 人,即实践先行,理论升华在后。比如对“IE6怪异模式“这条线索来说,要首先将遇到的IE6下的样式bug收集起来,每个bug都力争写一个简单的 demo复现之,等到你收集到第100个bug的时候,再笨的人都能看出一些规律,这时就会自然的理解IE的hasLayout、BFC和各种bug的原 因、你就成为了IE6的hack专家了,当你成为100个知识线索的专家的时候,你已经可以称得上“资深”的水平了。我们知道,10个人中有9个是坚持不 下来的,他们会以项目忙等各种理由万般推托,将自己硬生生的限制在草根一族,坐等被淘汰。所以,对于立志作前端的人来说,这种点滴积累和梳理知识非常重 要。

  第二,分解目标

  将手头的工作分解为几部分来看待,1,基本技能,2,项目经验,3,沟通能力,4,主动性和影响力。想清楚做一件事情你想在哪方面得到历练,比 如,我之前在做第一次淘宝彩票常规性重构的时候(正好是一次视觉和交互上的全新设计),我清楚的明白这次重构的目的是锻炼自己在架构准富应用时的模块解偶 能力,寻找在其他项目中架构的共通之处,所以我宁愿加班或花更多精力做这个事情,当然更没打算向业务方多解释什么,这件事情对我来说纯粹是技能的锻炼。而 经过这一次重构之后,我意外的发现对业务的理解更透彻深入、更清晰的把握用户体验上的瓶颈所在。如果一开始就把这次常规改版当成一个普通的项目按部就班的 做,我只能说,你也能按时完成项目,按时发布,但真真浪费了一次宝贵的锻炼机会,项目总结时也难有“动心忍性”的体会。

  所以,每个项目的每个事情都应当认真对待,甚至要超出认真的对待,想清楚做好每件事对于自己哪方面有所提升?哪怕是一个bug的解决,即便不是 自己的问题也不要草草踢出去了事,而是分析出问题原因,给出方案,有目的involve各方知晓……,正规的对待每个不起眼的小事,时间久了历练了心智, 这时如果突然遇到一个p0级的严重线上bug(比如淘宝首页白屏,够严重的了吧)也不会立即乱了方寸,这也是我上文提到的心有城府自然淡定万倍,而这种淡 定的气场对身边浮躁的人来说也是一种震慑和疗伤,影响力自然而然就形成了。

  第三,作分享

  做分享这事儿真的是一本万利。有心的人一定要逼着自己做分享,而且要做好。首先,自己了解的知识不叫掌握,只有理解并表达出来能让别人理解才叫 掌握,比如如果你解释不清楚hasLayout,多半说明自己没理解,如果你搞不懂双飞翼的使用场景,可能真的不知道布局的核心要素。再者,作分享绝对锻 炼知识点的提炼能力和表达能力,我们作为工程师不知道多少次和强硬的需求方pk,被击败的一塌糊涂。也反映出工程师很难提炼出通俗易懂的语言将技术要点表 述清楚。而做ppt和分享正是锻炼这种能力,将自己的观点提炼出要点和线索,分享次数多了,自然熟能生巧。档次也再慢慢提高。另一方面,逼迫自己站在公众 场合里大声讲话,本来就是提高自信的一种锻炼。

  这时,你或许会问,我讲的东西大家都明白,我讲的是不是多余,我第一次讲讲不好怎么办,大家会不会像看玩猴似的看我“这SB,讲这么烂还上来讲”?要是讲不好我以后再讲没人听怎么办,我今后怎么做人啊?

  老实说,这是一道坎,任何人都要跨过去的,谁都一样,你敢鼓起勇气在大庭广众之下向爱人表白,就没勇气对自己的职业宿命说不?其实勇敢的跨越这 一步,你会意外的收获他人的掌声和赞许,这些掌声和赞许不是送给你所分享的内容,而是送给你的认真和勇气。这个心结过不去,那就老老实实呆在自己的象牙塔 里遗老终生,当一辈子工程师里的钻石王老五吧。

  【匠人多福】

  如果你能耐心读到这里,心里一定有一个疑问,上面说的都是技术上能力上怎样怎样,那我所做项目不给力又当如何?如果项目不挣钱、黄了、裁了,我的努力不就白费了吗?我又有什么绩效和价值呢?

  没错,有这种想法的人不在少数。特别是刚出道的校招同学往往更加心高气傲,以为自己有改变世界的本事,一定要参与一个牛逼的团队做一款光鲜靓丽受人追捧能给自己脸上贴金的项目。如果你有这种想法,趁早打消掉这个念头,当然,我们这里先不讨论创业的情形。

  第一,如果你刚毕业就加入一个牛逼团队,说难听点,你就是团队中其他人眼中的“猪一样的队友”,不创造价值且拖项目后腿(显然大家都要照顾你的成长啊),按照271理论,你没有理由不是这个1。至少相当长一段时间内是这样。

  第二,你在所谓牛逼团队中的创造性受限,因为创新多来自于团队中的“资深“和大牛们,你参与讨论但观点通常不会被采纳,他们只会给你这个菜鸟分活干,想想看,你如何能花两到三年就超越身边的大牛们?甚至连拉近与他们的距离都难。

  第三,如果身在牛逼团队,自然心理对周围的牛人们有所期待,希望他们能灌输给你一些牛逼的知识和牛逼的理念。这种思想上的惰性在职场生涯之初是非常危险的。要知道技术和知识本身是很简单和淳朴的,只不过披上了一个光鲜项目的外衣而让人感觉与众不同。

  第四,由简入奢易,由奢入简难,做过一个看似光彩的项目,心理再难放平稳,去踏实的做一个看上去不那么酷的产品。这种浮躁心态会严重影响今后的职业发展和成长。

  第五,光鲜靓丽的项目被各种老大关注,是难容忍犯错误的,傻瓜都知道犯错误在成长之初的重要性。

  就我所看到的情形看,一开始加入看似很牛的项目组,三年后得到的成长,比那些开始加入一个不被重视的项目的同学要小很多,而后者在能力上的弹性 却更大。所以,道理很简单,你是要把一个很酷的项目做的和之前差不多酷,还是把一个不酷的项目做的很酷?项目是不是因为你的加入而变得与众不同了?

  从这个角度讲,不管是转行的新人还是刚出道的秀才,最好将自己当作“匠人”来对待,你的工作是“打磨”你的项目,并在这个过程中收获经验和成 长。付出的是勤奋,锻炼的是手艺,磨练的是心智。因此,你的价值来自于你“活儿“的质量,“活儿”的质量来自于你接手的项目之前和之后的差别。做好活儿是 匠人应有的职业心态。想通这一点,内心自然少一些纠结,才会对自己对项目的贡献度有客观的认识,不会感觉被项目所绑架。

  做一名多福的匠人,拥有了金刚钻、就不怕揽不到瓷器活儿。但对于人的成长来说,如果说“项目”重要但不关键,那么什么才是关键呢?这个话题还会在接下来的“伯乐与千里马”这篇中给出答案。 

  【若干年后】

  现在,让我们回过头回答一下“青春饭”的问题。在“青春饭”小节中提到,“程序员到三十岁之后需要转行或者转管理吗?”

  上文提到,工业化生产的四个领域,1,创意,2,生产线,3,高级技工,4,技术管理。Web前端技术也是如此,可以在这四个领域找到各自的归宿。

  第一,“创意“

  即和产品需求越走越近,拥有良好的产品感,对产品需求、设计交互把握准确,能够用适当的技术方案推动产品用户体验,属于“架构师”的范畴,因为 职能更加靠前,偏“出主意”型的。这种人更贴近用户,需要活跃的思维、广阔眼界、厚实的项目经验。更多的影响产品体验方面的决策。

  第二,“生产线“

  即前端基础设施建设,优化前端开发流程,开发工具,包括开发环境、打包上线自动化、和各种监控平台和数据收集等,属于“技术支持”的范畴,相比于很多企业粗犷难用的平台工具,前端技术方面的基础设施建设基础还需更加夯实,因为这是高效生产的基本保证。

  第三,“高级技工“

  即高级前端开发工程师,专职做项目,将产品做精做透,用代码将产品用户体验推向极致,偏“实战”型的,是项目的中坚力量,直接产出成果,影响产品效益。属于项目里的“资深”。

  第四,“技术管理“

  即做技术经理,这才是多数人所理解的“管理”,其实就是带团队、靠团队拿成果。这类人具有敏感的技术情结,在技术风潮中把握方向,能够指导培训新人,为各个业务输出前端人才,偏“教练”型的,促进新技术对业务的影响。并有意识的开辟新的技术领域。

  可见,转管理可不是想当然,也不是所谓做项目变资深了就能转管理,转了也不一定能做好。根据“彼得原理”,即人总是倾向于晋升到他所不能胜任的岗位,这时就又陷入“帕金森”定律所隐喻的恶性循环之中,直到你带的团队整个垮掉。

  Therefore, switching to management should be a very prudent thing, not as simple as switching to management if programmers can't get along. But in any case, there is one thing that needs to be considered especially clearly, that is, if the management is transferred, will the technology be lost? Let's talk about this in depth on the seventh day "Bole and Maxima".

  On the seventh day, Bole and Maxima

  【Brothers' choice 1】

  A thousand-mile horse often exists, but Bole does not. ——Han Yu, "Ma Shuo".

  It is a kind of fate that a person can meet a good senior brother in this life, which is rare. Many people’s happiness at work seems to come from being recognized, being understood and recognized by seniors. Someone can bluntly point out your shortcomings, help you discover opportunities, and assign you the most suitable things for you. This is great luck, but one out of ten people who are so lucky, most of them are gradually humiliated by the "hands of slaves" because of the lack of Bole's advice, their potential is gradually lost, and they are destroyed by the mean.

  In the field of front-end technology, this situation is very common and very special. Of course, there are many objective reasons. That is to say, the front-end technology has not been in the public eye for a long time, and powerful Bole is even rarer. What's more, the Web front-end technology still has some quackery, the knowledge points are too trivial, and the game of technical values ​​is also indistinguishable, that is, the knowledge structure of the overall system is not systematic. These factors also objectively affect the "orthodox" front-end technology. Precipitation, strange skills are abused, and the inheritance of front-end technical knowledge is too general. It is difficult for newcomers to see the current situation and grasp the priorities. Coupled with business pressure, it is inevitable that technical actions will be deformed prematurely. And these problems cannot be completely digested by oneself. If someone gives advice, the situation will be tens of thousands of times better. Therefore, in the field of front-end technology, finding a reliable senior for yourself is more important than the project, team, company, and even salary.

  This is also the reason why "the project is not important, but the brothers are important" as mentioned above. Speaking of this, there is a question, everyone should ask themselves, do you want to be a junior or a senior? What are the benefits of being a brother?

  That's right, many seniors are being subordinates, and they are not even ready to be seniors. Furthermore, many managers are also "recipients", pushed to management positions without being ready. Leading people is energy-consuming, and brothers have to do a lot of ideological struggles before they are willing to put this precious energy on those rookies. This is not a technical issue, but a moral issue. Remember, no one should give you all the skills they have mastered for no reason, and it will be fatal. After reading this, as a rookie, as an apprentice, as a rookie, as a junior, have you respected this destiny enough?

  The traditional virtue of respecting teachers and teaching has not been well continued in the technical field. It is also because of this that it is difficult to build a talent echelon, but for seniors, there are more opportunities.

  【Brothers' choice 2】

  As a senior brother, whether it is active or passive, I will definitely think that being a senior brother will improve me? For those who are first-time seniors, the biggest improvement lies in two aspects, 1, task decomposition, 2, problem analysis.

  First, task decomposition. As a senior brother, if you want to assign tasks to your juniors, it involves task decomposition. In a low level, it is to assign tasks. In a high level, it is actually doing "architecture", such as a page, According to what idea to divide the modules, whether the module division is suitable for single-person development, how to control shared styles and shared scripts, what interface do I need to provide for him, and how to control his code will not affect the entropy value of the overall page code when it is merged into the entire page , These are the problems that should be included in the real "architecture", and this kind of exercise starts from the small page, and if you do more, the "architecture sense" will naturally form.

  Second, problem analysis. In the past, writing codes by myself was all done alone, and everything was solved with codes. But once it involves collaboration, you have to force yourself to analyze the problem, or analyze the problem for the apprentice and tell him what method he should use. To solve the problem, when it comes to "method", a plan is formed in the mind, and the problem will be solved by following this plan. Analyzing problems is more abstract and efficient than writing code, because it is faster to build a plan in your mind than to write code, and your thinking will be more careful. When you exercise more, your thinking will become faster and faster, and the draft of the code will soon be completed. It is formed in the mind, which is why we say that many people do not write code but have high coding ideas and levels.

  These working methods are correct, and if you accumulate more, you will improve. The same is true for technical managers. Therefore, as mentioned in the "Gain and Loss" part of the fifth day, turning around as a senior brother and turning into a manager does not mean "losing" technical jobs, but a kind of progress.

  【Be your own bole】

  So, in the field of front-end technology, what kind of talent is considered a thousand-mile horse? In fact, everyone is a thousand-mile horse, and everyone can discover their own potential. If you can understand and recognize the above text, this kind of self-discovery has already begun. What's the problem without a good bole? Be a diligent little code farmer, less snobbish disputes, and soon you will find that you are the best Bole.

  但这并不是说,他人对自己的观点不重要,有时甚至要综合各种声音,所以,多找身边的大牛们聊聊天,多找你的师兄和主管,不管他们给你的建议是多么形而上,总有一些声音对你是有益的,多收集,有好处。

  第八日,做地球上最牛的UED

  【谁推动了历史前进,英雄?还是人民?】

  “做地球上最牛的UED!”,这是淘宝UED创立之初的口号,现在被渐渐淡忘了,因为微博上的一些讨论,又想起了这份曾经美好的初衷。玉伯也感 叹道:“这愿景曾吸引了多少好汉前往投奔呀。只可惜短短几年间,这愿景好像越来越远了”。问题是,要做好一个团队,靠的是个人、还是整体?愿景是越来越远 了吗?

  是谁推动了历史的前进,是英雄?还是人民?微观来看,是英雄,宏观来看,是人民。再放大了看,是互联网大潮之崛起推动了前端技术的进步,时势需要UED、需要用户体验。

  所以,UED团队的创立发展受这些积极的外因影响,赶上了好时候,成员也跟着沾光。然而,我并不关心这个口号,我只关心体制内的关键人物,那些 带动整个团队水涨船高的人们。往往我们发现,某些人的高度代表了整个团队的高度,个体的影响力代表了整个团队的影响力,某个人的水平代表了整个团队的水 平。支付宝、淘宝、腾讯、百度、盛大,都是如此。而我们作为普通的个体,正是要励志成为这种人,成为真真用技术推动用户体验前进的尖刀人物。

  这时我想起了很多人在知乎上的问题,关于跳槽、关于转行、关于创业、关于各种UED团队。我想,读得懂我上面的文字,你心理也许会有自己的答案。

  【归宿】

  Finally, there is another question that has to be said, that is, the question of ownership. Should front-end development belong to UED or the technical department? It should be said that the value of the current Web front-end technology is reflected in the "user experience". It is the last hurdle in the user experience field. In other words, front-end engineers should focus on the sensory experience of the pages they make. This requires some inspiration and sensibility. You should feel moved when you see a handsome and elegant interface, or feel a burst of joy when you realize an exquisite widget. This wonderful programming experience of what you see is what you get is what other back-end engineers cannot experience. Therefore, although this kind of fine craftsmanship that is accurate to the pixel level does not directly determine the life and death of the product, it is an element that enhances the taste and fashion sense of the product. Today, with more and more material things, isn't the higher demand of the public just for taste and fashion?

  If the front-end is assigned to the technical department, on the one hand, it is farther away from "design", and the code is well-written but gradually lacks spirituality; If one day, the average level of front-end engineers is high enough, and all of them come from computer science classes, it seems more appropriate to be included in the technical department. Therefore, Web front-end engineers are "engineers" and require scientific and rigorous programming skills, but the beauty and spirituality that should be possessed in UED must not be deprived.

  Another point is that Web front-end engineers, as the most practical and logical thinking type of work in UED, can maximize the impact of technology on design and can generate a lot of creation and innovation. This is also the traditional back-end engineer. do not have.

  Ninth day, front-end technology system

  Now I feel more and more that front-end technology needs to be accumulated in a systematic way. On the one hand, it can standardize our front-end technology training. On the other hand, it can be used as a knowledge clue to guide newcomers, so as to save detours and avoid falling into the deep pit of strange skills and obscenities. I can't extricate myself from it.

  I sorted out the " front-end technical knowledge structure " before, and the list was relatively scattered, but it basically expressed my point of view clearly. In the first half of this year, a front-end technology training was also organized in the entire R&D center, and the evolution rules of the front-end technology were sorted out, and they were all put in this ppt . I hope it will be helpful to everyone.

js object-oriented

[1] Basic concepts of object-oriented

  面向对象的英文全称叫做Object Oriented,简称OO。OO其实包括OOA(Object Oriented Analysis,面向对象分析)、OOD(Object Oriented Design,面向对象设计)和OOP(Object Oriented Programming,面向对象的程序设计)。

  通常所说的面向对象是指OOP, OOP是一种围绕真实世界的概念来组织模型的程序设计方法,它采用对象来描述问题空间的实体。在使用计算机解决问题时,对象是作为计算机模拟真实世界的一个抽象,一个对象就是一个物理实体或逻辑实体,它反映了系统为之保存信息和(或)与它交互的能力。使其具有自己的属性和行为, 从而简化对复杂事物的描述,更有利于工程的可维护性和扩展性。

  OOP同结构化程序设计相比最大的区别就在于: 前者首先关心的是所要处理的数据,而后者首先关心的是功能。

  【二】 面向对象三个基本特征

  封装 (Encapsulation) 将数据以及相关的操作组织在一起,成为独立的构件。外部无法直接访问这些封装了的数据,从而保证了这些数据的正确性。封装的目的是为了内部数据表现形式和实现细节的隐藏,信息隐藏是为了减少系统各部分间的依赖性,各部分间必须通过明确的通道传送信息,也就是对象间的接口.这样一来,隐藏了部分内部的细节,极大方便系统的开发,维护和扩展。

  继承 (Inheritance) 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。一个新类可以从现有的类中派生,这个过程称为类的继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且派生类可以修改或增加新的方法使之更适合特殊的需求。继承性很好地解决了软件的可重用性问题。

  多态 (Polymorphism) 多态是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是允许类与类之间相同方法名的指针得以调用, 这样很好地解决了应用程序函数同名问题。实现多态,有二种方式,覆盖,重载。

  【三】 Javascript 面向对象

  javascript本身是一种基于对象(object-based)的语言,我们日常编码过程中用到的所有东西几乎都是对象(Number, String, Boolean, etc.)。但是,相对于一些流行的面向对象语言(C++, C#, java),它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class的概念。

  Keyword: class, object, `this`, closure, constructor, prototype

  几种对象封装的方法

  • 继承
  • 多态体现

  之一、几种对象封装的方法

  1. 对象封装 – 原始模式

  假定我们把猫看成一个对象,它有”name”和”color”两个属性, “etc” 行为。

var Cat = {     name: ''     color: '',     eat: function() {} }; 

  Now, we need to generate two instance objects according to the specification (schema) of this prototype object.

function eat() {     console.log('I\'m eta fish'); } var cat1 = {name: 'Kitty', color: 'white', eat: eat}; var cat2 = {name: 'Smokey', color: 'black', eat: eat};  // var cat3, cat4 ,... 

  It is inconvenient to create multiple instance objects, the scalability is poor, and there is no connection between instances (cat1, cat2).

  2. Object Encapsulation – Constructor Mode

  A "constructor" is an ordinary function, but uses the `this` variable internally. Using the `new` operator on a function creates an instance, and the `this` variable is bound to the instance object.

  Objects created using a constructor will have a `constructor` attribute pointing to their constructor.

  `Class` is just a template, and the created instances are all generated from the template.

  For example, the cat prototype object can now be written like this:

function Cat(name,color){     this.name = name;     this.color = color;     this.eat = function() { console.log('eat fish'); }; } var cat1 = new Cat('Kitty', 'black'); console.log(cat1.name); // Kitty console.log(cat1 instanceof Cat); // TRUE // 这时 cat1 实例会自动含有一个 `constructor` 属性,指向它们的构造函数 `Cat`。 var cat2 = Cat('Smokey', 'white'); console.log(cat2); // undefined 

  3. 对象封装 – Prototype 模式

  `prototype` 是 `Function` 对象的一个属性,这个属性指向另一个对象。 这个对象的所有属性和方法,都会被构造函数的实例继承。

  同时 `prototype` 又存在一个指向构造函数的引用 `constructor`,这样就成功的构成一个循环引用的原型链结构。

  我们可以把那些不变的属性和方法,直接定义在 `prototype` 对象上, 节省内存开销。

function Cat(name, color) {     this.name = name;     this.color = color; } Cat.prototype.type = 'mammal'; Cat.prototype.eat = function() { console.log('eat fish'); }; var cat1 = new Cat('Kitty', 'white'); var cat2 = new Cat('Smokey', 'black'); console.log(cat1.type); // mammal console.log(cat1.eta === cat2.eta);     // TRUE, same reference console.log(cat1.constructor === Cat)   // TRUE, from Person.prototype 

  之二、继承 (Inheritance)

  将持有共性特点的属性或行为抽象出一个基本类, 可以按不同层次结构的业务分组抽象出多个基础类。

  Cat, Bird

  1. 继承 – 构造函数绑定

  使用call或apply方法,将父对象的构造函数绑定在子对象上。

function Animal() {     this.species = 'animal';     this.sleep = function() { console.log('I\'m sleep at night'); }; } function Cat(name, color) {     this.name = name;     this.color = color; } 

  让`Cat` 继承 `Animal` 的特性:

/** @class Cat */ function Cat(name, color) {     Animal.apply(this);     this.name = name;     this.color = color; } var cat1 = new Cat('Kitty', 'white'); cat1.sleep(); // I am sleep at night 

  2. 继承 – 原型链继承

  如果”猫”的prototype对象,指向一个Animal的实例,那么所有”猫”的实例,就能继承Animal了。

/** @class Cat */ function Cat(name, color) {     this.name = name;     this.color = color; } Cat.prototype = new Animal; Cat.prototype.eta = function() { console.log('fish is my delicious'); }; 

  它相当于完全删除了prototype 对象原先的值,然后赋予一个新值

// 任何一个prototype对象都有一个constructor属性,指向它的构造函数 Cat.prototype.constructor = Cat; // fix prototype chains var cat = new Cat('Kitty', 'fish'); cat.eat();      // fish is my delicious cat.sleep();    // I'm sleep at night' console.log(cat instanceof Cat);    // TRUE console.log(cat instanceof Animal); // TRUE 

  需要创建父类实列来实现 `prototype` 继承

  3. 继承 (Inheritance) – 利用空对象作为中介实现原型继承

var F = function() {}; F.prototype = Animal.prototype; Cat.prototype = new F(); Cat.prototype.constructor = Cat; 

  我们将上面的方法,封装成一个函数,便于使用。

function extend(ctor, superctor, px) {     if (!superctor || !ctor) throw Error('extend failed, verify dependencies');     var F = function() {};     F.prototype = superctor.prototype;     ctor.prototype = new F();     ctor.prototype.constructor = ctor;     ctor.superclass = superctor.prototype; // cache super class proto reference.     if (px) { // extend class implements         for (var k in px) {             if (px.hasOwnProperty(k)) ctor.prototype[k] = px[k];         }     }     return ctor; } 

  4 继承 – 借住工具方法实现继承

/** @class Mammal */ extend(Cat, Animal, {     eat: function() {         Cat.superclass.eat.call(this); // call super method         console.log('Also i like some ofther food, such as beef and more.');     } }); var cat = new Cat('Smokey', 'fish'); cat.sleep(); cat.eat(); console.log(cat instanceof Animal); console.log(cat instanceof Cat); 

  之三、多态

  1. 多态 – 通过重写原型方法来实现方法重名调用

/** @class Cat */ extend(Cat, Animal, {     eat: function() {         Cat.superclass.eat.call(this); // call super method         console.log('Also i like some ofther food, such as beef and more.');     } }); 

  2. 多态 (Polymorphism) – 原型继承 `prototype` 链上的方法、属性查找

  【四】总结 Summary

  Constructor

  Prototype

  Inheritance

 

js日期类

/**
* 日期处理工具类
*/

var DateUtil = function(){

    /**
     * 判断闰年
     * @param date Date日期对象
     * @return boolean true 或false
     */
    this.isLeapYear = function(date){
        return (0==date.getYear()%4&&((date.getYear()%100!=0)||(date.getYear()%400==0))); 
    }
    
    /**
     * 日期对象转换为指定格式的字符串
     * @param f 日期格式,格式定义如下 yyyy-MM-dd HH:mm:ss
     * @param date Date日期对象, 如果缺省,则为当前时间
     *
     * YYYY/yyyy/YY/yy 表示年份  
     * MM/M 月份  
     * W/w 星期  
     * dd/DD/d/D 日期  
     * hh/HH/h/H 时间  
     * mm/m 分钟  
     * ss/SS/s/S 秒  
     * @return string 指定格式的时间字符串
     */
    this.dateToStr = function(formatStr, date){
        formatStr = arguments[0] || "yyyy-MM-dd HH:mm:ss";
        date = arguments[1] || new Date();
        var str = formatStr;   
        var Week = ['日','一','二','三','四','五','六'];  
        str=str.replace(/yyyy|YYYY/,date.getFullYear());   
        str=str.replace(/yy|YY/,(date.getYear() % 100)>9?(date.getYear() % 100).toString():'0' + (date.getYear() % 100));   
        str=str.replace(/MM/,date.getMonth()>9?(date.getMonth() + 1):'0' + (date.getMonth() + 1));   
        str=str.replace(/M/g,date.getMonth());   
        str=str.replace(/w|W/g,Week[date.getDay()]);   
      
        str=str.replace(/dd|DD/,date.getDate()>9?date.getDate().toString():'0' + date.getDate());   
        str=str.replace(/d|D/g,date.getDate());   
      
        str=str.replace(/hh|HH/,date.getHours()>9?date.getHours().toString():'0' + date.getHours());   
        str=str.replace(/h|H/g,date.getHours());   
        str=str.replace(/mm/,date.getMinutes()>9?date.getMinutes().toString():'0' + date.getMinutes());   
        str=str.replace(/m/g,date.getMinutes());   
      
        str=str.replace(/ss|SS/,date.getSeconds()>9?date.getSeconds().toString():'0' + date.getSeconds());   
        str=str.replace(/s| S/g,date.getSeconds());   
      
        return str;   
    }

    
    /**
    * Date calculation  
    * @param strInterval string optional value y year m month d day w week ww week h hour n minute s second  
    * @param num int
    * @param date Date date object
    * @return Date return date object
    */
    this.dateAdd = function(strInterval, num, date){
        date = arguments[2] || new Date();
        switch (strInterval) { 
            case 's ' :return new Date(date.getTime() + (1000 * num));  
            case 'n' :return new Date(date.getTime() + (60000 * num));  
            case 'h' :return new Date(date.getTime() + (3600000 * num));  
            case 'd' :return new Date(date.getTime() + (86400000 * num));  
            case 'w' :return new Date(date.getTime() + ((86400000 * 7) * num));  
            case 'm' :return new Date(date.getFullYear(), (date.getMonth()) + num, date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());  
            case 'y' :return new Date((date.getFullYear() + num), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());  
        }  
    }  
    
    /**
    * 比较日期差 dtEnd 格式为日期型或者有效日期格式字符串
    * @param strInterval string  可选值 y 年 m月 d日 w星期 ww周 h时 n分 s秒  
    * @param dtStart Date  可选值 y 年 m月 d日 w星期 ww周 h时 n分 s秒
    * @param dtEnd Date  可选值 y 年 m月 d日 w星期 ww周 h时 n分 s秒 
    */
    this.dateDiff = function(strInterval, dtStart, dtEnd) {   
        switch (strInterval) {   
            case 's' :return parseInt((dtEnd - dtStart) / 1000);  
            case 'n' :return parseInt((dtEnd - dtStart) / 60000);  
            case 'h' :return parseInt((dtEnd - dtStart) / 3600000);  
            case 'd' :return parseInt((dtEnd - dtStart) / 86400000);  
            case 'w' :return parseInt((dtEnd - dtStart) / (86400000 * 7));  
            case 'm' :return (dtEnd.getMonth()+1)+((dtEnd.getFullYear()-dtStart.getFullYear() )*12) - (dtStart.getMonth()+1);  
            case 'y' :return dtEnd.getFullYear() - dtStart.getFullYear();  
        }  
    }

    /**
    * Convert string to date object
    * @param date Date The format is yyyy-MM-dd HH:mm:ss, which must be in the order of year, month, day, hour, minute, and second, and the middle separator is not limited */
    this.strToDate
    = function(dateStr){
        var data = dateStr;  
        var reCat = /(\ d{1,4})/gm;   
        var t = data.match(reCat);
        t[1] = t[1] - 1;
        eval('var d = new Date('+t.join(',')+');');
        return d;
    }

    /**
    * Convert the string in the specified format to a date object yyyy-MM-dd HH :mm:ss
    * 
    */
    this.strFormatToDate = function(formatStr, dateStr){
        var year = 0;
        var start = -1;
        var len = dateStr.length;
        if((start = formatStr.indexOf('yyyy')) > -1 && start < len){
            year = dateStr.substr(start, 4);
        }
        var month = 0;
        if((start = formatStr.indexOf('MM')) > -1 && start < len){
            month = parseInt(dateStr.substr(start, 2)) - 1;
        }
        var day = 0;
        if((start = formatStr.indexOf('dd')) > -1 && start < len){
            day = parseInt(dateStr.substr(start, 2));
        }
        var hour = 0;
        if( ((start = formatStr.indexOf('HH')) > -1 || (start = formatStr.indexOf('hh')) > 1) && start < len){
            hour = parseInt(dateStr.substr(start, 2));
        }
        var minute = 0;
        if((start = formatStr.indexOf('mm')) > -1  && start < len){
            minute = dateStr.substr(start, 2);
        }
        var second = 0;
        if((start = formatStr. indexOf('ss')) > -1 && start < len){
            second = dateStr. substr(start, 2);
        }
        return new Date(year, month, day, hour, minute, second);
    }


    /**
    * Date object converted to milliseconds
    */
    this.dateToLong = function(date){
        return date.getTime();
    }

    /**
    * Milliseconds converted to date object
    * @param dateVal number milliseconds of the date 
    */
    this.longToDate = function(dateVal){
        return new Date(dateVal);
    }

    /**
    * 判断字符串是否为日期格式
    * @param str string 字符串
    * @param formatStr string 日期格式, 如下 yyyy-MM-dd
    */
    this.isDate = function(str, formatStr){
        if (formatStr == null){
            formatStr = "yyyyMMdd";    
        }
        var yIndex = formatStr.indexOf("yyyy");     
        if(yIndex==-1){
            return false;
        }
        var year = str.substring(yIndex,yIndex+4);     
        var mIndex = formatStr.indexOf("MM");     
        if(mIndex==-1){
            return false;
        }
        var month = str.substring(mIndex,mIndex+2);     
        var dIndex = formatStr.indexOf("dd");     
        if(dIndex==-1){
            return false;
        }
        var day = str.substring(dIndex,dIndex+2);     
        if(!isNumber(year)||year>"2100" || year< "1900"){
            return false;
        }
        if(!isNumber(month)||month>"12" || month< "01"){
            return false;
        }
        if(day>getMaxDay(year,month) || day< "01"){
            return false;
        }
        return true;   
    }
    
    this.getMaxDay = function(year,month) {     
        if(month==4||month==6||month==9||month==11)     
            return "30";     
        if(month==2)     
            if(year%4==0&&year%100!=0 || year%400==0)     
                return "29";     
            else     
                return "28";     
        return "31";     
    }     
    /**
    *    变量是否为数字
    */
    this.isNumber = function(str)
    {
        var regExp = /^\d+$/g;
        return regExp.test(str);
    }
    
    /**
    * 把日期分割成数组 [年、月、日、时、分、秒]
    */
    this.toArray = function(myDate)  
    {   
        myDate = arguments[0] || new Date();
        var myArray = Array();  
        myArray[0] = myDate.getFullYear();  
        myArray[1] = myDate.getMonth();  
        myArray[2] = myDate.getDate();  
        myArray[3] = myDate.getHours();  
        myArray[4] = myDate.getMinutes();  
        myArray[5] = myDate.getSeconds();  
        return myArray;  
    }  
    
    /**
    * 取得日期数据信息  
    * 参数 interval 表示数据类型  
    * y 年 M月 d日 w星期 ww周 h时 n分 s秒  
    */
    this.datePart = function(interval, myDate)  
    {   
        myDate = arguments[1] || new Date();
        var partStr='';  
        var Week = ['日','一','二','三','四','五','六'];  
        switch (interval)  
        {   
            case 'y' :partStr = myDate.getFullYear();break;  
            case 'M' :partStr = myDate.getMonth()+1;break;  
            case 'd' :partStr = myDate.getDate();break;  
            case 'w' :partStr = Week[myDate.getDay()];break;  
            case 'ww' :partStr = myDate.WeekNumOfYear();break;  
            case 'h' :partStr = myDate.getHours();break;  
            case 'm' :partStr = myDate.getMinutes();break;  
            case 's' :partStr = myDate.getSeconds();break;  
        }  
        return partStr;  
    }  
    
    /**
    * 取得当前日期所在月的最大天数  
    */
    this.maxDayOfDate = function(date)  
    {   
        date = arguments[0] || new Date();
        date.setDate(1);
        date.setMonth(date.getMonth() + 1);
        var time = date.getTime() - 24 * 60 * 60 * 1000;
        var newDate = new Date(time);
        return newDate.getDate();
    }
    
    return this;
}();
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  <html>
  <head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
    <script type="text/javascript" src="./DateUtil.js" ></script>

    <script type="text/javascript">
        var date = new Date(); 
        document.write("penngo test DateUtil.js=====================" + date + "<br/>");
        document.write("date========================================" + date + "<br/>");
        document.write("isLeapYear==================================" + DateUtil.isLeapYear(date) + "<br/>");
        document.write("dateToStr===================================" + DateUtil.dateToStr('yyyy-MM-dd HH:mm:ss', date) + "<br/>");
        document.write("dateAdd('d', 2, date)=======================" + DateUtil.dateToStr('yyyy-MM-dd HH:mm:ss', DateUtil.dateAdd('d', 2, date)) + "<br/>");
    
        var date2 = DateUtil.dateAdd('s', 3, date);
        document.write("dateDiff('s', date, date2)==================" + DateUtil.dateDiff('s', date, date2) + "<br/>");
        document.write("strToDate('2013-01-16 00:27:23')============" + DateUtil.strToDate('2013-01-16 00:27:23') + "<br/>");
        document.write("strFormatToDate=============================" + DateUtil.strFormatToDate('yyyy-MM-dd HH:mm:ss', '2013-01-16 00:27:23') + "<br/>");
        document.write("dateToLong==================================" + DateUtil.dateToLong(date) + "<br/>");
        document.write("longToDate==================================" + DateUtil.longToDate(DateUtil.dateToLong(date)) + "<br/>");
        document.write("isDate('2013-01-16 00:27:23', 'yyyy-MM-dd HH:mm:ss')=" + DateUtil.isDate('2013-01-16', 'yyyy-MM-dd') + "<br/>");

        document.write("datePart====================================" + DateUtil.datePart('m', date) + "<br/>");
        document.write("maxDayOfDate================================" + DateUtil.maxDayOfDate(date) + "<br/>");
    </script>
  </head>
  <body>
  </body>
  </html>
============penngo test DateUtil.js==========
date======================== ==================Wed Jan 16 2013 01:14:23 GMT+0800 (China Standard Time)
isLeapYear=============== ==================== false
dateToStr ================================ ======2013-01-16 01:14:23
dateAdd('d', 2, date)==========================2013 -01-18 01:14:23
dateDiff('s', date, date2)=====================3
strToDate('2013-01-16 00:27: 23')=============Wed Jan 16 2013 00:27:23 GMT+0800 (China Standard Time)
strFormatToDate================= =============Wed Jan 16 2013 00:27:23 GMT+0800 (China Standard Time)
dateToLong===================== ===============1358270063903
longToDate==================================Wed Jan 16 2013 01:14:23 GMT+0800 (中国标准时间)
isDate('2013-01-16 00:27:23', 'yyyy-MM-dd HH:mm:ss')=true
datePart====================================14
maxDayOfDate================================31
 

jfinal系统启动时调用的方法和系统停止时调用的方法

public class DemoConfig extends JFinalConfig {
//在系统停止时调用的方法
    public void beforeJFinalStop() {
    
    };
    //在系统启动时调用的方法
    @Override
    public void afterJFinalStart() {
        // TODO Auto-generated method stub
        super.afterJFinalStart();
      
    }
}
 

jfinal拦截器笔记1

Interceptors is the implementation of jfinal aop. It can be configured
precisely .
The Interceptor interface only defines a method void intercept(ActionInvocation ai);
we can make a class implement this interface and rewrite the method, such as:
public class DemoInterceptor implements Interceptor {
public void intercept(ActionInvocation ai) {
System.out.println("Before action invoking");
ai.invoke();
System.out.println("After action invoking");
}
}
Just write an interceptor.
There are three levels of interceptor configuration, global level, controller level, and action level. The global-level interceptor will
intercept all actions, the controller-level interceptor will intercept all actions in the controller, and the action-level interceptor will
only intercept the action.
The global level interceptor is in
public void configInterceptor(Interceptors me) {
        me.add(new DemoInterceptor());            
}
, the controller-level interceptor uses @Before to configure before the controller class is defined, and the action-level interceptor
uses @Before to configure before the action definition. The specific configuration is as follows:
@Before(DemoInterceptor.class) // 配置一个Controller级别的拦截器
public class HelloController extends Controller {
@Before(AaaInterceptor.class)
public void index() {
renderText("配置一个action级别的拦截器");
}
@Before({AaaInterceptor.class, BbbInterceptor.class})
public void test() {
renderText("配置多个action级别的拦截器");
}
@ClearInterceptor
public void login() {
renderText("清除上一级别(Controller级)的拦截器");
}
@ClearInterceptor(ClearLayer.ALL)
public void clearAllLayers() {
renderText("Clear interceptors of all levels (Global level and Controller level)");
}
}
 

jfinal notes 2

The methods of the render series will render different types of views and return them to the client. The view types currently supported by jfinal are: freemarker, jsp, velocity, json, file, text, html, etc. In addition, you can inherit the render abstract class to expand infinitely view type.
Use the render(String) method to render the view, which is to render the view in the request forwarding mode.
When you want to redirect to another action after executing an action, use redirect(getRequest().getContextPath()+"/user") ;
getRequest().getContextPath() is the name of the project,
"/user" is the routing configuration of the mapping of the control class you want to access.
When developing with jfinal, after deploying the project to tomcat, the access will encounter 404 problems. The solution is: 1.
Add the name of the project to each link of the jsp access background method, such as:
<a href="${pageContext.request.contextPath }/user"><b>user management</b></a>
Some static resources should also be added with project names, such as css, js, and so on.
Method 2 to get the project path: configure first
public void configHandler(Handlers me) {
          me.add(new ContextPathHandler("base"));//get project path
    }
transfer
getAttr("base")
method to get the project path
 

jfinal note 3

The interceptor added in the configInterceptor method in jfinal is a global interceptor, so the access will first pass through the interceptor. When only a few classes do not need to pass through the interceptor, but most classes need to pass through the interceptor, configure the global interceptor. Just add @ClearInterceptor (xxx.class) to the class that does not need to go through the interceptor.
, when the interceptor only needs to be called when accessing a specific business, do not add this interceptor to the configInterceptor method, just add @Before(BlogInterceptor.class) in front of the specific business control class.
When you only want to intercept the method, just add @Before() to the method

The getPara series methods are divided into two types. The first type is the getPara series method whose first formal parameter is String. This series of methods is the encapsulation of HttpServletRequest.getParameter(String name), and these methods are all transfers of HttpServletRequest.getParameter(String name). The second type is the getPara series methods whose first formal parameter is int or has no formal parameter. This series of methods is to obtain the parameter values ​​carried in urlPara. getParaMap and getParaNames correspond to getParameterMap and getParameterNames of HttpServletRequest respectively.
Memory skill: If the first parameter is of String type, the field value of the question mark hanging parameter in the form or url will be obtained. The first parameter is an int or the parameter value in urlPara without parameters.
setAttr("", value) transfers the HttpServletRequest.setAttribute("", value) method, which can pass values ​​to the page
 

jfinal note 4

A JFinal-based web project needs to create a subclass inherited from the JFinalConfig class, which is used to configure the entire web project.
The JFinalConfig subclass needs to implement five abstract methods, such as:
public class DemoConfig extends 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) {}
}

configConstant
此方法用来配置 JF inal 常量 值,如开发模式 devMode 的配置,默认 视 图类型 ViewType 的配置 的配置 ,如下 代码 配置了 JFinal 运行在开发模式下且默认视图 类型为 JSP:
public void configConstant(Constants me) {
me.setDevMode(true);
me.setViewType(ViewType.JSP);
}


在开发模式下 ,JFinal会对每次 请求输出报告,如本会对每次 请求输出报告,如本请求的 Controller、 Method 以及请求所携带的参数。 以及请求所携带的参数。JFinal 支持 JSP 、 FreeMarker、Velocity三种常 用视图 。
configRoute
This method is used to configure the JF final access route. The following code configures the mapping of "/hello" to the HelloController controller. Through the following configuration, http://localhost/hello will access the HelloController.index() method, and
http://localhost/hello/other will access the HelloController.other() method.
The mapping between strings and control classes is:
public void configRoute(Routes me) {
me.add("/hello", HelloController.class);
}
The Routes class mainly has the following two methods:
public Routes add(String controllerKey, Class<? extends Controller> controllerClass, String viewPath)
public Routes add(String controllerKey, Class<? extends Controller> controllerClass)


第一个参数 controllerKey是指访问某个 Controller所需要的一个字符串 ,该 字符串唯一对应个 Controller,controllerKey仅能定位到 仅能定位到 Controller。第二个参 数 controll er Class 是该 controllerKey所对应 到的 Controller。第三个参数 view Path 是指 该 Controller返回的视图  的相对路径。当 view Path未指定时默认值为 controllerKey。
1.当url是http://localhost/controllerKey时,调用的是对应控制类的index()方法;
当需要传参数时,url这样写:http://localhost/controllerKey/a-b-c,参数之间用中横线分开,
index()方法中调用getPara(i)得到参数,i是参数对应的下标,例如a的下标是0,b的下标是1,c的下标是2.
2.当url是http://localhost/controllerKey/method时,调用的是对应控制类的method()方法;
3.
JFinal 在以上路由 规则之外 还提供了 ActionKey注解, 可以打破 原有 规则, 以下是代码示例 :
public class HelloController extends Controller{
    @ActionKey("second")
    public void second(){
        System.out.println("0="+getPara(0));
        System.out.println("1="+getPara(1));
        System.out.println("2="+getPara(2));
        renderText("yjw");
    }
}
In this way, the url can be written as http://localhost/second/1-2-3, without writing the mapping of the control class.
4.
If all the above routing rules cannot meet the requirements, developers can also customize more personalized routing according to the need to use the Handler. The general idea is to change the value of the first parameter String target in the Handler.
 

jfinal note 5

     摘要: JFinal主要特点:MVC架构,设计精巧,使用简单 遵循COC原则,零配置,无xml ActiveRecord支持,使数据库开发极致快速 自动加载修改后的java文件,开发过程中无需重启web server AOP支持,拦截器配置灵活,功能强大 Plugin体系结构,扩展性强 多视图支持,支持FreeMarker、JSP、Velocity 强大的Validator后端校验功能 功能齐全,拥有st...   阅读全文
 

在项目启动时调用的方法配置

<bean id="bookOutInThread" class="com.ourselec.eam.filter.BookOutInThread" init-method="runThread"/>
先把一个类交给spring管理,在配置初始化调用的方法
 

Form 表单域与 Java 对象属性的自动装配功能

     摘要: 时下很多 Web 框架 都实现了 Form 表单域与 Java 对象属性的自动装配功能,该功能确实非常有用,试想如果没这功能则势必到处冲积着 request.getParameter() 系列方法与类型转换方法的调用。重复代码量大,容易出错,同时又不美观,影响市容。   现在的问题是,这些框架通过什么方法实现自动装配的?如果不用这些框架我们自己如何去实现呢?尤其对于那些纯 JSP/Servle...   阅读全文
 

jquery学习

jQuery 是一个 JavaScript 函数库。

 

jQuery 库包含以下特性:

  • HTML 元素选取 
  • HTML 元素操作 
  • CSS 操作 
  • HTML 事件函数 
  • JavaScript 特效和动画 
  • HTML DOM 遍历和修改 
  • AJAX 
  • Utilities

通过 jQuery,您可以选取(查询,query) HTML 元素,并对它们执行“操作”(actions)。

————————————————————

jQuery 语法

jQuery 语法是为 HTML 元素的选取编制,可以对元素执行某些操作。
基础语法是:$(selector).action()
美元符号定义 jQuery 
选择符(selector)“查询”和“查找” HTML 元素 
jQuery action() 执行对元素的操作 
实例
$(this).hide() - 隐藏当前元素
$("p").hide() - 隐藏所有段落
$("p.test").hide() - 隐藏所有 class="test" 的段落
$("#test").hide() - 隐藏所有 id="test" 的元素
提示:jQuery 使用的语法是 XPath 与 CSS 选择器语法的组合。在本教程接下来的章节,您将学习到更多有关选择器的语法。

选择器允许您对元素组或单个元素进行操作。

————————————————————

jQuery 选择器

在前面的章节中,我们展示了一些有关如何选取 HTML 元素的实例。
关键点是学习 jQuery 选择器是如何准确地选取您希望应用效果的元素。
jQuery 元素选择器和属性选择器允许您通过标签名、属性名或内容对 HTML 元素进行选择。
选择器允许您对 HTML 元素组或单个元素进行操作。
在 HTML DOM 术语中:
选择器允许您对 DOM 元素组或单个 DOM 节点进行操作。
————————————————————

jQuery 元素选择器

jQuery 使用 CSS 选择器来选取 HTML 元素。
  • $("p") 选取 <p> 元素。

  • $("p.intro") 选取所有 class="intro" 的 <p> 元素。

  • $("p#demo") 选取 id="demo" 的第一个 <p> 元素。
————————————————————

jQuery 属性选择器

jQuery 使用 XPath 表达式来选择带有给定属性的元素。
  • $("[href]") 选取所有带有 href 属性的元素。

  • $("[href='#']") 选取所有带有 href 值等于 "#" 的元素。

  • $("[href!='#']") 选取所有带有 href 值不等于 "#" 的元素。

  • $("[href$='.jpg']") 选取所有 href 值以 ".jpg" 结尾的元素。
————————————————————

jQuery CSS 选择器

jQuery CSS 选择器可用于改变 HTML 元素的 CSS 属性。
更多的实例
语法 描述 
  • $(this) 当前 HTML 元素 
  • $("p") 所有 <p> 元素 
  • $("p.intro") 所有 class="intro" 的 <p> 元素 
  • $(".intro") all elements with class="intro" 
  • $("#intro") the first element with id="intro" 
  • $("ul li:first") the first <li> element of each <ul> 
  • $("[href$='.jpg']") all attributes with an href attribute ending in ".jpg" 
  • $("div#intro .head") All elements with class="head" in the <div> element with id="intro" 
 

Export the current web page to word in ie

<html>
<head>

<script type="text/javascript">
   var oWD = new ActiveXObject("Word.Application");
   var oDC = oWD.Documents.Add("",0,1);
   var oRange =oDC.Range(0,1);
function word(id,way){
   var sel = document.body.createTextRange();
   sel.moveToElementText(id);
   sel.select();
   sel.execCommand(way);
   oRange.Paste();
}

function test(){
   var table=document.getElementById('table1');
   var table_cells = table.rows[0].cells;
   var form_elements = document.getElementById('huahai');
   word(div_content,'Copy'); //调用word函数,将div_content范围内容拷贝到word里面。
   for(i=0;i<table_cells.length;i++){
       oRange =oDC.Range(oRange.End-1,oRange.End); //设定位置依次由上往下、从左往右
       var sel = document.body.createTextRange();
       sel.moveToElementText(table_cells[i]); //将单元格内容复制到word
       sel.select();
       sel.execCommand("Copy");
       sel.moveEnd('character');  //不加这句导出不了,里面参数为character、不是copy
       oRange.Paste();
       oRange =oDC.Range(oRange.End-1,oRange.End);
   }
    oRange =oDC.Range(oRange.End-1,oRange.End); //复制不同的东西,需要写这句继续 写死的这句话就是位置
    var img = document.getElementById('img');
    word(img,'Copy');//将img范围内容拷贝到word里面。
    oRange =oDC.Range(oRange.End-1,oRange.End);
    var text_area = document.getElementById('text_area');
    word(text_area,'Copy');//将text_area范围内容拷贝到word里面。
    oRange =oDC.Range(oRange.End-1,oRange.End);
    oWD.Application.Visible = true; //这句意思是所有操作完毕后,在显示出来,如果写在里面,会发现word打开后,什么标签啊、内容啊就跟打字机一样往里面填
}
</script>
</head>
<body>
<form action="" id="huahai" >
  <div align="center">
   <div align="center" id="div_content">
    <h2>
     <font color="red">测试导出word</font>
    </h2>
    <h4>
     <font color="red">测试导出word</font>
    </h4>
    </div>
<table id="table1">
<tr>
<td>姓名</td><td><input type="text" size="5"></td>
<td>年龄</td><td><input type="text" size="5"></td>
</tr>
<table>
<div id="img">
    <hr/>
    <img src="MM.jpg" height="45%" width="30%">
    </br>
</div>
 <div id="text_area">
    <textarea name="warn_task" wrap="off" cols="80" rows="12">区域内容:</textarea>
    </textarea>
    <hr />
</div>
<input type="button" οnclick="javascript:test();" value="测试">
</div>
 </form>
</body>
</html>
 

javascript4种异步编程方法

"同步模式"就是上一段的模式,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的;"异步模式"则完全不同, 每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执 行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。
"异步模式"非常重要。在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,"异步模式"甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降,很快就会失去响应。

  本文总结了"异步模式"编程的4种方法,理解它们可以让你写出结构更合理、性能更出色、维护更方便的Javascript程序。

  一、回调函数

  这是异步编程最基本的方法。

  假定有两个函数f1和f2,后者等待前者的执行结果。

f1(); f2();
如果f1是一个很耗时的任务,可以考虑改写f1,把f2写成f1的回调函数。
function f1(callback){ 
  setTimeout(function () { 
    // f1的任务代码   
  callback();   }, 1000);
 } 

    
    
     
     
执行代码就变成下面这样:
f1(f2); 
In this way, we have changed the synchronous operation into an asynchronous operation, and f1 will not block the running of the program, which is equivalent to executing the main logic of the program first, and delaying the execution of time-consuming operations.

  The advantage of the callback function is that it is simple, easy to understand and deploy, but the disadvantage is that it is not conducive to the reading and maintenance of the code, the flow of the program will be very confusing, and each task can only specify one callback function.

  Two, event monitoring

  Another way of thinking is to use an event-driven model. The execution of tasks does not depend on the order of the code, but on whether a certain event occurs.

  Still take f1 and f2 as an example. First, bind an event to f1 ( the way jQuery is used here ).

f1.on('done',f2); 
The above line of code means that when the done event occurs in f1, f2 will be executed. Then, rewrite f1:
function f1(){  
 setTimeout(function () {  
   // f1 task code   
  f1.trigger('done'); }, 1000); 
 }

      
      
       
       
f1.trigger('done') means that after the execution is completed, the done event will be triggered immediately, thus starting to execute f2.

  The advantage of this method is that it is easier to understand, multiple events can be bound, and each event can specify multiple callback functions. The disadvantage is that the entire program must become event-driven, and the running process will become very unclear.

  3. Publish/Subscribe

  The "event" in the previous section can be understood as a "signal".

  我们假定,存在一个"信号中心",某个任务执行完成,就向信号中心"发布"(publish)一个信号,其他任务可以向信号中心"订阅"(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做"发布/订阅模式"(publish-subscribe pattern),又称"观察者模式"(observer pattern)。

  这个模式有多种实现,下面采用的是Ben Alman的Tiny Pub/Sub,这是jQuery的一个插件。

  首先,f2向"信号中心"jQuery订阅"done"信号。

jQuery.subscribe("done", f2); 
然后,f1进行如下改写:
function f1(){ 
  setTimeout(function () {
     // f1的任务代码   
  jQuery.publish("done");   }, 1000); 
} 

        
        
         
         
jQuery.publish("done")的意思是,f1执行完成后,向"信号中心"jQuery发布"done"信号,从而引发f2的执行。

  此外,f2完成执行后,也可以取消订阅(unsubscribe)。

jQuery.unsubscribe("done", f2); 
The nature of this method is similar to "event monitoring", but it is obviously better than the latter. Because we can monitor the operation of the program by looking at the "Message Center" to understand how many signals exist and how many subscribers each signal has.

  Four, Promises object

  The Promises object is a specification proposed by the CommonJS working group to provide a unified interface for asynchronous programming .

  Simply put, its idea is that each asynchronous task returns a Promise object, which has a then method that allows specifying a callback function. For example, the callback function f2 of f1 can be written as:

f1().then(f2); 
function f1(){  
 var dfd = $.Deferred(); 
  setTimeout(function () { 
    // task code of f1   
  dfd.resolve();  
 }, 500);  
 return dfd.promise; 
 }

          
          
           
           
The advantage of writing this way is that the callback function becomes a chain writing method, the program flow can be seen clearly, and there is a whole set of supporting methods that can realize many powerful functions.

  For example, to specify multiple callback functions:

f1().then(f2).then(f3); 
For another example, specify a callback function when an error occurs:
f1().then(f2).fail(f3); 
而且,它还有一个前面三种方法都没有的好处:如果一个任务已经完成,再添加回调函数,该回调函数会立即执行。所以,你不用担心是否错过了某个事件或信号。这种方法的缺点就是编写和理解,都相对比较难。

 

extjs中directjngine的配置

第一步,在web.xml中配置DirectJNgine Servlet.我配置的web.xml如下:
在web.xml配置文件中写:
    <?xml version="1.0" encoding="UTF-8"?>  
    <web-app version="2.5"   
        xmlns="http://java.sun.com/xml/ns/javaee"   
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
    <!-- 以下为DirectJNgine servlet 默认配置-->  
      <servlet>  
        <servlet-name>DjnServlet</servlet-name>  
        <servlet-class>com.softwarementors.extjs.djn.servlet.DirectJNgineServlet</servlet-class>  
         
        <init-param>  
          <param-name>debug</param-name>  
          <param-value>true</param-value>  
        </init-param>    
      
        <init-param>  
          <param-name>providersUrl</param-name>  
          <param-value>djn/directprovider</param-value>  
        </init-param>  
    <!-- DirectJNgine servlet 默认配置-->  
      
    <!-- api域:对应下面的各个param-name的前缀,可以设置多个不同的域-->  
        <init-param>  
          <param-name>apis</param-name>  
          <param-value>  
            mynamespace  
          </param-value>  
        </init-param>  
      
    <!-- mynamespace对应上面的api域。MyAction对应生成的js相应的文件夹.服务器运行后,将在MyAction/下存放自动生成的3个js文件。这里的名称分别为  
        MyActionApi.js,MyActionApi-debug.js,MyActionApi-min.js  
     -->   
        <init-param>  
          <param-name>mynamespace.apiFile</param-name>  
          <param-value>MyAction/MyActionApi.js</param-value>  
        </init-param>  
    <!-- mynamespace.对应上面的域."Ext.zhouyang"为命名空间所对应的值。会在页面加载时候用上. -->  
        <init-param>  
          <param-name>mynamespace.apiNamespace</param-name>  
          <param-value>Ext.zhouyang</param-value>  
        </init-param>  
    <!-- mynamespace.对应上面的域. 要使用的类的全路径名 -->  
        <init-param>  
          <param-name>mynamespace.classes</param-name>  
          <param-value>  
          com.softwarementors.extjs.djn.MyAction.MyAction  
          </param-value>  
        </init-param>  
          
        <load-on-startup>1</load-on-startup>  
      </servlet>   
       
      <servlet-mapping>  
        <servlet-name>DjnServlet</servlet-name>  
        <url-pattern>/djn/directprovider/*</url-pattern>  
      </servlet-mapping>  
        
      <welcome-file-list>  
        <welcome-file>  
          index.html  
        </welcome-file>  
      </welcome-file-list>  
    </web-app>   

第二步,使你的服务器端方法对JavaScript可见,其实就是说对客户端可见。

以我的demo为例,我想在hello.html中调用服务器端的方法。于是,我在hello.html中添加如下一段话。

  <!--以下为DirectJNgine的基础JS文件,放在djn目录下,直接引用就可以。-->
  <script type="text/javascript" src="../djn/djn-remote-call-support.js"></script>
  <script type="text/javascript" src="../ejn/ejn-assert.js"></script>
  <!--以上为DirectJNgine的基础JS文件.-->
  <script type="text/javascript" src="MyActionApi.js"></script>

前两个script引用,是用来调用directjngine提供的默认的一些操作函数。只需引用即可,不需要关注太多。

The last js, you can't see it before starting the server. Because it is a directjngine project, it is automatically generated according to your configuration. As for what it is, I will introduce it in detail below.

 

The third step is to design the server-side method. Such as the function name, whether to return a value, and so on. Because on the hello.html page, I'm going to call the method.

The specific calling code will be described in the final hello.html code description section.

 

The fourth step is to use the Java language to write the server-side method. The attached code is as follows:

  1. package com.softwarementors.extjs.djn.MyAction;  
  2. import com.softwarementors.extjs.djn.config.annotations.DirectMethod;  
  3. public class MyAction {  
  4.     @DirectMethod  
  5.     public String doEcho(String parm)  
  6.     {  
  7.         return "The parameter is" + parm;  
  8.     }  
  9.     @DirectMethod  
  10.     public String doShow()  
  11.     {  
  12.         return "i am not easy";  
  13.     }  
  14. }  
Notice:

The @DirectMethod tag is very important. It is through this tag and some configurations in web.xml that the js that needs to be introduced in the second step will be dynamically generated. In this way of writing, the method name you write in the Java code is the method name you call in the foreground JS. If you feel like this is unsafe or unprofessional. Then the method can be accessed by defining an alias. The written form is as follows:

@DirectMethod( method="nameyouwant")

After this definition, when the front-end JS calls the server-side method, the name of the method is the name you defined in red.

After compiling the class, put the class file into the corresponding package directory of WEB-INF\classes. It should be the same as the directory structure of the package of the class file in web.xml.

 

The fifth step is to tell DirectJNgine where to find the server-side methods.

In the configuration of web.xml, there is the following code:

    <init-param>
      <param-name>mynamespace.classes</param-name>
      <param-value>
      com.softwarementors.extjs.djn.MyAction.MyAction
      </param-value>
    </init-param>

It should be noted here that the red part of mynamespace.classes must be the same as the mynamespace of the apis variable above web.xml.

Secondly, com.softwarementors.extjs.djn.MyAction.MyAction is the full path name of the class written in the fourth step. If there are multiple classes, separate them with commas.

 

The sixth step, in order for Extjs to call our server-side method, we need to register a remote call provider, a remoting provider. All you need to do is to add the following statement to the hello.html code to register a remote call provider for a certain space:

//Here, through the namespace, add and initialize the remote call API
Ext.zhouyang.REMOTING_API.enableBuffer = 0;
Ext.Direct.addProvider(Ext.zhouyang.REMOTING_API);

Note: Ext.zhouyang above is already defined in the web.xml variable mynamespace.apiNamespace.

 

The seventh step is to call the server-side method through JavaScript.

MyAction.doShow(function(result, e){
    var t = e.getTransaction();
    if(e.status){
        out.append(
                           String.format('<p><b>Successful call to {0}.{1} with response:</b><xmp>{2}</xmp></p>',
               t.action, 
                           t.method, 
                           Ext.encode(result)));
    }else{
        out.append(
                           String.format('<p><b>Call to {0}.{1} failed with message:</b><xmp>{2}</xmp></p>',
               t.action, 
                           t.method, 
                           e.message));
        }
        out.el.scroll('b', 100000, true);
    });        
    
    //doEcho function, this function has parameters.
    var parm = txtparm.value; //The parameters to be passed to the background
    MyAction.doEcho(parm, function(result, e){
        var t = e.getTransaction();
        if(e.status){
            out.append(String. format('<p><b>Successful call to {0}.{1} with response:</b><xmp>{2}</xmp></p>',
                t.action, t.method, Ext.encode(result)));
        }else{
            out.append(String.format('<p><b>Call to {0}.{1} failed with message:
                t.action, t.method, e.message));
        }
        out.el.scroll('b', 100000, true);
    });                       

上面的代码排版有点乱,这里先做些说明,这个demo的下载网址,我最后会附送。可以直接查看代码。

 

可以看到,对于函数的结构。如果需要传入参数,则把参数写在函数前面。

因为JavaScript调用服务器端方法是异步的,所以,最好的方法就是定义一个回调函数处理数据,而不是让程序终止。

所以,对于上面的两个方法,最后都定义了一个回调函数。这个函数的作用是用来处理服务器端返回的数据。

参数result是服务器端方法返回的数据,e是一个even对象,包括一个事务对象,这个对象包含action和method的名称和其他一些信息。

 

e.status表示服务器端成功执行了函数。如果返回false,则表示服务器端出现了错误。通过e.message就可以查看出错信息。

 

其他参数说明:

  • <init-param>  
  •   <param-name>debug</param-name>  
  •   <param-value>true</param-value>  
  • </init-param>


如果设置为true,在tomcat的log目录下的stdout_2010****.log文件中会输入相关的打印信息。如:
INFO : com.softwarementors.extjs.djn.servlet.DirectJNgineServlet - "Servlet GLOBAL configuration: debug=true, providersUrl=djn/directprovider, minify=true, batchRequestsMultithreadingEnabled=true, batchRequestsMinThreadsPoolSize=16, batchRequestsMaxThreadsPoolSize=80, batchRequestsMaxThreadsPerRequest=8, batchRequestsMaxThreadKeepAliveSeconds=60, gsonBuilderConfiguratorClass=com.softwarementors.extjs.djn.gson.DefaultGsonBuilderConfigurator, dispatcherClass=com.softwarementors.extjs.djn.servlet.ssm.SsmDispatcher, jsonRequestProcessorThreadClass=com.softwarementors.extjs.djn.servlet.ssm.SsmJsonRequestProcessorThread, contextPath=--not specified: calculated via Javascript--, createSourceFiles=true" ()
INFO : com.softwarementors.extjs.djn.servlet.DirectJNgineServlet - "Servlet GLOBAL configuration: registryConfiguratorClass=" ()
INFO : com.softwarementors.extjs.djn.servlet.DirectJNgineServlet - "Servlet APIs configuration: apis=mynamespace" ()
INFO : com.softwarementors.extjs.djn.servlet.DirectJNgineServlet - "Servlet 'mynamespace' Api configuration: apiNamespace=Ext.zhouyang, actionsNamespace=, apiFile=MyAction/MyActionApi.js => Full api file: C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps\directdemo\MyAction\MyActionApi.js, classes=com.softwarementors.extjs.djn.MyAction.MyAction" ()
INFO : com.softwarementors.extjs.djn.jscodegen.CodeFileGenerator - "Creating source files for APIs..." ()

如果非调试状态,则可以置为false。

 

完成上面的步骤后,启动tomcat,发现在\Tomcat 6.0\webapps\directdemo\MyAction 目录下生成了三个文件。

如下:

MyActionApi.js,MyActionApi-debug.js,MyActionApi-min.js。其中的MyActionApi.js就是我们在第二步中引入的JavaScript。

它的作用相当于Server端代码的API一样,因为有它的存在,客户端的网页才知道服务器端都定义了些什么方法。我的demo中,生成的MyActionApi.js的代码如下:

/**********************************************************************
 * 
 * Code generated automatically by DirectJNgine
 * Copyright (c) 2009, Pedro Agulló Soliveres
 * 
 * DO NOT MODIFY MANUALLY!!
 * 
 **********************************************************************/

Ext.namespace( 'Ext.zhouyang');

Ext.zhouyang.PROVIDER_BASE_URL=window.location.protocol + '//' + window.location.host + '/' + (window.location.pathname.split('/').length>2 ? window.location.pathname.split('/')[1]+ '/' : '')  + 'djn/directprovider';

Ext.zhouyang.POLLING_URLS = {
}

Ext.zhouyang.REMOTING_API = {
  url: Ext.zhouyang.PROVIDER_BASE_URL,
  type: 'remoting',
  actions: {
    MyAction: [
      {
        name: 'doEcho'/*(String) => String */,
        len: 1,
        formHandler: false
      },
      {
        name: 'doShow'/*() => String */,
        len: 0,
        formHandler: false
      }
    ]
  }
}
It can be seen that the function name, parameter type, number of parameters, etc. are all defined.

 So far, directjngine and Ext Direct call the Java server-side method and you're done.

 

pass by value and pass by reference

在java中,栈内存存放基本类型的值,存放引用类型数据在堆内存的内存首地址,例如,int a = 1;void add(int a){a+=1};
a最后输出还是1,这是值传递,不会改变
栈内存存放基本类型的
值。但是当传入的是引用类型的数据时,因为栈内存存放的是引用类型数据在堆内存的内存首地址不是具体的值,所以会改变引用类型的值
 

extjs按条件查询分页不丢失数据方法

分页查询时加上
itemid = deviceIdCtl.getValue();
                                rfid1 = rfid.getValue();
                                if (itemid == undefined || itemid == '')
                                    itemid = "";
                                if (rfid1 == undefined || rfid1 == '')
                                    rfid1 = "";

    typeStore.on("beforeload",function(){ //The paging condition does not lose the method                                
                                    typeStore.baseParams={
                                            'itemid' : itemid,'rfid' : rfid1
                                           }
                                    });
                                typeStore.load( {
                                    params : {
                                        'itemid' : itemid,
                                        'rfid' : rfid1,
                                        'start' : 0,
                                        ' limit' : 20
                                    }
                                });
 

js笔记

1.多个script标签中的内容,可以在一起执行
2.script脚本代码可以作为属性值<a href="javascript:alert(1);"></a>
3.在HTML事件中也可以执行script代码。οnclick="alert(11)"
4.script区分大小写

1.在加号运算符是,如果表达式中有一个是字符串,运算结果就是字符串
2.在script中除号得出的结果不是整除,如果除不尽,有小数
3.在位运算是,&表示只有参加运算的俩位都是1,结果才是1,否则是0。
|表示只有参加运算的俩位都是0,结果才是0,否则是1。
^(异或)表示只有参加运算的俩位不同,结果才是1,否则是0


在函数中修改参数值的问题
将基本数据类型变量作为函数参数传递

function add(x){ 
    x = 5;
}
var x = 3;
add(x);
alert(x);
x还是3
 

log4j配置

1.引入jar包
2.建立
log4j.properties文件放在src下
3.在servlet 的init方法中写
 String class_path =  getClass().getResource("/").getPath();  
        PropertyConfigurator.configure(class_path+"log4j.properties");//获取 log4j 配置文件  
        Logger logger = Logger.getLogger(IndexServlet.class ); //获取log4j的实例,IndexServlet是当前java文件的名字
在web.xml中写
<servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>IndexServlet</servlet-name>
    <servlet-class>com.test.yjw.IndexServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
   
  </servlet>

  <servlet-mapping>
    <servlet-name>IndexServlet</servlet-name>
    <url-pattern>/indexservlet</url-pattern>
  </servlet-mapping>
 
就会在系统启动时加载  
 

js操作xml

JavaScript操作XML是通过XML DOM来完成的  Ie 下面是用ActiveX对象来实现的。
那么什么是XML DOM呢?
XML DOM 是:
  • 用于 XML 的标准对象模型
  • 用于 XML 的标准编程接口
  • 中立于平台和语言
  • W3C 的标准
XML DOM 定义了所有XML 元素的对象和属性,以及访问它们的方法(接口)。
也就是说:
XML DOM 是用于查询、添加、修改、删除XML 元素的标准。 

ie创建 xml
function xmlcreate() {
var version = [
'MSXML2.DOMDocument6.0',
'MSXML2.DOMDocument3.0',
'MSXML2.DOMDocument'
];
    for(var i=0; i<version.length;i++) {
         try {
            var xml = new ActiveXObject(version[i]);
            return xml;
         }catch(e) {
             
         }
    }
    throw new Error('您的系统不支持MSXML库');
}


//Load XML file, two ways: 1. Load XML character loadXML(); 2. Load XML external file load()
xml.loadXML('<root>\n<user>Lee</user>\n</root>'); //load XML string
alert(xml.xml);
Printing the first content must use standard DOM
alert(xml.getElementsByTagName('user')[0].firstChild.nodeValue);

load external xml
xml.load('a.xml');

Dynamically add xml
xml.load('a.xml');
var b = xml.createElement('bbb');
var root = xml.documentElement;
root.appendChild(b);
alert(xml.xml);

Server side synchronous/asynchronous
On the server side, asynchronous loading is used by default. If it is not loaded, it will definitely not print out.

Set this value to false to load synchronously
xml.async = false;
But if the xml is too large, it will cause a state of suspended animation

But asynchronous is better, but what should I do if I can't get the content asynchronously? 

there is an event

xml.onreadystatechange = function

This event can determine whether the loading is complete, but the event needs to be loaded first, first load the event into the memory, and then load the xml  

事件里面有个属性  xml.readyState  可以判断是否加载完成

这个函数等xml全部加载好 开始处理
xml.onreadystatechange = function() {
    if(xml.readyState ==4){    //如果正确就输出
        if(xml.parseError == 0) {
            alert(xml.xml);
        }else {   //如果错误 就返回
            var a = "错误代码"+xml.parseError.errorCode+'\r\n';
            a += "错误行号"+xml.parseError.line+'\r\n';
            a += "错误上一行"+xml.parseError.linepos+'\r\n';
            a += "错误信息"+xml.parseError.reason+'\r\n';
           alert(a); 
        }
    }
}

DOM2操作xml
//create  xml  第一个参数 命名空间 第二个 根节点 第三个 文档声明
var xml = document.implementation.createDocument('','root',null);   //创建xml
var user = xml.createElement('user');               
xml.documentElement.appendChild(user);             //插入user
alert(xml.getElementsByTagName('user')[0].tagName);   //取得user

dom2 also has a load method that is also asynchronous by default and can be loaded by setting synchronization

get a message
var xml = document.implementation.createDocument("",'root',null);
xml.async = false;
xml.load('a.xml');
alert(xml.getElementsByTagName('url')[0].firstChild.nodeValue);

You can also pass textContent but ie does not support  
alert(xml.getElementsByTagName('url')[0].textContent);

If the dom is asynchronous, how to judge whether the loading is complete? It can be judged by the load method, which is much simpler than ie.
var xml = document.implementation.createDocument("",'root',null);
xml.onload = function(){
alert(xml.getElementsByTagName('url')[0].textContent);
}
xml.load('a.xml');

ps  不过 load 只支持 firefox  和最新版本的opera
但是 w3c提供了2个对象处理xml

var xml = new DOMParser(); //实例化xml对象
var a= "<root><user>gwyy</user></root>";
var xmldom = xml.parseFromString(a,'text/xml');   //通过xml对象创建xml
var seria = new XMLSerializer()     //序列号xml
var z = seria.serializeToString(xmldom);
alert(z);

DOM2没有错误对象  出错了 会给你返回一段xml格式的错误信息  
//判断错误
var errors = xmldom.getElementsByTagName('parsererror');
if(errors.length > 0) {
    throw new Error('错误信息:'+errors[0].textContent);
}



下面是跨浏览器创建xml 
//跨浏览器创建
function createxml(xmlstr) {
    var xml = null;
    if(typeof window.DOMParser != "undefined") {
        xml = (new DOMParser).parseFromString(xmlstr,'text/xml');
        var errors = xml.getElementsByTagName('parsererror');
        if(errors.length > 0){
           throw new Error('Error message:'+errors);
        }
    } else if(typeof window.ActiveXObject != "undefined") {
        var version = [
'MSXML2.DOMDocument6.0',
'MSXML2.DOMDocument3.0',
'MSXML2.DOMDocument'
        ];
        for(var i=0;i<version.length;i++) {
             try{
                xml = new ActiveXObject(version[i]);
                return xml;
             }catch(e){
             }
        }
        xml.loadXML(xmlstr);
        if(xml.parseError != 0) {
            throw new Error('错误信息'+xml.parseError.reason);
        }

        return xml;
    } else {
        throw new Error('你的系统或浏览器不支持xml');
    }
    

    return xml;
}




//序列化
function serializerXMl(xmlstr) {
 var xml = "";
 if(typeof window.XMLSerializer != "undefined") {
    xml = (new XMLSerializer()).serializeToString(xmlstr);
 } else if(typeof xmlstr.xml != "undefined"){
     xml = xmlstr.xml;
 }
 return xml;
}

//accomplish
var xmlstr = "<root><user>aaaa</user></root>";

var xmldom = createxml(xmlstr);

alert(serializerXMl(xmldom));


For cross-browser xml, you can only give up loading xml from outside
 

The difference between strut1 and strut2

PK 1. Commonly used classes:

Ostrich1:

ActionServlet[process()]: After the ActionServlet instance receives the HTTP request, the process() method will be called in the doGet() or doPost() method to process the request;

RequestProcessor[processPreprocess()] : When ActionServlet receives a client request, it will perform a series of initialization operations, and then transfer the client request to a suitable processor for processing. The suitable processor is org.apache.struts. action.RequestProcessor, call the processPreprocess() method. This method does not perform any operations and returns true directly. Subclasses can override this method to perform customized preprocessing request operations;

PlugIn : Mainly used for filters, plug-ins (data type conversion), internationalization, etc. in struts1.x;

Action:ForwardAction、includeAction、DispatchAction、MappingDispatchAction、LookupDispatchAction、SwitchAction的实现接口;

ActionForm:ActionForm用于封装用户的请求参数,而请求参数是通过JSP页面的表单域传递过来的。因此应保证ActionForm的参数,与表单域的名字相同;

ActionForward:ActionForward 是 Struts的核心类之一,其基类仅有4个属性:name / path / redirect / classname。在基于Struts的Web应用程序开发过程中,Action操作完毕后程序会通过Struts的配置文件struts- config.xml链接到指定的ActionForward,传到Struts的核心类ActionServlet,ActionServlet使用 ActionForward提供的路径,将控制传递给下一个步骤。ActionForward控制接下来程序的走向。ActionForward代表一个 应用的URI,它包括路径和参数,例如:path=“/modify.do?method=edit&id=10”;

ActionMapping:将 特定请求映射到特定Action的相关信息存储在ActionMapping中,ActionServelt将ActionMapping传送到 Action类的perform()方法,Action将使用ActionMapping的findForward()方法,此方法返回一个指定名称的 ActionForward,这样Action就完成了本地转发。若没有找到具体的ActionForward,就返回一个null;

struts-config.xml: struts-config.xml is the main configuration file of Struts, in this file, you can configure the data source, form-bean, action and plug-in (plug-in) and resource file information.

-------------------------------------------------------------------------------------------------------------------

Struts2:

FilterDispatcher: org.apache.struts2.dispatcher.FilterDispatcher is the main Filter of Struts2, which is responsible for four functions: executing Actions, clearing ActionContext, maintaining static content, and clearing XWork interceptors in the request life cycle;

ActionSupport: The ActionSupport class is a tool class that has implemented the Action interface. In addition, it also implements the Validateable interface to provide data validation functions. Action development of Struts 2 can be simplified by inheriting from the ActionSupport class.

ServletActionContext[getResponse()]: Struts 2 uses the ServletActionContext class to maintain Servlet objects, and puts Servlet objects in ServletActionContext, such as request, response, application, and Session. ServletActionContext uses ThreadLocal to maintain Servlet objects of different threads, so it can be obtained by using the ServletActionContext class. This method can also be called non-injection method (non-IoC method);

ModelDriven[getModel()]: Implementing the modelDriven interface can directly obtain the User object in the action, and it will put the User obtained by ObjectgetModel() into the ValueStack. It can be understood as adding the attribute of this User to the Action. Its main function is to realize the FormBean function similar to Struts;
MethodFilterInterceptor: Struts2 provides a MethodFilterInterceptor class to filter the methods in Action. MethodFilterInterceptor is a subclass of the AbstractInterceptor class. If you want to implement the interceptor method filtering function, you need to inherit MethodFilterInterceptor. Users only need to rewrite doInterceptor(ActionInvocation action) in MethodFilterInceptor. Its content is actually the same as the interceptor.

struts.xml:struts.xml 为Struts 2的核心配置文件。struts.xml文件主要负责管理应用中的Action映射,以及该Action包含的Result定义等。struts.xml 中主要配置Struts项目的一些全局的属性,用户请求和响应Action之间的对应关系,以及配置Action中可能用到的参数,以及处理结果的返回页 面。还包括各种拦截器的配置等。

 

 

======================================================================================================

PK 二、工作流程:

Struts1:

发布Struts Web服务时,根据web.xml初始化ActionServlet,ActionContext等内容.在接到一个HttpRequest请求 后,ActionServlet 根据struts-config.xml中的配置内容,将请求的参数传到对应的Formbean中,并设置session.然后根据请求中的Action 参数,在struts-config.xml中查找指定的Action,并调用此Action来处理请求.根据Action的处理结果,会返回一个forward变量,此时通过mapping.findForward()查找出对应的forward所标示的Action或者JSP页面,将请求转到下一个处理.如果是forward指向JSP页面,则输出到前台.

---------------------------------------------------------------------------------------------------

Struts2:

(1) The client submits a HttpServletRequest request (.action or JSP page);
(2) The request is submitted to a series of Filter filters, such as ActionCleanUp and FilterDispatcher;
(3) FilterDispatcher is the core of the Struts2 controller, which is usually The last filter in the filter chain;
(4) After the request is sent to FilterDispatcher, FilterDispatcher asks ActionMapper whether it needs to call an Action to process the Request (generally judged according to whether the URL suffix is ​​.action); (5)
If ActionMapper It is decided that a certain Action needs to be called, and the FilterDispatcher sends the request to ActioProxy for processing;
(6) ActionProxy asks the configuration file of the framework through Configuration Manager (it will access struts.xml), and finds the Action class that needs to be called;
(7) )ActionProxy creates an ActionInvocation instance, and ActionInvocation calls Action through the proxy mode, (all related Interceptor interceptors will be loaded according to the configuration file before calling); (8) After the Action is executed,
a result string is returned, and then press The reverse order passes through the Interceptor interceptor;
(9) Finally, ActionInvocation is responsible for finding the result corresponding to the return value according to the result element configured in struts.xml, and deciding to proceed to the next step of output.

 

PK 3. The difference and comparison between Struts1 and Struts2:

Action class:

Struts1 requires the Action class to inherit an abstract base class. A common problem with Struts1 is programming with abstract classes instead of interfaces.
Struts2, Action class can implement an Action interface, and can also implement other interfaces, making optional and customized services possible. Struts2 provides an ActionSupport base class to implement common interfaces. The Action interface is not necessary, any POJO object marked with execute can be used as the Action object of Struts2.

Thread mode:

Struts1, Action is a singleton pattern and must be thread-safe, because there is only one instance of Action to handle all requests. The singleton strategy limits what Struts1 Action can do, and special care must be taken during development. Action resources must be thread-safe or synchronized.                                                                              

Struts2, Action object generates an instance for each request, so there is no thread safety problem. (Actually, the servlet container generates many discardable objects per request, and it does not cause performance and garbage collection problems).

Servlets depend on:

Struts1, Action depends on Servlet API, because HttpServletRequest and HttpServletResponse are passed to the execute method when an Action is invoked.     

Struts2 and Action do not depend on the container, allowing Action to be tested independently of the container. Struts2 Action can still access the original request and response if needed. However, other elements reduce or eliminate the need for direct access to HttpServetRequest and HttpServletResponse.

Testability:

Struts1、 测试Struts1 Action的一个主要问题是execute方法暴露了servlet API(这使得测试要依赖于容器)。一个第三方扩展--Struts TestCase--提供了一套Struts1的模拟对象(来进行测 试)。                                                                                      

Struts2、Action可以通过初始化、设置属性、调用方法来测试,“依赖注入”支持也使测试更容易。

捕获输入:

Struts1、 使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类。因为其他JavaBean不能用作ActionForm,开发者经 常创建多余的类捕获输入。动态Bean(DynaBeans)可以作为创建传统ActionForm的选择,但是,开发者可能是在重新描述(创建)已经存 在的JavaBean(仍然会导致有冗的 javabean)。                                                                                                                

Struts2、 直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能够通过 web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种 ModelDriven 特性简化了taglib对POJO输入对象的引用。

表达式语言:

Struts1、整合了JSTL,因此使用JSTL EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很弱。使用标准JSP机制把对象绑定到页面中来访问。

Struts2 and Struts2 can use JSTL, but also support a more powerful and flexible expression language - "Object Graph Notation Language" (OGNL). Bind values ​​​​to pages (views). Using "ValueStack" technology, taglib can access the value without binding your page (view) to the object. ValueStack strategies allow reusing pages (views) through a series of properties with the same name but different types.

Type conversion:

Struts1, ActionForm properties are usually String type. Struts1 uses Commons-Beanutils for type conversion. One converter per class, not configurable per instance.

Struts2, use OGNL for type conversion. Provides converters for basic and commonly used objects.

check:

Struts1 supports manual verification in the validate method of ActionForm, or verification through the extension of Commons Validator. The same class can have different validation content, but subobjects cannot be validated.

Struts2 supports validation through the validate method and the XWork validation framework. The XWork validation framework supports chain validation sub-properties using validation and content validation defined for attribute class types.

Action execution control:

Struts1 supports each module to have a separate Request Processors (life cycle), but all Actions in the module must share the same life cycle.

Struts2 supports the creation of different life cycles for each Action through Interceptor Stacks. The stack can be used with different Actions as needed.
 

java read xml data method

xml file:

  XML code


  <?xml version="1.0" encoding="GB2312"?>  
  <RESULT> 
  <VALUE> 
  <NO>A1234</NO> 
  <ADDR>河南省郑州市</ADDR> 
  </VALUE> 
  <VALUE> 
  <NO>B1234</NO> 
  <ADDR>河南省郑州市二七区</ADDR> 
  </VALUE> 
  </RESULT>

第一种 DOM 实现方法:

  Java代码


    import java.io.File; 
  import javax.xml.parsers.DocumentBuilder; 
  import javax.xml.parsers.DocumentBuilderFactory; 
  import org.w3c.dom.Document; 
  import org.w3c.dom.NodeList; 
  public class MyXMLReader2DOM { 
  public static void main(String arge[]) { 
  long lasting = System.currentTimeMillis(); 
  try { 
  File f = new File("data_10k.xml"); 
  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
  DocumentBuilder builder = factory.newDocumentBuilder(); 
  Document doc = builder.parse(f); 
  NodeList nl = doc.getElementsByTagName("VALUE"); 
  for (int i = 0; i < nl.getLength(); i++) { 
  System.out.print("Vehicle plate number: "+ doc.getElementsByTagName("NO").item(i).getFirstChild().getNodeValue()); System.out.println 
  ("Owner address: "+ doc.getElementsByTagName ("ADDR").item(i).getFirstChild().getNodeValue()); 
  System.out.println("Elapsed time: " + (System.currentTimeMillis() - lasting) 
  + "milliseconds"); 
  } 
  } 
  } catch (Exception e) { 
  e. printStackTrace(); 
  } 
  } 
  }

  The second, DOM4J implementation method:

  java code


    import java.io.*; 
  import java.util.*; 
  import org.dom4j.*; 
  import org.dom4j.io.*; 
  public class MyXMLReader2DOM4J { 
  public static void main(String arge[]) { 
  long lasting = System.currentTimeMillis(); 
  try { 
  File f = new File("data_10k.xml"); 
  SAXReader reader = new SAXReader(); 
  Document doc = reader.read(f); 
  Element root = doc.getRootElement(); 
  Element foo; 
  for (Iterator i = root.elementIterator("VALUE"); i.hasNext();) { 
  foo = (Element) i.next(); 
  System.out.print("车牌号码:" + foo.elementText("NO")); 
  System.out.println("车主地址:" + foo.elementText("ADDR")); 
  } 
  System.out.println("运行时间:" + (System.currentTimeMillis() - lasting) 
  + "毫秒"); 
  } 
  } catch (Exception e) { 
  e.printStackTrace(); 
  } 
  } 
  }

  第三种 JDOM实现方法:

  Java代码


    import java.io.*; 
  import java.util.*; 
  import org.jdom.*; 
  import org.jdom.input.*; 
  public class MyXMLReader2JDOM { 
  public static void main(String arge[]) { 
  long lasting = System.currentTimeMillis(); 
  try { 
  SAXBuilder builder = new SAXBuilder(); 
  Document doc = builder.build(new File("data_10k.xml")); 
  Element foo = doc.getRootElement(); 
  List allChildren = foo.getChildren(); 
  for (int i = 0; i < allChildren.size(); i++) { 
  System.out.print("车牌号码:"+ ((Element) allChildren.get(i)).getChild("NO").getText()); 
  System.out.println("车主地址:"+ ((Element) allChildren.get(i)).getChild("ADDR").getText()); 
  } 
  System.out.println("运行时间:" + (System.currentTimeMillis() - lasting) 
  + "毫秒"); 
  } 
  } catch (Exception e) { 
  e.printStackTrace(); 
  } 
  } 
  }

  第四种SAX实现方法:

  Java代码


 import javax.xml.parsers.SAXParser; 
  import javax.xml.parsers.SAXParserFactory; 
  import org.xml.sax.Attributes; 
  import org.xml.sax.InputSource; 
  import org.xml.sax.SAXException; 
  import org.xml.sax.helpers.DefaultHandler; 
  public class MyXMLReader2SAX extends DefaultHandler { 
  java.util.Stack tags = new java.util.Stack(); 
  public MyXMLReader2SAX() { 
  super(); 
  } 
  public static void main(String args[]) { 
  long lasting = System.currentTimeMillis(); 
  try { 
  SAXParserFactory sf = SAXParserFactory.newInstance(); 
  SAXParser sp = sf.newSAXParser(); 
  MyXMLReader2SAX reader = new MyXMLReader2SAX(); 
  sp.parse(new InputSource("data_10k.xml"), reader); 
  } catch (Exception e) { 
  e.printStackTrace(); 
  } 
  System.out.println("运行时间:" + (System.currentTimeMillis() - lasting) 
  + "毫秒"); 
  } 
  public void characters(char ch[], int start, int length) 
  throws SAXException { 
  String tag = (String) tags.peek(); 
  if (tag.equals("NO")) { 
  System.out.print("车牌号码:" + new String(ch, start, length)); 
  } 
  if (tag.equals("ADDR")) { 
  System.out.println("地址:" + new String(ch, start, length)); 
  } 
  } 
  public void startElement(String uri, String localName, String qName, 
  Attributes attrs) { 
  tags.push(qName); 
  } 
  }
 

Understanding of java reflection

Beginners may wonder what reflection is and what it does. Then I'll start with a simple little requirement. Now there are 3 classes, A, B, C. Now I want a method to get the corresponding instance object according to the input string, that is, when I pass in "A" to this object, I want to get an A Instance, when "B" is passed in to get a B instance, some people say to use if, so if there are 1000 classes, should we use 1000 if or case, and if we don't know how many cases there are in advance?

To solve this problem, let's start with the basics.

在Java程序执行的时候,在这个进程中,内存分为代码区,静态存储区,堆内存和栈内存。一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。堆内存用于存放由new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。静态存储区,主要是用来存储字符串和类的静态成员变量等。现在说到了对于反射来讲很重要的一块内存,代码区(CodeSegment)。代码区主要存放的是加载到内存的二进制文件。注意,这不是对象实例,而是那些一个个还没有被唤醒的.class文件。

从面相对象的角度来讲,这些文件都是一类,都是Class类。至于如何理解.class文件对象和实例对象,我是这样理解的。在代码区的.class对象就像是下载视频的种子,虽然它并不是一个实实在在的视频,但是必须要通过这个种子才能获得视频文件,而且一个种子可以使用多次。相对应的,在程序中.class文件对象,要通过这个对象来获取需要的对象,而且能多次使用。

在Java虚拟机中,有一个很重要的搬运工的角色,就是ClassLoader,这是一大类Class,它们的作用就是把相应的用到的二进制的Class文件加载到内存中。注意,这里有一个动态的加载机制,不是说,在程序启动的时候,如果ClassPath下有100个.class文件,就会把所有的二进制码一下子加载到内存中,而是刚刚开始的时候JVM使用ClassLoader把最初的几个.class二进制码Load到内存中,之后的是用到的时候才加载,慢慢的会有更多的加载到存中。当然也可以通过代码显示的要求立即把相应的二进制类代码加载到内存,如JDBC驱动的加载 Class.forName("com.mysql.jdbc.Driver")

在这里有一个相关的知识点就是static静态语句块的问题。有人说,静态语句块是第一次new对象的时候执行,这种说法是不准确的,确切的说,是加载到内存中的时候执行。一般来讲我们自己写的类,是用的时候才加载到内存,而我们用的方式,一般都是new一个对象,一般不会强制显示的去加载,所以,大家就以为是第一次实例化的时候执行。如果我们使用Class.Forname显示的把它load到内存,而并不new对象,可以发现,此时静态代码块也执行了。

现在解决最初提出的那个问题,只需要一句代码

String type = “A”;

Object o = Class.forName(type).newInstance();

下面是有关反射使用的一些常用的方法,包括获取成员方法等。从面相对象的角度看,类中的一个个属性或者方法都是对象,要让其执行,调用invoke就可以了。

 

ext验证正整数

minValue : 1,
            xtype : 'numberfield',
            regex: /^\d+$/,//验证数字
 

servlet各种监听器

目前Servlet2.4和JSP2.0总共有8个监听器接口和6个Event类,其中 HttpSessionAttributeListener与HttpSessionBindingListener皆使用 HttpSessionBindingEvent;HttpSessionListener和 HttpSessionActivationListener则都使用HttpSessionEvent;其余Listener对应的Event如下所 示:

Listener接口

Event类

ServletContextListener

ServletContextEvent

ServletContextAttributeListener

ServletContextAttributeEvent

HttpSessionListener

HttpSessionEvent

HttpSessionActivationListener

HttpSessionAttributeListener

HttpSessionBindingEvent

HttpSessionBindingListener

ServletRequestListener

ServletRequestEvent

ServletRequestAttributeListener

ServletRequestAttributeEvent


分别介绍:
一 ServletContext相关监听接口
补充知识:
通过ServletContext 的实例可以存取应用程序的全局对象以及初始化阶段的变量。
在JSP文件中,application 是 ServletContext 的实例,由JSP容器默认创建。Servlet 中调用 getServletContext()方法得到 ServletContext 的实例。
注意:
全局对象即Application范围对象,初始化阶段的变量指在web.xml中,经由<context-param>元素所设定的变量,它的范围也是Application范围,例如:

<context-param> 
<param-name>Name</param-name> 
<param-value>browser</param-value>
</context-param>
当容器启动时,会建立一个Application范围的对象,若要在JSP网页中取得此变量时:
String name = (String)application.getInitParameter("Name");
或者使用EL时:
${initPara.name}
若是在Servlet中,取得Name的值方法:
String name = (String)ServletContext.getInitParameter("Name");


1.ServletContextListener:
用于监听WEB 应用启动和销毁的事件,监听器类需要实现javax.servlet.ServletContextListener 接口。
ServletContextListener 是 ServletContext 的监听者,如果 ServletContext 发生变化,如服务器启动时 ServletContext 被创建,服务器关闭时 ServletContext 将要被销毁。

ServletContextListener接口的方法:
void contextInitialized(ServletContextEvent sce)
通知正在接受的对象,应用程序已经被加载及初始化。
void contextDestroyed(ServletContextEvent sce)
通知正在接受的对象,应用程序已经被载出。

ServletContextEvent中的方法:
ServletContext getServletContext()
取得ServletContext对象


2.ServletContextAttributeListener:用于监听WEB应用属性改变的事件,包括:增加属性、删除属性、修改属性,监听器类需要实现javax.servlet.ServletContextAttributeListener接口。

ServletContextAttributeListener接口方法:
void attributeAdded(ServletContextAttributeEvent scab)
若有对象加入Application的范围,通知正在收听的对象
void attributeRemoved(ServletContextAttributeEvent scab)
若有对象从Application的范围移除,通知正在收听的对象
void attributeReplaced(ServletContextAttributeEvent scab)
若在Application的范围中,有对象取代另一个对象时,通知正在收听的对象


ServletContextAttributeEvent中的方法:
java.lang.String getName()
回传属性的名称
java.lang.Object getValue()
回传属性的值

二、HttpSession相关监听接口
1.HttpSessionBindingListener接口
注意:HttpSessionBindingListener接口是唯一不需要再web.xml中设定的Listener

当我们的类实现了HttpSessionBindingListener接口后,只要对象加入Session范围 (即调用HttpSession对象的setAttribute方法的时候)或从Session范围中移出(即调用HttpSession对象的 removeAttribute方法的时候或Session Time out的时候)时,容器分别会自动调用下列两个方法:
void valueBound(HttpSessionBindingEvent event)
void valueUnbound(HttpSessionBindingEvent event)

思考:如何实现记录网站的客户登录日志, 统计在线人数?

2.HttpSessionAttributeListener接口
HttpSessionAttributeListener监听HttpSession中的属性的操作。
当在Session增加一个属性时,激发attributeAdded(HttpSessionBindingEvent se) 方法;当在Session删除一个属性时,激发attributeRemoved(HttpSessionBindingEvent se)方法;当在Session属性被重新设置时,激发attributeReplaced(HttpSessionBindingEvent se) 方法。这和ServletContextAttributeListener比较类似。

3.HttpSessionListener接口
HttpSessionListener监听HttpSession的操作。当创建一个Session时,激发session Created(HttpSessionEvent se)方法;当销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se)方法。

4.HttpSessionActivationListener接口
主要用于同一个Session转移至不同的JVM的情形。

四、ServletRequest监听接口
1.ServletRequestListener接口
和ServletContextListener接口类似的,这里由ServletContext改为ServletRequest
2.ServletRequestAttributeListener接口
和ServletContextListener接口类似的,这里由ServletContext改为ServletRequest 

 

系统启动调用线程的方法

1.新建类继承Thread,
2.把此类交给spring管理
<bean id="b" class="" init-method="start" />
当系统启动时就可以了
 

获得地址栏中的地址

var url = window.location.href;
 

ServletContextListener的配置

新建一个java类,实现
ServletContextListener
接口,在web.xml中配置
<listener>
      <listener-class>类的完全限定名</listener-class>
  </listener>
 

使用hibernate按条件查询拼sql方法

方法1.例如:

StringBuffer sql = new StringBuffer();
        sql.append("from Book b where 1=1 ");
        if(!"".equals(sum)&&sum!=null){
            sql.append(" and b.sum ='"+sum+"'");
        }
        if(!"".equals(aut)&&aut!=null){
            sql.append(" and b.author ='"+aut+"'");
        }
        if(!"".equals(pub)&&pub!=null){
            sql.append(" and b.publish ='"+pub+"'");
        }
        if(!"".equals(rfid)&&rfid!=null){
            sql.append(" and b.addRfidSum ='"+rfid+"'");
        }
方法2.
StringBuffer sql = new StringBuffer();
        sql.append("from Book b where ");
        if(!"".equals(sum)&&sum!=null){
            sql.append(" b.sum ='"+sum+"' and ");
        }
        if(!"".equals(aut)&&aut!=null){
            sql.append(" b.author ='"+aut+"' and ");
        }
        if(!"".equals(pub)&&pub!=null){
            sql.append(" b.publish ='"+pub+"' and ");
        }
        if(!"".equals(rfid)&&rfid!=null){
            sql.append(" b.addRfidSum ='"+rfid+"' and ");
        }
        String s = sql.toString();
         s=s.substring(0,s.lastIndexOf(" and ")>0? s.lastIndexOf(" and "):s.indexOf("where"));
         System.out.println(s);

当心在单引号和双引号中间不要有空格,不然会出错
 

DirectJNgine类中获取application,session,Request,Response对象

WebContext context = WebContextManager.get();
HttpSession session = context.getSession();
ServletContext application = context.getServletContext();
context.getRequest();
 context.getResponse();
   
 

日期转换

String s = "2012-08-25";  
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");  
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年M月d日");  
try {  
    System.out.println(sdf2.format(sdf1.parse(s)));  
} catch (ParseException e) {  
    
    e.printStackTrace();  
}  
 

根据访问者的ip地址自动显示所在地天气,好用的接口



根据有道的API 先根据IP确定城市 在根据城市获取天气
 

在window下开机自动启动tomcat方法

在命令行框中输入tomcat路径,例如
D:\tomcat-6.0.18\bin\service.bat install,在系统服务中找到tomcat,定义为自动启动就好了
 

extjs中Ext.BLANK_IMAGE_URL的作用

在使用ExtJS时,我们往往需要在使用之前加入这么一句:
Ext.BLANK_IMAGE_URL = "....."其中省略部分为s.gif在extjs包中的路径。
那么ExtJS为什么要设置这样一个变量呢?如果我们不这样做会带来什么后果?
首先说后果:
如果没有以上那句代码,Ext会按照默认的地址:http://www.extjs.com/s.gif去下载这张图片,由于网络不通或者速度较慢等原因,可能导致这张图片加载不成功,造成页面上很多小白条。
设置这个变量的原因:
原来ExtJS中在创建组件的时候,组件中需要替换图标的地方,初始化时都是拿这个s.gif替代的,如果用户指定icon属性,它会将s.gif替换为icon的地址,说白了,s.gif就是一个占位的功能。
另外,如果看过ExtJS的源代码可能发现,它对于ie和air的默认实现是去url请求这张图片,而对于其它浏览器则直接使用图片解码,这是因为ie和air不支持图片解码。

----------------------------------------------------------------------------------------------------------

Ext.BLANK_IMAGE_URL

图片位置默认指向:
/resources/images/default/s.gif'

 

最近在看Ext中jack的window导航式例时,看到一个细节,让我顿时明白了作者的这一做法的初衷。
作者在对一些需要应用图片或者图标的地方,都没有显式写明要应用的图标(片)路径,
而都是通过css来配置,许多应用图标的地方刚开始都Ext.BLANK_IMAGE_URL来替代,
而在css在加载之后就会替换到真实的图标路径 。
这一招就彻底解决了界面的换肤问题。

 

把extjs部署到tomcat中方法

把extjs源代码包发到wabapps中,启动tomcat,在浏览器地址栏输入 http://localhost:8080/ext/docs/index.html就可以了
 

简单(静态)工厂模式

简单工厂模式存在的目的是定义一个用于创建对象的接口,此模式由三个部分组成:
(1)工厂类角色:这是本模式的核心,含有一定的逻辑和判断,由一个具体类实现
(2)抽象产品角色:一般是具体产品继承的父类或者实现的接口,
(3)工厂类所创建的对象就是此角色的实例
 

读取配置文件.properties中的数据

.properties文件中的数据是键值对形式的,key = value格式,把此文件放在紧跟在src目录下,新建一个类来读取数据,例如:

public class ReadCommand {
 /**
  * 读取properties文件
  */

 private static ReadCommand readConfig = new ReadCommand();
 public static Map<String, String> nodeMap = new HashMap<String, String>();
 
 static{
  System.out.println("ReadConfig...");
  InputStream in = ReadCommand.class.getClassLoader().getResourceAsStream("light_command.properties");
  Properties prop = new Properties();
  try {
   prop.load(in);
   Enumeration en = prop.propertyNames();
   while(en.hasMoreElements()){
    String key = (String) en.nextElement();
    String value = (String) prop.get(key);
    nodeMap.put(key, value);
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
 
 //私有化构造函数
 private ReadCommand(){}
 
 /**
  * 实例化该类(单例)
  *  *  */
 public static ReadCommand getInstance(){
  return readConfig;
 }
 
 /**
  * 获取配置的节点的信息
  * 
  *   */
 public Map<String, String> getNodes(){
  return nodeMap;
 }
public static Map<String,String> getLightName(){
  Map<String, String> map = ReadConfig.getInstance().getNodes();
 
 return map;
 }
Map<String,String> map = GetLightName.getLightName();
  Set<String> keys = map.keySet();//得到键值
  for(String key : keys){
   System.out.println(key+"-----"+map.get(key));
  }
}

 

extjs中嵌入别的系统的网页

Ext.ux.LightTabPanel.superclass.constructor.call(this, {
  id : this.panelId,
  title : this.treeNode.text,
  layout : 'border',
  closable : true,  
  autoScroll : true,
  width: '100%',
  height: '100%',
   html: '<iframe width=100% height=100% src=" http://192.168.1.5:8080/ord?file:^html/access/employee.htm" />'
 });

在面板的构造方法中这样写,就可以了
 

extjs定时向后台请求

var alarmTask = {
   run   : function() {
   Ext.Ajax.request(写需要请求的代码);
   },
   interval : 5000
  };
  Ext.TaskMgr.start(alarmTask);
 

删除数组和集合中重复的数据

List<String> a = new ArrayList<String>();
a.add("6");
a.add("3");
a.add("4");
 a.add("1");
 a.add("1");
 a.add("2");
 a.add("2");
 a.add("3");
 a.add("4");
 a.add("5");
 a.add("6");
 a.add("5");
 List<String> b = new ArrayList<String>();
 for(String c : a){
  if(!b.contains(c)){
   b.add(c);
  }
 }
在删除集合中重复的数据时,只要先创建一个新的集合存放数据就好
 

BeanNameAutoProxyCreator自动创建事务代理

用BeanNameAutoProxyCreator自动创建事务代理
下面介绍一种优秀的事务代理配置策略:采用这种配置策略,完全可以避免增量式配置,所有的事务代理由系统自动创建。容器中的目标bean自动消失,避免需要使用嵌套bean来保证目标bean不可被访问。
这种配置方式依赖于Spring提供的bean后处理器,该后处理器用于为每个bean自动创建代理,此处的代理不仅可以是事务代理,也可以是任意的代理,只需要有合适的拦截器即可。这些是AOP框架的概念读者只需了解这种事务代理的配置方式即可。
下面是采用BeanNameAutoProxyCreator配置事务代理的配置文件:
<?xml version="1.0" encoding="gb2312"?>
<!--  Spring配置文件的文件头,包含DTD等信息-->
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    " [url]http://www.springframework.org/dtd/spring-beans.dtd[/url]">
<beans>
    <!--定义数据源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <!--  定义数据库驱动-->
            <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
        <!--  定义数据库url-->
            <property name="url"><value>jdbc:mysql://localhost:3306/spring</value></property>
<!--  定义数据库用户名-->
            <property name="username"><value>root</value></property>
        <!--  定义数据库密码-->
            <property name="password"><value>32147</value></property>
    </bean>
    <!--定义一个hibernate的SessionFactory-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <!--  定义SessionFactory必须注入DataSource-->
            <property name="dataSource"><ref local="dataSource"/></property>
            <property name="mappingResources">
            <list>
                <!--以下用来列出所有的PO映射文件-->
                <value>Person.hbm.xml</value>
            </list>
            </property>
            <property name="hibernateProperties">
            <props>
<!--此处用来定义hibernate的SessionFactory的属性:
不同数据库连接,启动时选择create,update,create-drop-->
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
        </props>
        </property>
    </bean>
    <!--  定义事务管理器,使用适用于Hibernte的事务管理器-->
<bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <!--  HibernateTransactionManager  bean需要依赖注入一个SessionFactory bean的引用-->
            <property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
    <!--  配置事务拦截器-->
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
        <!--  事务拦截器bean需要依赖注入一个事务管理器 -->
        <property name="transactionManager" ref="transactionManager"/>
        <property name="transactionAttributes">
            <!--  下面定义事务传播属性-->
            <props>
                <prop key="insert*">PROPAGATION_REQUIRED</prop>
                <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>
<!-- 定义BeanNameAutoProxyCreator,该bean是个bean后处理器,无需被引用,因此没有id属性
这个bean后处理器,根据事务拦截器为目标bean自动创建事务代理
    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
          指定对满足哪些bean name的bean自动生成业务代理 -->
 <property name="beanNames">
            <!--  下面是所有需要自动创建事务代理的bean-->
            <list>
                <value>personDao</value>
            </list>
            <!--  此处可增加其他需要自动创建事务代理的bean-->
        </property>
        <!--  下面定义BeanNameAutoProxyCreator所需的事务拦截器-->
        <property name="interceptorNames">
            <list>
                <value>transactionInterceptor</value> 
                    <!-- 此处可增加其他新的Interceptor -->
            </list>
        </property>
    </bean>
    <!--定义DAO Bean ,由于BeanNameAutoProxyCreator自动生成事务代理-->
    <bean id="personDao" class="lee.PersonDaoHibernate">
        <property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
</beans>
TranscationInterceptor是一个事务拦截器bean,需要传入一个TransactionManager的引用。配置中使用Spring依赖注入该属性,事务拦截器的事务属性通过transactionAttributes来指定,该属性有props子元素,配置文件中定义了三个事务传播规则:
所有以insert开始的方法,采用PROPAGATION_REQUIRED的事务传播规则。程序抛出MyException异常及其子异常时,自动回滚事务。所有以find开头的方法,采用PROPAGATION_REQUIRED事务传播规则,并且只读。其他方法,则采用PROPAGATION_REQUIRED的事务传播规则。
BeanNameAutoProxyCreator是个根据bean名生成自动代理的代理创建器,该bean通常需要接受两个参数。第一个是beanNames属性,该属性用来设置哪些bean需要自动生成代理。另一个属性是interceptorNames,该属性则指定事务拦截器,自动创建事务代理时,系统会根据这些事务拦截器的属性来生成对应的事务代理。

 

ext中引用变量的使用

在ext的js文件中,使用对象的属性时,如果对象的属性是基本数据类型和String时,和对象的属性是引用属性时,例如是别的类名时,可以这样使用:
var typeRecord = new Ext.data.Record.create([ {
  name : 'id',
  type : 'long'
 }, {
  name : 'rfid',
  type : 'string'
 }, {
  name : 'addTime',
  type : 'string'
 }, {
  name : 'food',//food是别的类的对象,Food
  type : 'AUTO'//定义为这样
 }, {
  name : 'foodCode',
  type : 'string'
 }, {
  name : 'sum',
  type : 'string'
 }, {
  name : 'deadTime',
  type : 'string'
 }]);

在使用时,这样,例如:
  columns : [ {
   header : '编号',
   dataIndex : 'id',
   width : 60
  }, {
   header : '卡号',
   dataIndex : 'rfid'
  }, {
   header : '添加时间',
   dataIndex : 'addTime'
  }, {
   header : '食物现库存',
   dataIndex : 'sum'
  }, {
   header : '食物快要过期,剩余天数',
   dataIndex : 'deadTime'
  }, {
   header : '所属食物的常规数量',
   dataIndex : 'food',
   renderer: function(v){
    return v.num;
   }
  }, {
   header : '所属食物的产地',
   dataIndex : 'food',//这样就可以去到Food的对象food的address的数据了
   renderer: function(v){
    return v.address;
   }
  }, {
   header : '所属食物的保质期',
   dataIndex : 'food',
   renderer: function(v){
    return v.limitTime;
   }
  }, {
   header : '所属食物',
   dataIndex : 'food',
   renderer: function(v){
    return v.foodName;
   }
  }   ]
 

InitializingBean与DisposableBean总结

当想让系统启动时就执行的代码,可以有2中方法实现:
1.让一个类实现InitializingBean接口,重写afterPropertiesSet()方法 ,再把这个类交给spring管理,定义为一个bean,这样就可以了
2.在一个类中自己写一个方法,此方法是无参数的,把这个类交给spring管理,定义init-method="自己定义的方法名",这样也可以,这个接触了对spring的依赖
当系统管理时执行的代码可以这样实现:
让一个类实现DisposableBean接口,重写 destroy()方法,再把这个类交给spring管理
 

extjs中选中一行

typeGrid.on('rowclick', function(grid, rowIndex, event) {
  currRecord = grid.getStore().getAt(rowIndex);
 });

typeGrid是数据类表的面板,currRecord 是这一行的对象


extjs的分页感悟

 

Extjs中分页的使用:

在后台查询程序中查询出的数据集合要放在一个辅助类的对象中辅助类要有2个属性,一个放数据总数,一个房数据集合,例如:

public class DirectStore {

 

    private int totalRecords;

    private final List<?> results;

 

    public DirectStore(final int totalRecord, final List<?> results) {

       super();

       this.totalRecords = totalRecord;

       this.results = results;

    }

 

    public List<?> getResults() {

       return this.results;

    }

 

    public int getTotalRecord() {

       return this.totalRecords;

    }

 

    public void setTotalRecord(final int totalRecord) {

       this.totalRecords = totalRecord;

    }

 

    @Override

    public String toString() {

       return "{'totalRecords':" + this.totalRecords + ",'results'"

              + this.results + "}";

    }

 

}

把查询出的额数据集合放在对象中

DirectStore store = new DirectStore(recordNumber, list);

在ext的页面中,需要先定义如下:

var typeStore = new Ext.data.DirectStore({

       paramOrder : [ 'start', 'limit' ],

       baseParams : {

           'start' : 0,

           'limit' : 20

       },

       root : 'results',

       totalProperty : 'totalRecords',//和DirectStore对象的totalRecords属性一样

       idProperty : 'id',

       fields : [ 'id', 'name', 'Unit', 'description' ],//集合中存放的对象的属性

       directFn : EamDjn.getDepartment

    });

    typeStore.load();

再在页面下面写:

bbar: new Ext.PagingToolbar({

           pageSize: 20,

           store : typeStore,

           displayInfo: true,

           displayMsg: '显示第 {0} 条到 {1} 条记录,一共 {2} 条',

           emptyMsg: '没有记录'

       })

这样就完成分页了,需要

 

extTree

function tree3(){
    var root=new Ext.tree.TreeNode({
      id:"root",
      href:"http://www.easyjf.com",
       hrefTarget:"_blank",
      text:"树的根"});
    var c1=new Ext.tree.TreeNode({
      id:"c1",
      href:"http://www.easyjf.com",
       hrefTarget:"_blank",
      text:"一级子节点1"
      });
    var c2=new Ext.tree.TreeNode({
      id:"c2",
      href:"http://www.easyjf.com",
       hrefTarget:"_blank",
      text:"一级子节点2"
      });
    var c3=new Ext.tree.TreeNode({
      id:"c3",
      href:"http://www.easyjf.com",
       hrefTarget:"_blank",
      text:"二级子节点1"
      });
    var c4=new Ext.tree.TreeNode({
      id:"c4",
      href:"http://www.easyjf.com",
       hrefTarget:"_blank",
      text:"二级子节点2"
      });
    root.appendChild(c1);
    root.appendChild(c2);
    c1.appendChild(c3);
    c2.appendChild(c4);
    var tree=new Ext.tree.TreePanel({
      renderTo:"hello",
      root:root,
      width:200
      });
    root.on("click",function(node,event){
      alert("您点击了"+node.text);
              }
          );
    c1.on("click",function(node,event){
      alert("您点击了"+node.text);
            }
     );
    c2.on("click",function(node,event){
      alert("您点击了"+node.text);
            }
     );
    c3.on("click",function(node,event){
      alert("您点击了"+node.text);
            }
     );
    c4.on("click",function(node,event){
      alert("您点击了"+node.text);
            }
     );    
   }
 

ext 学习笔记

     摘要: <html>    <head>        <link rel="stylesheet" type="text/css" href="ext-3.3.1\resources\css/ext-all.css" />     &nbs...   阅读全文
 

get请求中文乱码问题的解决

在tomcat的conf文件夹中的server.xml文件中找到<Connector>节点,在节点中写上URIEncoding="UTF-8",就可以解决整个项目中的get请求的中文乱码

 

hibernate里的DetachedCriteria的几种条件查询方法

detachedCriteria.add(Restrictions.eq("user.userId", userId));
Restrictions.eq()是等于,Restrictions.allMap()使用Map,使用key和value进行多个等于的对比
Restrictions.gt()大于,Restrictions.ge()大于等于,Restrictions.lt()小于,
Restrictions.le()小于等于,Restrictions.between()对应sql中的between字句,
Restrictions.like()对应sql的like字句,
Restrictions.in()对应sql的in字句
Restrictions.and()
Restrictions.or()
Restrictions.sqlRestnction(),是对sql限定查询 

 

中文字符转码

1.    String s = “中文”;
S = new String(s.getBytes(“ISO8859-1”),”utf-9”);
2.    使用过滤器:
public class CharsetFilter implements Filter{

    private String encoding = "UTF-8";
    
    public void destroy() {
        
    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding(encoding);
        chain.doFilter(request, response);
    }

    public void init(FilterConfig filterConfig) throws ServletException {
        String encoding = filterConfig.getInitParameter("encoding");
        if(encoding != null) {
            this.encoding = encoding;
        }
    }

}
3.request.setCharacterEncoding(“utf-8”);
 

内存溢出解决方案

找到自己的myeclipse安装目录,找到文件myeclipse.ini,改最后三项数据
-Xmx1024m
-XX:MaxPermSize=1024
-XX:ReservedCodeCacheSize=512m,再重做tomcat就好了
 

用配置事务

在applicationContext.xml里写:
<?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

">
<!-- 使用注解支持事务
<tx:annotation-driven transaction-manager="transactionManager" />   -->
<!-- 添加jdbc的任务管理器 -->
<bean  id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <!-- name表示以什么开始的方法名,比如 add*表示add开头的方法
            propagation表示事务传播属性,不写默认有
         -->
         <tx:method name="save*" propagation="REQUIRED"/>
         <tx:method name="del*" />
         <tx:method name="update*"/>
         <tx:method name="find*"  read-only="true"/>
    </tx:attributes>
</tx:advice>
<!-- 配置事务切面 -->
<aop:config>
    <aop:pointcut expression="execution(* com.yjw.service..*.*(..))" id="pointcut"/>
    <aop:advisor advice-ref="txAdvice"  pointcut-ref="pointcut"/>
</aop:config>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass"  value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl"  value="jdbc:mysql:///mydb"/>
<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>
<!-- 在使用事务时不能配置jdbc模板,只能配置数据流 -->
<bean  id="userdao" class="com.yjw.dao.UserDao">
    <property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="userService"  class="com.yjw.service.UserService">
    <!-- name的值只和set方法后面的有关,要一样 -->
    <property name="dao"  ref="userdao"></property>
</bean>
</beans>
在service里写:
public class UserService  {

    private  UserDao  userdao;
    
    

    public void setDao(UserDao userdao) {
        this.userdao = userdao;
    }

    
    public  void  save(User user){
        userdao.save(user);
        if(true){
            throw new  RuntimeException();
        }

    
        userdao.save(user);
    }

    //只读,会使性能提高,推荐使用
    //@Transactional(readOnly=true)
    public  User findById(int id){
        return userdao.findById(id);
    }

}

 

用注解的方式加事务

在applicationContext.xml里写:
<?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

">
<!-- 使用注解支持事务 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- 添加jdbc的任务管理器 -->
<bean  id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass"  value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl"  value="jdbc:mysql:///mydb"/>
<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>
<!-- 在使用事务时不能配置jdbc模板,只能配置数据流 -->
<bean  id="userdao" class="com.yjw.dao.UserDao">
    <property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="userService"  class="com.yjw.service.UserService">
    <!-- name的值只和set方法后面的有关,要一样 -->
    <property name="dao"  ref="userdao"></property>
</bean>
</beans>在service里加:
//在类的头上加上这个注解,代表这个类的所有方法都加上了事务,
//作用是某个方法里的代码要么都执行,要么都不执行
//默认是在发生RunTimeException是才回滚,发生Exception不回滚
//加上(rollbackFor=Exception.class)表示所有的异常都回滚
@Transactional(rollbackFor=Exception.class)
public class UserService  {

    private  UserDao  userdao;
    
    

    public void setDao(UserDao userdao) {
        this.userdao = userdao;
    }

    
    public  void  save(User user){
        userdao.save(user);
    }

    //只读,会使性能提高,推荐使用
    @Transactional(readOnly=true)
    public  User findById(int id){
        return userdao.findById(id);
    }

}

 

Spring对jdbc的支持

     摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->在applicationContext.xml文件里写:<?xml version="1.0" encoding="UTF-8"?><beans xmlns...   阅读全文
 

用struts2给的jar包解析json

1,添加jar包struts2-json-plugin-2.3.1.2.jar
2.在json-struts.xml里配置
    <package name="myjson"  extends="json-default">
            <action name="myjson"  class="com.yjw.web.MyjsonAction">
                <result  type="json">
                    <!--找到根节点-->
                <param name="root">user</param>
                <!--浏览器不要缓存-->
                <param name="noCache">true</param>
                <!--GZIP网页压缩协议,可以让传送更快,省流量-->
                <param name="enableGZIP">true</param>
                    <!--排除action里是null的属性-->
                <param name="excludeNullProperties">true</param>
                </result>
            </action>
        </package>
在MyjsonAction里写:
package com.yjw.web;

import com.opensymphony.xwork2.Action;

public class MyjsonAction  implements  Action  {
    private User user;
    private String x;

    public String execute() throws Exception {
        user = new  User();
        user.setId(1);
        user.setMoney(22);
        user.setName("tom");
        
        return "success";
    }


    public User getUser() {
        return user;
    }


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


    public String getX() {
        return x;
    }


    public void setX(String x) {
        this.x = x;
    }


}

 

输出xml

在struts2.Xml中写:
<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
    "http://struts.apache.org/dtds/struts-2.1.7.dtd">
    <struts>
        <package name="myxml"  extends="struts-default">
        <!-- 输出xml的方法不写result -->
            <action name="xml" class="com.yjw.web.MyxmlAction"></action>
        </package>
    </struts>
在action中写:
package com.yjw.web;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.Action;

public class MyxmlAction implements  Action {

    public String execute() throws Exception {
        HttpServletResponse  response = ServletActionContext.getResponse();
        response.setContentType("text/xml;charset=UTF-8");
        PrintWriter  out = response.getWriter();
        out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        out.print("<root>");
        for(int i=0;i<5;i++){
            out.print("<person>");
            out.print("<name>person"+i+"</name>");
            out.print("</person>");
        }

        out.print("</root>");
        //一定要返回null
        return null;
    }


}

在jsp里写:
<body>
  <input  type="button"  value="xml"  id="btnxml"/>
  <div  id="mydiv"></div>
  <script type="text/javascript"  src=js/jquery-1.5.1.min.js></script>
  <script  type="text/javascript">
              $(document).ready(function() {
                  $("#btnxml").click(function(){
                      $.get("xml.action",function(xml){
                          $(xml).find("person").each(function(){
                              var name = $(this).find("name").text();
                              $("#mydiv").html($("#mydiv").html()+name+'<br/>');
                          }
);
                      }
);
                      
                  }
);
              }
);
  </script>
  </body>

 

Struts2下载文件的程序

在jsp里写:
  <a href="download.action">点此下载文件</a>

在struts.xml中:
<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
    "http://struts.apache.org/dtds/struts-2.1.7.dtd">
    <struts>
        <package name="mydown" extends="struts-default">
            <action name="download" class="com.yjw.web.DownAction">
                <param name="id">1</param>
                <result type="stream">
                
                
                    <!-- 下载文件的mime类型 -->
                    <param name="contentType">$ {fileType}</param>
                    <!-- 下载文件的描述 -->
                    <param name="contentDisposition">attachment;filename=$ {fileName}</param>
                    <!-- 设置缓冲区大小 -->
                    <param name="bufferSize">1024</param>
                    <!-- 获得文件名的getxxx方法的名字 ,不包含get-->
                    <param name="inputName">inputStream</param>
                </result>
            </action>
        </package>
    </struts>
在action中的程序:
package com.yjw.web;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.Action;
public class DownAction implements  Action {
    private String fileName;
    private String id;
    private String fileType;
    public String execute() throws Exception {
        return "success";
    }

public InputStream  getInputStream() throws IOException{
    String path = ServletActionContext.getServletContext().getRealPath("/");
    if(id.equals("1")) {
        path = path + "download/less.pdf";
        fileName = "css.pdf";
        fileType = "application/pdf";
    }
 else {
        path = path + "download/data.xlsx";
        fileName = "data.xlsx";
        fileType = "application/vnd.ms-excel";
    }

        FileInputStream  stream = new  FileInputStream(new File(path));
    return stream;
    }

public String getFileName() {
    return fileName;
}

public void setFileName(String fileName) {
    this.fileName = fileName;
}

public String getId() {
    return id;
}

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

public String getFileType() {
    return fileType;
}

public void setFileType(String fileType) {
    this.fileType = fileType;
}

}

 

创建一个excel文件

HSSFWorkbook wb = new HSSFWorkbook();
    FileOutputStream fileout = new FileOutputStream("d:/b.xls");
    wb.write(fileout);
    fileout.close();
 

验证码的使用

验证码:


1, 导入jar包jcaptcha验证码

2.在web.xml里配置<servlet>

     <servlet-name>j</servlet-name>

    <servlet-class>com.octo.captcha.module.servlet.image.SimpleImageCaptchaServlet</servlet-class>

   </servlet>

   <servlet-mapping>

     <servlet-name>j</servlet-name>

     <url-pattern>/jcaptcha.jpg</url-pattern>

   </servlet-mapping>

3.在页面上写

<form action="vali.action" method="post">

     <input type="text" name="name"/>

     <a href="javascript:void(0)"
id="mya"><img src="jcaptcha.jpg" id="myimg"/></a>

     <input type="submit" value="save"/>

   </form>

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

 <script type="text/javascript">

       $(document).ready(function(){

          $("#mya").click(function(){

            $("#myimg").attr("src","jcaptcha.jpg?xxx=" + Math.random());

          });

4.在struts-vali.xml里写

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

 <!DOCTYPE struts
PUBLIC

   "-//Apache Software Foundation//DTD Struts
Configuration 2.1.7//EN"

   "http://struts.apache.org/dtds/struts-2.1.7.dtd">

   <struts>

     <package name="myvali"
extends="struts-default">

        <action name="vali" class="com.yjw.web.ValiAction">

          <result>WEB-INF/views/list.jsp</result>

          <result name="error">WEB-INF/views/main.jsp?id=1</result>

        </action>

     </package>

   </struts>

5.在ValiAction里写:

package com.yjw.web;

import org.apache.struts2.ServletActionContext;

import com.octo.captcha.module.servlet.image.SimpleImageCaptchaServlet;

import com.opensymphony.xwork2.Action;

public class ValiAction implements Action{

   private String name;

   public String execute() throws Exception {

     boolean result = SimpleImageCaptchaServlet.validateResponse(ServletActionContext.getRequest(),
name);

     System.out.println(result);

     if(result){

        return "success";

     }else {

        return "error";

     }

   }

   public String getName() {

     return name;

   }

   public void setName(String name) {

     this.name = name;

   }

}

 

java 中文件的复制,查询,删除

在javaIO中,文件的查询和删除,文件的复制程序如下:

普通的复制是:

public class Acopy {

 public void copy(String oldpath,String  newpath ) throws IOException {

    File of = new File(oldpath);

    File nf = new File(newpath);

    if(!nf.exists()){

      nf.createNewFile();

    }

    FileInputStream i = new FileInputStream(of); 

    FileOutputStream o = new FileOutputStream(nf);

    int b= 0;

    byte[] buffer = new byte[100];

    while((b=i.read(buffer))!=-1){

      o.write(buffer, 0, b-1);

    }

    i.close();

    o.flush();

    o.close();

  }

}

加强的复制是:

public class Bcopy {

 public void copy(String opath,String npath) throws IOException{

    File of = new File(opath);

    File nf = new File(npath);

    if(!nf.exists()){

      nf.createNewFile();

    }

    FileInputStream i = new FileInputStream(of);

    BufferedInputStream bi = new BufferedInputStream(i);

    FileOutputStream o = new FileOutputStream(nf);

    BufferedOutputStream bo = new BufferedOutputStream(o);

    int b = 0;

    byte[] buffer = new byte[100];

    while((b=bi.read(buffer))!=-1){

      bo.write(buffer, 0, b-1);

    }

    bi.close();

    bo.flush();

    bo.close();

  }

}

文件的查询是:

public void show(String path){

    File f = new File(path);

    if(f.isFile()){

      System.out.println(f.getPath());

    }else if(f.isDirectory()){

      File[] files = f.listFiles();

      if(files!=null){

        for(File file : files){

          if(file.isFile()){

            System.out.println(file.getPath());

          }else if(file.isDirectory()){

            System.out.println("["+file.getPath()+"]");

            show(file.getPath());

          }

        }

      }

    }

  }

文件的删除是:

public void del(String path){

    File f = new File(path);

    if(f.isFile()){

      f.delete();

    }else if(f.isDirectory()){

      File[] files = f.listFiles();

      if(files.length==0){

        f.delete();

      }else if(files!=null){

        for(File file : files){

          if(file.isFile()){

            file.delete();

          }else if(file.isDirectory()){

            del(file.getPath());

          }

        }

      }

    }

    f.delete();

  }

 

java线程

在建立线程时,有两种方式,1是继承java.lang.Thread类,重写run方法,此方法用于你想让线程干的事,在调用此方法时,不能直接调用run方法,要调用start方法,如果想访问此线程,使用Thread.currentThread()方法。2,是实现Runnable接口,在调用时,因为接口没有start方法,所以要先创建出实现类的的对象, 再创建出Thread的对象,把实现类的对象传入Thread的对象的构造方法中,再用Thread的对象调用start()方法。

线程有生命周期的,新建 ,就绪,运行,死亡。新建以后只有调用start方法才处于就绪队列,处于就绪队列的线程在获得处理机资源后处于运行,在运行过程中,如果调用sleep方法,或IO阻塞例如Scanner输入,或等待同步锁,或等待通知时就处于阻塞,这是释放处理机资源,在sleep时间到,或IO方法返回,或获得同步锁,或受到通知后,处于就绪队列,线程在run执行完成,或Error,或exeception时,就死亡。可以调用stop方法让线程死亡,但是禁止使用,可以使用isAlive方法判断线程是否死亡,该方法在线程处于就绪,运行,阻塞时返回true,处于新建和死亡时返回false,线程一旦死亡,不能再次调用start方法让线程重新执行。

当一个程序在执行中被另外一个线程插队,并且后来的线程需要先执行完后原来的线程才能执行,就要让插队线程先调用start方法,再调用join方法,进行插队。

守护线程就是在主线程死亡后,守护线程也随之死亡,在使用时让守护线程的对象先调用setDaemon(true)方法,再调用start方法。

当多个线程同时对同一个对象的实例属性进行操作时,会引起线程的同步问题,为了消除线程的同步,可用synchronized来修饰有可能引起线程同步的方法,也可用用synchronized(this)

{方法代码} ,设置同步代码块,在JDK1.5以上的版本可使用同步锁来操作,具体做法是:

Private final ReentrantLock  lock = new ReentrantLock();

在方法内部定义lock.lock();在程序执行完毕后,一定要解锁,lock.unlock();

 

java中文件的处理1

一,复制文件
        File oldFile = new File("F:/FavoriteVideo/0CAMGLN0K.jpg");
File newFile = new File("F:/FavoriteVideo/yang.jpg");
if(!oldFile.exists()){
newFile.createNewFile();
}
FileInputStream input = new FileInputStream(oldFile);
/*如果你想让文件的复制加快BufferedInputStream bufferedInput = new BufferedInputStream(input);*/
FileOutputStream output = new FileOutputStream(newFile );
/*BufferedOutputStream bufferedOut = new BufferedOutputStream(output);*/
byte[]  buffer = new byte[512];
int b = 0;
long startTime = System.currentTimeMillis();
while(b!=-1){
b=input.read(buffer);
output.write(buffer, 0, buffer.length);
}
long endTime = System.currentTimeMillis();
System.out.println(endTime-startTime);
input.close();
output.flush();
output.close();
二文件的查询方法
public class ShowFilePath {
public void show(String path){
File f = new File(path);
if(f.isFile()){
System.out.println(f.getPath());
}else if(f.isDirectory()){
File[] files = f.listFiles();
if(files!=null){
for(File file:files ){
if(file.isFile()){
System.out.println(file.getPath());
}else {
System.out.println("["+file.getPath()+"]");
show(file.getPath());
}
}
}
}

 

java和数据库的连接(jdbc)

一.使用JDBC  API对数据库进行CRUD(create,receive,update,delete)操作,开发JDBC的步骤是:

package com.yjw.j3;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.Statement;

public class Test {

public static void main(String[] args)  {

   Connection c = null;

   Statement s = null;

   ResultSet r = null;

   try {

      //1.加载数据库驱动(提供一个jdbc的数据库驱动的名称)

   Class.forName("com.mysql.jdbc.Driver");

      //2.获取数据库连接

      String a = "jdbc:mysql://localhost:3306/school";

       c = DriverManager.getConnection(a, "root", "root");

      //3.获取Statment对象(该对象用于对数据库进行CRUD操作)

       s = c.createStatement();

      //4.执行SQL语句

      String sql = "SELECT id,classname FROM t_class";

       r = s.executeQuery(sql);

      while(r.next()){

        int id = r.getInt("id");

        String b = r.getString("classname");

        System.out.println("id"+id+"\t"+"classname"+b);

       

      }

   } catch (Exception e) {

      e.printStackTrace();

   }finally{

      try {

        //5.释放连接

        r.close();

       

      } catch (Exception e2) {

        e2.printStackTrace();

      }finally{

        try {

           //5.释放连接

           s.close();

          

        } catch (Exception e3) {

           e3.printStackTrace();

        }finally{

           try {

              //5.释放连接

              c.close();

           } catch (Exception e4) {

              e4.printStackTrace();

           }

        }

      }

   }

  

}

}

二.在statement类的对象调用executeUpdate()方法用来对数据进行insert update,delete操作,该方法返回影响数据库的行数,对象调用executeQuery()方法用来对数据进行select操作,输出要使用while迭代器

三.释放连接时对象的顺序不能变,释放的顺序和创建对象的顺序相反

四.如果操作的事本地的数据库,在连接数据库时,有三种方法

1.”jdbc:mysql://本地ip:端口号/数据库名字”

2.”jdbc:mysql://localhost:端口号/数据库名字”

3.”jdbc:mysql:///数据库名字”

五.如果不知道数据库列的数据类型,可以通过这三步在控制台上查看

1.输入:mysql –u用户名 –p密码

2.输入:use 数据库名

3.输入: desc  表名

 

java中异常的处理

一.在java中的异常中,Throwable类有两个子类,Error和Exception,在Exception类中有两个子类,RuntimeException(运行时异常)和非运行时异常,运行时异常是指只有在运行时才会报错的异常,不会编译错,但是非运行时异常是会编译错的,在运行前就报错了。

二.在cry {语句1}catch(Exception e){语句2}finally{语句3}语句中,语句1放的是可能会发生异常的语句,语句2放的是发生异常后执行的语句,语句3放的是一定会执行的语句,不管有异常没有,

三。PrintStackTrace()方法用于输出有关的异常信息,包括异常的原因,以及该异常发生在类的第几行代码中,getMessage()方法用于返回异常相关的详细信息,但是无法跟踪到具体的行。

四.在自定义异常中,如果是继承自Exception类时,有两种方法处理

1.在有可能发生异常的方法中,在这个方法名后利用throws跑出自定义异常,

在对象调用此方法的时,需要对象自己利用try  catch语句处理此方法

2在有可能发生异常的方法中,自己利用try  catch语句处理异常,在对象调用此方法时,不在需要对象自己利用try  catch语句处理此方法,直接调用方法就可以

五.在自定义异常中,如果继承自RuntimeException类时,在对象调用此方法的时,需要对象自己利用try  catch语句处理此方法。

 

mysql的感悟之三

一.在内连接中的等值连接中,适用于两个表,且两个表中都有共同的一项,根据这一项来连接两表中其他的项,但是如果不在where中约束两表中共同的一项相等,会产生笛卡尔积。

比如select  stuname,score  from  t_student,t_scores  where  t_student.id=t_sccores.stu_id;

标准的内连接是  select  stuname,scores  from  t_student  inner join  t_scores   on

T_student.id=t_scores.stu_id;

二.左连接会全部显示左边的信息,比如  select   stuname,score  from  t_student

Left   join   t_scores  on  t_student.id=t_scores.stu_id;

三.只要是几个表的连接查询,都要在其中直接连接的两个表中找到相同的项,作为纽带,查询其他的列。

四.表之间的关系包括1对1,1对多,多对多,其中1对1 时比如建立人的表和身份证表,他们是1对1的,在建立身份证表时,表的id号不是自动增长的,并且id即使身份证表的主键,也是人表的外键,也就是说id不但不能重复,还要一定时人表中存在的,1对1的。

在1对多时,比如人表和银行卡表,一个人可以有多个银行卡,但是一个银行卡只能属于一个人,所以把人的id放在银行卡表中,作为人表的外键,也就是说,在1对多时,在多的表中存放1的主键。

在多对多时,比如学生表和课程表,一个学生可以选多个课,一个课可以有多个学生上课,这就是多对多的情况,需要建立第三张关系表,在关系表中包括学生表和课程表的俩主键,这俩主键也是关系表的主键

 

我的mysql学习的一点感想

在mysql中,group by 分组后,可用sun()来计算每组的莫一列的内容和,比如价格总额,数量总额,count()是用来计算列的个数和,不是内容和,

在查询中,关键字的使用顺序是1.select,2.from,3.where,4.group by,5.having,

6.order by,7.limit

在子查询中又是可以把子查询分解为几个单表查询,最后再整合在一起

在相关子查询中,比如SELECT customers.cust_id, customers.cust_name,(SELECT COUNT(*) FROM orders WHERE orders.cust_id=customers.cust_id) FROM customers;中是先在customers表中拿到第一个cust_id 带到小括号里进行比对,如果有相同的就计算总和,没有相同的为0,以此类推,最后算出结果,。

一 :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

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");
%>

Guess you like

Origin blog.csdn.net/MingDaw/article/details/9969561