Thrift在Tomcat中以Servlet运行

Thrift在Tomcat中以Servlet运行

创建Servlet继承自TServlet

以前在将Thrift服务在Tomcat中以Servlet运行时,需要自己实现协议转换的“中间”Servlet,现在只需要继承org.apache.thrift.server.TServlet就可以,(Thrift的基本知识在此不再冗述,读者可自己查看github。此处的例子基于其中的tutorial和shared示例)实例代码如下:
CalculatorServiceServlet.java

import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServlet;

public class CalculatorServiceServlet extends TServlet {
    
    

    public CalculatorServiceServlet() {
    
    
        super(new Calculator.Processor<>(new CalculatorHandler()), new TBinaryProtocol.Factory());
    }
}

注:
如果在请求的数据未到达Servlet前增加自定义的数据处理,可自己编写继承自HttpServlet类,替换TServlet,代码如下:

import org.apache.thrift.TException;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.transport.TIOStreamTransport;
import org.apache.thrift.transport.TTransport;

public class TCommonServlet extends HttpServlet {
    
    
    private final TProcessor processor;
    private final TProtocolFactory inProtocolFactory;
    private final TProtocolFactory outProtocolFactory;
    private final Collection<Entry<String, String>> customHeaders;

    public TCommonServlet(TProcessor processor, TProtocolFactory inProtocolFactory, TProtocolFactory outProtocolFactory) {
    
    
        this.processor = processor;
        this.inProtocolFactory = inProtocolFactory;
        this.outProtocolFactory = outProtocolFactory;
        this.customHeaders = new ArrayList();
    }

    public TCommonServlet(TProcessor processor, TProtocolFactory protocolFactory) {
    
    
        this(processor, protocolFactory, protocolFactory);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        TTransport inTransport = null;
        Object var4 = null;
		//打印header中的内容
        Enumeration enums = request.getHeaderNames();
        while (enums.hasMoreElements()) {
    
    
            String key = (String) enums.nextElement();
            System.out.println("key: " + key);
            System.out.println("value: " + request.getHeader(key));
        }
        System.out.println("--------------");

        try {
    
    
            response.setContentType("application/x-thrift");
            if (null != this.customHeaders) {
    
    
                Iterator var5 = this.customHeaders.iterator();

                while(var5.hasNext()) {
    
    
                    Entry<String, String> header = (Entry)var5.next();
                    response.addHeader((String)header.getKey(), (String)header.getValue());
                }
            }

            InputStream in = request.getInputStream();
            OutputStream out = response.getOutputStream();
            TTransport transport = new TIOStreamTransport(in, out);
            TProtocol inProtocol = this.inProtocolFactory.getProtocol(transport);
            TProtocol outProtocol = this.outProtocolFactory.getProtocol(transport);
            this.processor.process(inProtocol, outProtocol);
            out.flush();
        } catch (TException var10) {
    
    
            throw new ServletException(var10);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        this.doPost(request, response);
    }

    public void addCustomHeader(final String key, final String value) {
    
    
        this.customHeaders.add(new Entry<String, String>() {
    
    
            public String getKey() {
    
    
                return key;
            }

            public String getValue() {
    
    
                return value;
            }

            public String setValue(String valuex) {
    
    
                return null;
            }
        });
    }

    public void setCustomHeaders(Collection<Entry<String, String>> headers) {
    
    
        this.customHeaders.clear();
        this.customHeaders.addAll(headers);
    }
}

CalculatorHandler.java

import org.apache.thrift.TException;

import java.util.HashMap;

public class CalculatorHandler implements Calculator.Iface {
    
    

    private HashMap<Integer, SharedStruct> log;

    public CalculatorHandler() {
    
    
        log = new HashMap<Integer, SharedStruct>();
    }

    @Override
    public void ping() throws TException {
    
    
        System.out.println("ping()");
    }

    @Override
    public int add(int num1, int num2) throws TException {
    
    
        System.out.println("add(" + num1 + "," + num2 + ")");
        return num1 + num2;
    }

    @Override
    public int calculate(int logid, Work w) throws InvalidOperation, TException {
    
    
        System.out.println("calculate(" + logid + ",{" + w.op + "," + w.num1 + "," + w.num2 + "})");
        int val = 0;
        switch (w.op) {
    
    
            case ADD:
                val = w.num1 + w.num2;
                break;
            case SUBTRACT:
                val = w.num1 - w.num2;
                break;
            case MULTIPLY:
                val = w.num1 * w.num2;
                break;
            case DIVIDE:
                if (w.num2 == 0) {
    
    
                    InvalidOperation io = new InvalidOperation();
                    io.whatOp = w.op.getValue();
                    io.why = "Cannot divide by 0";
                    throw io;
                }
                val = w.num1 / w.num2;
                break;
            default:
                InvalidOperation io = new InvalidOperation();
                io.whatOp = w.op.getValue();
                io.why = "Unknown operation";
                throw io;
        }
        SharedStruct entry = new SharedStruct();
        entry.key = logid;
        entry.value = Integer.toString(val);
        log.put(logid, entry);
        return 0;
    }

    @Override
    public void zip() throws TException {
    
    
        System.out.println("zip()");
    }

    @Override
    public SharedStruct getStruct(int key) throws TException {
    
    
        System.out.println("getStruct(" + key + ")");
        return log.get(key);
    }
}

web.xml

    <servlet>
        <servlet-name>CalculatorServiceServlet</servlet-name>
        <servlet-class>xxx.servlets.CalculatorServiceServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>CalculatorServiceServlet</servlet-name>
        <url-pattern>/CalculatorService</url-pattern>
    </servlet-mapping>

编译打包成war包,部署到Tomcat中即可。客户端代码如下:
Client.java

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.THttpClient;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;

public class ClientApp {
    
    

    public static void main(String[] args) {
    
    

        try {
    
    
            //TTransport transport = new TSocket("localhost", 9090); //访问Thrift server
            //transport.open();
            THttpClient httpClient = new THttpClient("http://localhost:8080/CalculatorService"); //访问Tomcat中Servlet


            TProtocol protocol = new TBinaryProtocol(httpClient);
            Calculator.Client client = new Calculator.Client(protocol);

            perform(client);
            //transport.close(); //
            httpClient.close();
        } catch (TTransportException tranx) {
    
    
            tranx.printStackTrace();
        } catch (TException e) {
    
    
            e.printStackTrace();
        }
    }

    public static void perform(Calculator.Client client) throws TException {
    
    
        client.ping();
        System.out.println("ping()");

        int sum = client.add(1, 2);
        System.out.println("1+2=" + sum);

        Work work = new Work();
        work.op = Operation.DIVIDE;
        work.num1 = 1;
        work.num2 = 0;

        try {
    
    
            int quotient = client.calculate(1, work);
            System.out.println("Whoa we can divide by 0");
        } catch (InvalidOperation io) {
    
    
            System.out.println("Invalid operation: " + io.why);
        }

        work.op = Operation.SUBTRACT;
        work.num1 = 15;
        work.num2 = 10;

        try {
    
    
            int diff = client.calculate(1, work);
            System.out.println("15-10=" + diff);
        } catch (InvalidOperation io) {
    
    
            System.out.println("Invalid operation: " + io.why);
        }

        SharedStruct log = client.getStruct(1);
        System.out.println("Check log: " + log.value);
    }
}

猜你喜欢

转载自blog.csdn.net/leon_founder/article/details/83690770