Burlap中hessian协议研究(二)协议的实现

远程技术的研究

本人使用反编译工具查看源代码:

 使用MircoBurlapOutput类生成xml文件:

package com.caucho.burlap.client;

import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

public class MicroBurlapOutput
{

    public MicroBurlapOutput(OutputStream os)
    {
        init(os);
    }

    public MicroBurlapOutput()
    {
    }

    public void init(OutputStream os)
    {
        this.os = os;
    }

    public void call(String method, Object args[])
        throws IOException
    {
        startCall(method);
        if(args != null)
        {
            for(int i = 0; i < args.length; i++)
                writeObject(args[i]);

        }
        completeCall();
    }

    public void startCall(String method)
        throws IOException
    {
        print("<burlap:call><method>");
        print(method);
        print("</method>");
    }

    public void completeCall()
        throws IOException
    {
        print("</burlap:call>");
    }

    public void writeBoolean(boolean value)
        throws IOException
    {
        print("<boolean>");
        printInt(value ? 1 : 0);
        print("</boolean>");
    }

    public void writeInt(int value)
        throws IOException
    {
        print("<int>");
        printInt(value);
        print("</int>");
    }

    public void writeLong(long value)
        throws IOException
    {
        print("<long>");
        printLong(value);
        print("</long>");
    }

    public void writeNull()
        throws IOException
    {
        print("<null></null>");
    }

    public void writeString(String value)
        throws IOException
    {
        if(value == null)
        {
            print("<null></null>");
        } else
        {
            print("<string>");
            printString(value);
            print("</string>");
        }
    }

    public void writeBytes(byte buffer[], int offset, int length)
        throws IOException
    {
        if(buffer == null)
        {
            print("<null></null>");
        } else
        {
            print("<base64>");
            printBytes(buffer, offset, length);
            print("</base64>");
        }
    }

    public void writeUTCDate(long time)
        throws IOException
    {
        print("<date>");
        if(utcCalendar == null)
        {
            utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
            date = new Date();
        }
        date.setTime(time);
        utcCalendar.setTime(date);
        printDate(utcCalendar);
        print("</date>");
    }

    public void writeLocalDate(long time)
        throws IOException
    {
        print("<date>");
        if(localCalendar == null)
        {
            localCalendar = Calendar.getInstance();
            date = new Date();
        }
        date.setTime(time);
        localCalendar.setTime(date);
        printDate(localCalendar);
        print("</date>");
    }

    public void writeRef(int value)
        throws IOException
    {
        print("<ref>");
        printInt(value);
        print("</ref>");
    }

    public void writeObject(Object object)
        throws IOException
    {
        if(object == null)
            writeNull();
        else
        if(object instanceof String)
            writeString((String)object);
        else
        if(object instanceof Boolean)
            writeBoolean(((Boolean)object).booleanValue());
        else
        if(object instanceof Integer)
            writeInt(((Integer)object).intValue());
        else
        if(object instanceof Long)
            writeLong(((Long)object).longValue());
        else
        if(object instanceof Date)
            writeUTCDate(((Date)object).getTime());
        else
        if(object instanceof byte[])
        {
            byte data[] = (byte[])object;
            writeBytes(data, 0, data.length);
        } else
        if(object instanceof Vector)
        {
            Vector vector = (Vector)object;
            int size = vector.size();
            writeListBegin(size, null);
            for(int i = 0; i < size; i++)
                writeObject(vector.elementAt(i));

            writeListEnd();
        } else
        if(object instanceof Hashtable)
        {
            Hashtable hashtable = (Hashtable)object;
            writeMapBegin(null);
            Object value;
            for(Enumeration e = hashtable.keys(); e.hasMoreElements(); writeObject(value))
            {
                Object key = e.nextElement();
                value = hashtable.get(key);
                writeObject(key);
            }

            writeMapEnd();
        } else
        {
            writeCustomObject(object);
        }
    }

    public void writeCustomObject(Object object)
        throws IOException
    {
        throw new IOException("unexpected object: " + object);
    }

    public void writeListBegin(int length, String type)
        throws IOException
    {
        print("<list><type>");
        if(type != null)
            print(type);
        print("</type><length>");
        printInt(length);
        print("</length>");
    }

    public void writeListEnd()
        throws IOException
    {
        print("</list>");
    }

    public void writeMapBegin(String type)
        throws IOException
    {
        print("<map><type>");
        if(type != null)
            print(type);
        print("</type>");
    }

    public void writeMapEnd()
        throws IOException
    {
        print("</map>");
    }

    public void writeRemote(String type, String url)
        throws IOException
    {
        print("<remote><type>");
        if(type != null)
            print(type);
        print("</type><string>");
        print(url);
        print("</string></remote>");
    }

    public void printInt(int v)
        throws IOException
    {
        print(String.valueOf(v));
    }

    public void printLong(long v)
        throws IOException
    {
        print(String.valueOf(v));
    }

    public void printString(String v)
        throws IOException
    {
        int len = v.length();
        for(int i = 0; i < len; i++)
        {
            char ch = v.charAt(i);
            switch(ch)
            {
            case 60: // '<'
                print("&lt;");
                break;

            case 38: // '&'
                print("&amp;");
                break;

            case 13: // '\r'
                print("&#13;");
                break;

            default:
                if(ch < '\200')
                {
                    os.write(ch);
                    break;
                }
                if(ch < '\u0800')
                {
                    os.write(192 + (ch >> 6 & 0x1f));
                    os.write(128 + (ch & 0x3f));
                } else
                {
                    os.write(224 + (ch >> 12 & 0xf));
                    os.write(128 + (ch >> 6 & 0x3f));
                    os.write(128 + (ch & 0x3f));
                }
                break;
            }
        }

    }

    public void printBytes(byte data[], int offset, int length)
        throws IOException
    {
        for(; length >= 3; length -= 3)
        {
            int chunk = ((data[offset] & 0xff) << 16) + ((data[offset + 1] & 0xff) << 8) + (data[offset + 2] & 0xff);
            os.write(base64encode(chunk >> 18));
            os.write(base64encode(chunk >> 12));
            os.write(base64encode(chunk >> 6));
            os.write(base64encode(chunk));
            offset += 3;
        }

        if(length == 2)
        {
            int chunk = ((data[offset] & 0xff) << 8) + (data[offset + 1] & 0xff);
            os.write(base64encode(chunk >> 12));
            os.write(base64encode(chunk >> 6));
            os.write(base64encode(chunk));
            os.write(61);
        } else
        if(length == 1)
        {
            int chunk = data[offset] & 0xff;
            os.write(base64encode(chunk >> 6));
            os.write(base64encode(chunk));
            os.write(61);
            os.write(61);
        }
    }

    public static char base64encode(int d)
    {
        d &= 0x3f;
        if(d < 26)
            return (char)(d + 65);
        if(d < 52)
            return (char)((d + 97) - 26);
        if(d < 62)
            return (char)((d + 48) - 52);
        return d != 62 ? '/' : '+';
    }

    public void printDate(Calendar calendar)
        throws IOException
    {
        int year = calendar.get(1);
        os.write((char)(48 + (year / 1000) % 10));
        os.write((char)(48 + (year / 100) % 10));
        os.write((char)(48 + (year / 10) % 10));
        os.write((char)(48 + year % 10));
        int month = calendar.get(2) + 1;
        os.write((char)(48 + (month / 10) % 10));
        os.write((char)(48 + month % 10));
        int day = calendar.get(5);
        os.write((char)(48 + (day / 10) % 10));
        os.write((char)(48 + day % 10));
        os.write(84);
        int hour = calendar.get(11);
        os.write((char)(48 + (hour / 10) % 10));
        os.write((char)(48 + hour % 10));
        int minute = calendar.get(12);
        os.write((char)(48 + (minute / 10) % 10));
        os.write((char)(48 + minute % 10));
        int second = calendar.get(13);
        os.write((char)(48 + (second / 10) % 10));
        os.write((char)(48 + second % 10));
        os.write(90);
    }

    public void print(String s)
        throws IOException
    {
        int len = s.length();
        for(int i = 0; i < len; i++)
        {
            int ch = s.charAt(i);
            os.write(ch);
        }

    }

    private OutputStream os;
    private Date date;
    private Calendar utcCalendar;
    private Calendar localCalendar;
}

 此类MicroBurlapInput类解析响应xml文件

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name:   MicroBurlapInput.java

package com.caucho.burlap.client;

import java.io.*;
import java.util.*;

// Referenced classes of package com.caucho.burlap.client:
//            BurlapServiceException, BurlapProtocolException, BurlapRemote

public class MicroBurlapInput
{

    public MicroBurlapInput(InputStream is)
    {
        sbuf = new StringBuffer();
        entity = new StringBuffer();
        init(is);
    }

    public MicroBurlapInput()
    {
        sbuf = new StringBuffer();
        entity = new StringBuffer();
    }

    public String getMethod()
    {
        return method;
    }

    public void init(InputStream is)
    {
        this.is = is;
        refs = null;
    }

    public void startCall()
        throws IOException
    {
        expectStartTag("burlap:call");
        expectStartTag("method");
        method = parseString();
        expectEndTag("method");
        refs = null;
    }

    public void completeCall()
        throws IOException
    {
        expectEndTag("burlap:call");
    }

    public Object readReply(Class expectedClass)
        throws Exception
    {
        if(startReply())
        {
            Object value = readObject(expectedClass);
            expectEndTag("value");
            completeReply();
            return value;
        }
        Hashtable fault = readFault();
        Object detail = fault.get("detail");
        if(detail instanceof Exception)
        {
            throw (Exception)detail;
        } else
        {
            String code = (String)fault.get("code");
            String message = (String)fault.get("message");
            throw new BurlapServiceException(message, code, detail);
        }
    }

    public boolean startReply()
        throws IOException
    {
        refs = null;
        expectStartTag("burlap:reply");
        if(!parseTag())
            throw new BurlapProtocolException("expected <value>");
        String tag = sbuf.toString();
        if(tag.equals("fault"))
        {
            peekTag = true;
            return false;
        }
        if(tag.equals("value"))
            return true;
        else
            throw expectBeginTag("value", tag);
    }

    public void completeReply()
        throws IOException
    {
        expectEndTag("burlap:reply");
    }

    public boolean readBoolean()
        throws IOException
    {
        expectStartTag("boolean");
        int value = parseInt();
        expectEndTag("boolean");
        return value != 0;
    }

    public int readInt()
        throws IOException
    {
        expectStartTag("int");
        int value = parseInt();
        expectEndTag("int");
        return value;
    }

    public long readLong()
        throws IOException
    {
        expectStartTag("long");
        long value = parseLong();
        expectEndTag("long");
        return value;
    }

    public long readUTCDate()
        throws IOException
    {
        expectStartTag("date");
        if(utcCalendar == null)
            utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
        long value = parseDate(utcCalendar);
        expectEndTag("date");
        return value;
    }

    public long readLocalDate()
        throws IOException
    {
        expectStartTag("date");
        if(localCalendar == null)
            localCalendar = Calendar.getInstance();
        long value = parseDate(localCalendar);
        expectEndTag("date");
        return value;
    }

    public BurlapRemote readRemote()
        throws IOException
    {
        expectStartTag("remote");
        String type = readType();
        String url = readString();
        expectEndTag("remote");
        return new BurlapRemote(type, url);
    }

    public String readString()
        throws IOException
    {
        if(!parseTag())
            throw new BurlapProtocolException("expected <string>");
        String tag = sbuf.toString();
        if(tag.equals("null"))
        {
            expectEndTag("null");
            return null;
        }
        if(tag.equals("string"))
        {
            sbuf.setLength(0);
            parseString(sbuf);
            String value = sbuf.toString();
            expectEndTag("string");
            return value;
        } else
        {
            throw expectBeginTag("string", tag);
        }
    }

    public byte[] readBytes()
        throws IOException
    {
        if(!parseTag())
            throw new BurlapProtocolException("expected <base64>");
        String tag = sbuf.toString();
        if(tag.equals("null"))
        {
            expectEndTag("null");
            return null;
        }
        if(tag.equals("base64"))
        {
            sbuf.setLength(0);
            byte value[] = parseBytes();
            expectEndTag("base64");
            return value;
        } else
        {
            throw expectBeginTag("base64", tag);
        }
    }

    public Object readObject(Class expectedClass)
        throws IOException
    {
        if(!parseTag())
            throw new BurlapProtocolException("expected <tag>");
        String tag = sbuf.toString();
        if(tag.equals("null"))
        {
            expectEndTag("null");
            return null;
        }
        if(tag.equals("boolean"))
        {
            int value = parseInt();
            expectEndTag("boolean");
            return new Boolean(value != 0);
        }
        if(tag.equals("int"))
        {
            int value = parseInt();
            expectEndTag("int");
            return new Integer(value);
        }
        if(tag.equals("long"))
        {
            long value = parseLong();
            expectEndTag("long");
            return new Long(value);
        }
        if(tag.equals("string"))
        {
            sbuf.setLength(0);
            parseString(sbuf);
            String value = sbuf.toString();
            expectEndTag("string");
            return value;
        }
        if(tag.equals("xml"))
        {
            sbuf.setLength(0);
            parseString(sbuf);
            String value = sbuf.toString();
            expectEndTag("xml");
            return value;
        }
        if(tag.equals("date"))
        {
            if(utcCalendar == null)
                utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
            long value = parseDate(utcCalendar);
            expectEndTag("date");
            return new Date(value);
        }
        if(tag.equals("map"))
        {
            String type = readType();
            return readMap(expectedClass, type);
        }
        if(tag.equals("list"))
        {
            String type = readType();
            int length = readLength();
            return readList(expectedClass, type, length);
        }
        if(tag.equals("ref"))
        {
            int value = parseInt();
            expectEndTag("ref");
            return refs.elementAt(value);
        }
        if(tag.equals("remote"))
        {
            String type = readType();
            String url = readString();
            expectEndTag("remote");
            return resolveRemote(type, url);
        } else
        {
            return readExtensionObject(expectedClass, tag);
        }
    }

    public String readType()
        throws IOException
    {
        if(!parseTag())
            throw new BurlapProtocolException("expected <type>");
        String tag = sbuf.toString();
        if(!tag.equals("type"))
        {
            throw new BurlapProtocolException("expected <type>");
        } else
        {
            sbuf.setLength(0);
            parseString(sbuf);
            String value = sbuf.toString();
            expectEndTag("type");
            return value;
        }
    }

    public int readLength()
        throws IOException
    {
        expectStartTag("length");
        int ch = skipWhitespace();
        peek = ch;
        if(ch == 60)
        {
            expectEndTag("length");
            return -1;
        } else
        {
            int value = parseInt();
            expectEndTag("length");
            return value;
        }
    }

    public Object resolveRemote(String type, String url)
        throws IOException
    {
        return new BurlapRemote(type, url);
    }

    public Hashtable readFault()
        throws IOException
    {
        expectStartTag("fault");
        Hashtable map = new Hashtable();
        do
        {
            if(!parseTag())
                break;
            peekTag = true;
            Object key = readObject(null);
            Object value = readObject(null);
            if(key != null && value != null)
                map.put(key, value);
        } while(true);
        if(!sbuf.toString().equals("fault"))
            throw new BurlapProtocolException("expected </fault>");
        else
            return map;
    }

    public Object readMap(Class expectedClass, String type)
        throws IOException
    {
        Hashtable map = new Hashtable();
        if(refs == null)
            refs = new Vector();
        refs.addElement(map);
        Object key;
        Object value;
        for(; parseTag(); map.put(key, value))
        {
            peekTag = true;
            key = readObject(null);
            value = readObject(null);
        }

        if(!sbuf.toString().equals("map"))
            throw new BurlapProtocolException("expected </map>");
        else
            return map;
    }

    protected Object readExtensionObject(Class expectedClass, String tag)
        throws IOException
    {
        throw new BurlapProtocolException("unknown object tag <" + tag + ">");
    }

    public Object readList(Class expectedClass, String type, int length)
        throws IOException
    {
        Vector list = new Vector();
        if(refs == null)
            refs = new Vector();
        refs.addElement(list);
        Object value;
        for(; parseTag(); list.addElement(value))
        {
            peekTag = true;
            value = readObject(null);
        }

        if(!sbuf.toString().equals("list"))
            throw new BurlapProtocolException("expected </list>");
        else
            return list;
    }

    protected int parseInt()
        throws IOException
    {
        int sign = 1;
        int value = 0;
        int ch = skipWhitespace();
        if(ch == 43)
            ch = read();
        else
        if(ch == 45)
        {
            sign = -1;
            ch = read();
        }
        for(; ch >= 48 && ch <= 57; ch = read())
            value = (10 * value + ch) - 48;

        peek = ch;
        return sign * value;
    }

    protected long parseLong()
        throws IOException
    {
        long sign = 1L;
        long value = 0L;
        int ch = skipWhitespace();
        if(ch == 43)
            ch = read();
        else
        if(ch == 45)
        {
            sign = -1L;
            ch = read();
        }
        for(; ch >= 48 && ch <= 57; ch = read())
            value = (10L * value + (long)ch) - 48L;

        peek = ch;
        return sign * value;
    }

    protected long parseDate(Calendar calendar)
        throws IOException
    {
        int ch = skipWhitespace();
        int year = 0;
        for(int i = 0; i < 4; i++)
        {
            if(ch >= 48 && ch <= 57)
                year = (10 * year + ch) - 48;
            else
                throw expectedChar("year", ch);
            ch = read();
        }

        int month = 0;
        for(int i = 0; i < 2; i++)
        {
            if(ch >= 48 && ch <= 57)
                month = (10 * month + ch) - 48;
            else
                throw expectedChar("month", ch);
            ch = read();
        }

        int day = 0;
        for(int i = 0; i < 2; i++)
        {
            if(ch >= 48 && ch <= 57)
                day = (10 * day + ch) - 48;
            else
                throw expectedChar("day", ch);
            ch = read();
        }

        if(ch != 84)
            throw expectedChar("`T'", ch);
        ch = read();
        int hour = 0;
        for(int i = 0; i < 2; i++)
        {
            if(ch >= 48 && ch <= 57)
                hour = (10 * hour + ch) - 48;
            else
                throw expectedChar("hour", ch);
            ch = read();
        }

        int minute = 0;
        for(int i = 0; i < 2; i++)
        {
            if(ch >= 48 && ch <= 57)
                minute = (10 * minute + ch) - 48;
            else
                throw expectedChar("minute", ch);
            ch = read();
        }

        int second = 0;
        for(int i = 0; i < 2; i++)
        {
            if(ch >= 48 && ch <= 57)
                second = (10 * second + ch) - 48;
            else
                throw expectedChar("second", ch);
            ch = read();
        }

        for(; ch > 0 && ch != 60; ch = read());
        peek = ch;
        calendar.set(1, year);
        calendar.set(2, month - 1);
        calendar.set(5, day);
        calendar.set(11, hour);
        calendar.set(12, minute);
        calendar.set(13, second);
        calendar.set(14, 0);
        return calendar.getTime().getTime();
    }

    protected String parseString()
        throws IOException
    {
        StringBuffer sbuf = new StringBuffer();
        return parseString(sbuf).toString();
    }

    protected StringBuffer parseString(StringBuffer sbuf)
        throws IOException
    {
        int ch;
        for(ch = read(); ch >= 0 && ch != 60; ch = read())
        {
            if(ch == 38)
            {
                ch = read();
                if(ch == 35)
                {
                    ch = read();
                    if(ch >= 48 && ch <= 57)
                    {
                        int v = 0;
                        for(; ch >= 48 && ch <= 57; ch = read())
                            v = (10 * v + ch) - 48;

                        sbuf.append((char)v);
                    }
                } else
                {
                    StringBuffer entityBuffer = new StringBuffer();
                    for(; ch >= 97 && ch <= 122; ch = read())
                        entityBuffer.append((char)ch);

                    String entity = entityBuffer.toString();
                    if(entity.equals("amp"))
                        sbuf.append('&');
                    else
                    if(entity.equals("apos"))
                        sbuf.append('\'');
                    else
                    if(entity.equals("quot"))
                        sbuf.append('"');
                    else
                    if(entity.equals("lt"))
                        sbuf.append('<');
                    else
                    if(entity.equals("gt"))
                        sbuf.append('>');
                    else
                        throw new BurlapProtocolException("unknown XML entity &" + entity + "; at `" + (char)ch + "'");
                }
                if(ch != 59)
                    throw expectedChar("';'", ch);
                continue;
            }
            if(ch < 128)
            {
                sbuf.append((char)ch);
              &

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值