2006年7月14日
#
一.HTTP请求:
HTTP请求分为:
1).请求行
2).消息头
3).空行
4).正文
1.请求行
[方法 URI HTTP版本信息]
如: GET /index.htm HTTP/1.0
2.方法(全部大写):
GET 请求URI标识的资源
HEAD 请求获取响应消息头
PUT 请求存储资源,并用URI作为其标识
POST 请求服务器接收信息
CONNECT ?
TRACE
DELETE
OPTIONS
二.HTTP响应:
1).状态行
2).消息头
3).空行
4).正文(资源的内容,比如index.htm文件的文本内容)
1.状态行
HTTP版本信息 状态码 响应码描述
例: HTTP/1.1 200 OK
2.状态码(第一位表示响应的类别)
1xx:
2xx:
3xx:
4xx:
5xx:
HTTP协议状态码具体意义
100 : Continue
101 : witchingProtocols
200 : OK
201 : Created
202 : Accepted
203 : Non-AuthoritativeInformation
204 : NoContent
205 : ResetContent
206 : PartialContent
300 : MultipleChoices
301 : MovedPermanently
302 : Found
303 : SeeOther
304 : NotModified
305 : UseProxy
307 : TemporaryRedirect
400 : BadRequest
401 : Unauthorized
402 : PaymentRequired
403 : Forbidden
404 : NotFound
405 : MethodNotAllowed
406 : NotAcceptable
407 : ProxyAuthenticationRequired
408 : RequestTime-out
409 : Conflict
410 : Gone
411 : LengthRequired
412 : PreconditionFailed
413 : RequestEntityTooLarge
414 : Request-URITooLarge
415 : UnsupportedMediaType
416 : Requestedrangenotsatisfiable
417 : ExpectationFailed
500 : InternalServerError
501 : NotImplemented
502 : BadGateway
503 : ServiceUnavailable
504 : GatewayTime-out
505 : HTTPVersionnotsupported
三.HTTP消息头:
1. 普通
2. 请求头
3. 响应头
4. 实体头
格式:(名字大小写无关)
<名字>:<空格><值>
1.普通头
.Cache-Control (HTTP1.1, HTTP1.0:Pragma)
缓存指令:
请求时: no-cache,no-store,max-age,max-stale,min-fresh,only-if-cached
响应时: public,private,no-cache,no-store,no-transform,must-revalidate,proxy-revalidate,max-age,s-maxage.
例: Cache-Control: no-cache
.Date
客户端:在发送正文时要包含Date,
服务器:在响应时包含Date.
.Connection
.Pragma(1.0用)
2. 请求头
.Accept
.Accept-Charset
.Accept-Encoding
.Accept-Language
.Authorization
.Host(必须的)
.User-agent
3.响应头
.Location
.Server
.WWW-Authenticate,要包含在401中.
4.实体头
.Content-Encoding
.Content-Language
.Content-Length
.Content-Type
.Last-Modified
.Expires
package wlz.xml;
import javax.xml.parsers.*;
import org.w3c.dom.*;
//import javax.xml.transform.*;
//import javax.xml.transform.dom.DOMSource;
//import javax.xml.transform.stream.StreamResult;
import java.io.*;
import org.apache.xml.serialize.*;
public class WriteXml {
public static void writeXml(Document doc,String filename) throws Exception{
/*TransformerFactory tf=TransformerFactory.newInstance();
Transformer f=tf.newTransformer();
//f.setOutputProperties();
DOMSource source=new DOMSource(doc);
StreamResult result=new StreamResult(new File(filename));
f.transform(source,result);*/
FileOutputStream fos = new FileOutputStream(filename);
OutputFormat of = new OutputFormat("XML","GB2312",true);
of.setIndent(2);
of.setIndenting(true);
XMLSerializer serializer = new XMLSerializer(fos,of);
serializer.asDOMSerializer();
serializer.serialize(doc.getDocumentElement());
fos.close();
}
public static void outputElement(Document doc,String elementName){
NodeList list= doc.getElementsByTagName(elementName);
System.out.println("------------------------------------------");
for(int i=0;i<list.getLength();i++){
System.out.println(elementName+"="+list.item(i).getFirstChild().getNodeValue()); //取出元素的值
}
System.out.println("------------------------------------------");
}
public static void addElement(Document doc,Element root,String name,String age,String sex){
Element student=doc.createElement("student");
Element ename=doc.createElement("name");
Element eage=doc.createElement("age");
Element esex=doc.createElement("sex");
ename.appendChild(doc.createTextNode(name));
eage.appendChild(doc.createTextNode(age));
esex.appendChild(doc.createTextNode(sex));
student.appendChild(ename);
student.appendChild(eage);
student.appendChild(esex);
root.appendChild(student);
}
public static Document createDocument() throws Exception{
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
DocumentBuilder db=dbf.newDocumentBuilder();
Document doc=db.newDocument();
return doc;
}
public static void main(String[] args) throws Exception{
/*
output the xml
<class name="计算机1班">
<student>
<name>
<age>
<sex>
</student>
<student>
<name>
<age>
<sex>
</student>
</class>
*/
Document doc=createDocument();
doc.createProcessingInstruction("encoding","gb2312");
Element root=doc.createElement("class");
root.setAttribute("name","计算机1班");
doc.appendChild(root);
addElement(doc,root,"黄蓉","30","女");
addElement(doc,root,"郭靖","32","男");
addElement(doc,root,"杨过","8","男");
outputElement(doc,"name");
outputElement(doc,"sex");
writeXml(doc,"mydomxml.xml");
System.out.println("output ok.");
}
}
1.线程中要使用的类.各线程只有其一个引用.
public class VarClass {
private static ThreadLocal threadVar=new ThreadLocal(){
protected synchronized Object initialValue(){
System.out.println(Thread.currentThread().getName()+" initial value is 1");
return new Integer(1);
}};
public int getValue(){
return ((Integer)threadVar.get()).intValue();
}
public void setValue(){
int a=getValue();
a++;
threadVar.set(new Integer(a));
}
}
2.线程类
public class Worker extends Thread {
private long interval=0;
private boolean isRun=true;
private VarClass v=null;
public Worker(String name,VarClass v,long interval){
setName(name);
this.v=v;
this.interval=interval;
}
public void run() {
while(isRun){
try{
Thread.sleep(interval);
}catch(InterruptedException e){
e.printStackTrace();
}
v.setValue();
}
System.out.println(getName()+" is over at "+v.getValue());
}
public void stopThread(){
isRun=false;
}
}
3.测试类
public class TestThreadLocal {
public static void main(String[] args){
VarClass v=new VarClass();
Worker w1=new Worker("Thread_A",v,100);
Worker w2=new Worker("Thread_B",v,200);
Worker w3=new Worker("Thread_C",v,300);
Worker w4=new Worker("Thread_D",v,400);
Worker w5=new Worker("Thread_E",v,500);
w1.start();
w2.start();
w3.start();
w4.start();
w5.start();
System.out.println("All threads is over after 20 seconds");
//延时20秒后,终止5个线程
try{
Thread.sleep(20000);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("All threads will be overed");
w1.stopThread();
w2.stopThread();
w3.stopThread();
w4.stopThread();
w5.stopThread();
}
}
4.测试结果:
All threads is over after 20 seconds
Thread_A initial value is 1
Thread_B initial value is 1
Thread_C initial value is 1
Thread_D initial value is 1
Thread_E initial value is 1
All threads will be overed
Thread_A is over at 200
Thread_B is over at 101
Thread_D is over at 51
Thread_C is over at 68
Thread_E is over at 42
5.结果说明:虽然各线程使用的是同一个对象的引用,但由于使用了ThreadLocal,实际上每个线程所操作的数据是不一样的.
1. Base64使用A--Z,a--z,0--9,+,/ 这64个字符.
2. 编码原理:将3个字节转换成4个字节( (3 X 8) = 24 = (4 X 6) )
先读入3个字节,每读一个字节,左移8位,再右移四次,每次6位,这样就有4个字节了.
3. 解码原理:将4个字节转换成3个字节.
先读入4个6位(用或运算),每次左移6位,再右移3次,每次8位.这样就还原了.
proxool连接池的配置(0.8.3)
1. 配置文件(xml形式,文件名任意)
--------------------------------
<?xml version="1.0"?>
<!-- the proxool configuration can be embedded within your own application's.
Anything outside the "proxool" tag is ignored. -->
<something-else-entirely>
<proxool>
<alias>mypool</alias> <!-- add "proxool" before alias -- proxool.alias -->
<driver-url>jdbc:oracle:thin:@localhost:1521:oradb</driver-url>
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<driver-properties>
<property name="user" value="username"/>
<property name="password" value="password"/>
</driver-properties>
<connection-lifetime>60</connection-lifetime>
<maximum-connection-count>50</maximum-connection-count>
<minimum-connection-count>4</minimum-connection-count>
<house-keeping-test-sql>select CURRENT_DATE</house-keeping-test-sql>
</proxool>
</something-else-entirely>
2.web.xml配置
--------------
<servlet>
<servlet-name>ServletConfigurator</servlet-name>
<servlet-class>
org.logicalcobwebs.proxool.configuration.ServletConfigurator
</servlet-class>
<init-param>
<param-name>xmlFile</param-name>
<param-value>WEB-INF/proxool.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- monitor proxool status -->
<servlet>
<servlet-name>Admin</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Admin</servlet-name>
<url-pattern>/admin</url-pattern>
</servlet-mapping>
3. 程序调用
Connection conn=null;
try {
Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
conn = DriverManager.getConnection("proxool.mypool"); //add "proxool" before "mypool" in proxool.xml
}catch(ClassNotFountException e){
e.printStackTrace();
}catch(SQLException e) {
e.printStackTrace();
}
1. wait:
Causes current thread to wait until either another thread invokes the notify()
method or the
notifyAll()
method for this object
This method should only be called by a thread that is the owner of this object's
monitor
使当前线程放弃对象锁(等待?),直到其它线程为该对象调用notify()或notifyAll().
这个方法只能被拥有对象锁(监听器?)的线程执行。
2. notify,notifyAll
Wakes up a or all threads that are waiting on this object's monitor.
唤醒正在等待指定对象的锁的一个或所有线程。
-- 这样翻译也不知是否准确,括号内是按直译过来的意思。
3. 四种方式
1.static synchronized method(){}
2.sychronized(Class)
3.sychronized method(){}
4.sychronized() {}
4. 书上没说过的: Spin Lock (旋转锁)
本例以租房子为例:
一.说明:
动态代理可动态为某个类添加代理,以拦截客户端的调用,在此基础上进行额外的处理.
目前较流行的AOP技术,就有以动态代理为技术基础进行实现的.
本例中,中介作为房子的动态代理,所有调用房子的方法,必须经过中介类(HouseAgency).
二.源代码:
1.House接口:
public interface House {
public void rent();
public int getPrice();
}
2.House接口实现类ConcreateHouse:
public class ConcreteHouse implements House{
private int price;
public ConcreteHouse(int price){
this.price=price;
}
public void rent(){
System.out.println("rent ok!");
}
public int getPrice(){
return price;
}
}
3.实现InvocationHandler接口的中介类:
import java.lang.reflect.*;
public class HouseAgency implements InvocationHandler {
private Object house;
public HouseAgency(Object house){
this.house=house;
}
public HouseAgency(){}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result=null;
if("getPrice".equals(method.getName())){
System.out.println("invoking getPrice() to query rent price.");
}
if("rent".equals(method.getName())){
System.out.println("invoking rent() to rent the house.");
}
result=method.invoke(house,args);
return result;
}
}
4.客户端
import java.lang.reflect.*;
public class HouseClient{
public static void main(String[] args){
ConcreteHouse house1=new ConcreteHouse(400);
HouseAgency ha=new HouseAgency(house1);
House house=(House)Proxy.newProxyInstance(house1.getClass().getClassLoader(),
house1.getClass().getInterfaces(),ha);
int price=house.getPrice();
System.out.println("the house rent is : "+price);
if(price>300){
house.rent();
}
}
}
三:打印结果
invoking getPrice() to query rent price.
the house rent is : 400
invoking rent() to rent the house.
rent ok!
JDOM(1.0)的初次接触
一.源代码:
import org.jdom.Element; //代表元素
import org.jdom.Attribute; //代表元素的属性
import org.jdom.Document; //代表整个XML文档
import org.jdom.Comment; //注释
import org.jdom.output.XMLOutputter; //输出
import org.jdom.output.Format; //输出的格式
import java.io.FileWriter; // :)
public class JDomTest {
public static void main(String[] args) throws Exception{
Element root=new Element("人员信息");
Document document=new Document(root); //建立新XML文档,并以根元素初始化
root.addContent(new Comment("新进公司职员")); //建立新元素,并将新元素作为根元素的内容.
root.setAttribute(new Attribute("单位","XXXX软件公司"));
root.addContent(new Element("姓名").addContent("XYZ"));
root.addContent(new Element("年龄").addContent("23")
.setAttribute("体形","适中"));
root.addContent(new Element("性别").addContent("男"));
root.addContent(new Element("身高").addContent("green"));
root.addContent(new Element("体重").addContent("75KG"));
//output
Format format=Format.getPrettyFormat(); //静态方法,产生两个空格的缩进格式
format.setIndent(" "); //变成四个空格的缩进格式,用四个空格字符作参数
format.setEncoding("gb2312"); //设置编码格式
XMLOutputter out=new XMLOutputter(format);
out.output(document,System.out); //输出到控制台
FileWriter writer=new FileWriter("./jdomtest.xml");
out.output(document,writer); //输出到文件
}
}
二.说明:
以上代码根据网上文章所写,总体感觉JDOM使用起来,比SAX,DOM要顺手的多(仅为个人观点)。
三.程序输出
<?xml version="1.0" encoding="gb2312"?>
<人员信息 单位="XXXX软件公司">
<!--新进公司职员-->
<姓名>XYZ</姓名>
<年龄 体形="适中">23</年龄>
<性别>男</性别>
<身高>green</身高>
<体重>75KG</体重>
</人员信息>