存档

文章标签 ‘java’

初探httpclient

2010年3月28日 没有评论

httpclient是由java实现用来模拟http请求的,开源的,现在已经出到4.1版本了,改动太大了,还是之前的3.1版本比较符合人的思维,主要讲下使用中遇到的问题。

一、编码

编码有好几块,一个是客户端发起请求时指定的编码,一个是服务器返回的编码,还有一个是返回页面的Content-Type里指定的编码,一般来说后两者是相同的。

对于发起请求时的编码,可以先查看网页的源码,拿到里面的编码作为请求时的编码即可。

为了获取正确的返回内容,可以采用如下:

System.out.println("response body: "+new String(method.getResponseBody(), method.getRequestCharSet()))

有些时候通过指定正确的编码还是返回乱码,有可能是由于服务端采用gzip压缩的原因,尝试在request header里去掉[Accept-Encoding,gzip,deflate]也许会返回正确的结果。
二、为get/post指定请求编码

分别继承各自的父类,然后重载getRequestCharSet,如get方法

public class EncodedGetMethod extends GetMethod {
	private String charSet = "utf-8";

	public EncodedGetMethod(String uri, String charset) {
		super(uri);
		this.charSet = charset;
	}

	@Override
	public String getRequestCharSet() {
		return this.charSet;
	}
}

三、post的两种传参数方式

对于表单提交,一般有两种,带有图片,form的属性里有enctype=”multipart/form-data”;还有一种是简单的纯文本提交,如输入用户名密码然后登录的表单。

httpclient针对这两种form使用了不同的传参数方式,

1. 对于有图片的form提交使用Part[],有两种,StringPart用于传简单的文本,FilePart用于传文件,典型的StringPart如下:

StringPart sp = new StringPart(name, value, charset);

2. 对于纯文本的form提交使用NameValuePair[]

四、关于cookie

httpclient已经相当聪明了,会自动管理cookie,对于一个client发出的一系列get/post请求都享有当前的cookie。

参考:

  1. httpclient主页
  2. 关于编码
  3. 关于multipart表单的post方法
分类: java 标签: ,

初识jdk代理

2009年3月5日 没有评论

关键的类:java.lang.reflect.Proxy,java.lang.reflect.InvocationHandler
关键的方法:
Proxy类的

public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)  throws IllegalArgumentException

参数说明:
loader:用来加载被代理类的classloader
interfaces: 被代理类实现的接口
h:当被代理类调用实现的接口的某个方法时,由此handler来决定怎么做

通过上面的参数分析,可以看出要让一个class被代理,需要几个步骤:
1. 定义一个或多个interface,被代理类实现这些interface
2. 定一个handler,此handler必须实现InvocationHandler接口


InvocationHandler接口只有一个方法:
public Object invoke(Object proxy, Method method, Object[] args)   throws Throwable;
参数说明:
proxy: 被代理类的instance
method: 被代理类调用的方法,属于上面某个interface的
args: 此方法的参数

从上可以看出,此方法是利用发射来达到调用某个方法的目的,为什么不直接调呢?这样的目的是可以在真正调用此方法前后做一些其他的事情。

具体的例子:
1. 定义一个或多个interface,被代理类实现这些interface

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface AnInterface {
    public void doSth();
}

interface AnotherInterface {
    public void anotherdo();
}
class AClass implements AnInterface,AnotherInterface {
    public void doSth(){
        System.out.println("inside AClass.doSth");
    }

    public void anotherdo() {
        System.out.println("inside AClass.anotherdo");
    }
}

2.  定一个handler,此handler必须实现InvocationHandler接口

class SimpleInvocationHandler implements InvocationHandler {
     private Object realObject;
     public SimpleInvocationHandler(Object realObject){
          this.realObject = realObject;
     }
     public Object invoke(Object proxy, Method method, Object[] args)  throws Throwable {
         Object result = null;
         System.out.println("Before calling: "+method.getName());
         result = method.invoke(realObject, args);
         System.out.println("After calling: "+method.getName());
         System.out.println(proxy.getClass().getName());
         return result;
    }
}

3. 查看效果

public class ProxyTest {
     public static void main(String[] args) {
         AnInterface realSubject = new AClass();
         Class[] clazs = realSubject.getClass().getInterfaces();
         for(Class c : clazs) {
               System.out.println(c.getName());
               AnInterface proxy =                 (AnInterface)Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),
//                realSubject.getClass().getInterfaces(),
                  new Class[]{AnInterface.class},
                  new SimpleInvocationHandler(realSubject));

               proxy.doSth();
              System.out.println(Proxy.isProxyClass(proxy.getClass()));
              System.out.println(proxy instanceof AnInterface);

              if(proxy instanceof AnotherInterface){
                  AnotherInterface ai = (AnotherInterface)proxy;
                  ai.anotherdo();
              }
         }
     }
}

注:生成的代理类都是以$Proxy开头的,尽管自己新建一个类的时候也可以以$Proxy开头,但是不建议这么做

分类: java 标签: