Apache Mina:如何编写Http服务器?

时间:2019-04-17 11:59:30

标签: java nio apache-mina

我正在尝试使用Apache Mina编写Http Server。

根据Mina的体系结构,应该有2个用于此任务的过滤器,一个用于Http请求传递,另一个用于处理请求并生成响应。因此,使用Mina示例代码,我想到了以下代码,其中包含一个接受器,日志记录过滤器,Http过滤器和一个用于处理请求的过滤器。

服务器的启动正确运行,但是请求未到达DummyHttpSever过滤器。我尝试调试,但是找不到问题。怎么了?

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.api.AbstractIoFilter;
import org.apache.mina.api.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filterchain.ReadFilterChainController;
import org.apache.mina.http.DateUtil;
import org.apache.mina.http.HttpDecoderState;
import org.apache.mina.http.HttpServerDecoder;
import org.apache.mina.http.HttpServerEncoder;
import org.apache.mina.http.api.DefaultHttpResponse;
import org.apache.mina.http.api.HttpContentChunk;
import org.apache.mina.http.api.HttpEndOfContent;
import org.apache.mina.http.api.HttpMethod;
import org.apache.mina.http.api.HttpPdu;
import org.apache.mina.http.api.HttpRequest;
import org.apache.mina.http.api.HttpStatus;
import org.apache.mina.http.api.HttpVersion;
import org.apache.mina.transport.nio.NioTcpServer;

public class HttpTest {

    public static void main(String[] args) throws Exception {

        NioTcpServer httpServer = new NioTcpServer();
        httpServer.setReuseAddress(true);
        httpServer.setFilters(new ProtocolCodecFilter<HttpPdu, ByteBuffer, Void, HttpDecoderState>(new HttpServerEncoder(),
                        new HttpServerDecoder()), new LoggingFilter("DECODED"), new DummyHttpSever());


        httpServer.getSessionConfig().setTcpNoDelay(true);

        httpServer.bind(new InetSocketAddress(8080));

        // run for 20 seconds
        Thread.sleep(2000000000);
        httpServer.unbind();

    }

    private static class DummyHttpSever extends AbstractIoFilter {

        private HttpRequest incomingRequest;

        private List<ByteBuffer> body;

        @Override
        public void messageReceived(IoSession session, Object message, ReadFilterChainController controller) {
            if (message instanceof HttpRequest) {
                System.out.println("This shit is working");


                incomingRequest = (HttpRequest) message;
                body = new ArrayList<ByteBuffer>();

                // check if this request is going to be followed by and HTTP body or not
                if (incomingRequest.getMethod() != HttpMethod.POST && incomingRequest.getMethod() != HttpMethod.PUT) {
                    sendResponse(session, incomingRequest);
                } else {

                }
            } else if (message instanceof ByteBuffer) {
                body.add((ByteBuffer) message);
            } else if (message instanceof HttpEndOfContent) {
                // we received all the post content, send the crap back
                sendResponse(session, incomingRequest);
            }

        }

        public void sendResponse(IoSession session, HttpRequest request) {
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("Server", "Apache MINA Dummy test server/0.0.");
            headers.put("Date", DateUtil.getCurrentAsString());
            headers.put("Connection", "Close");
            String strContent = "Hello ! we reply to request !";
            ByteBuffer content = ByteBuffer.wrap(strContent.getBytes());

            // compute content len
            headers.put("Content-Length", String.valueOf(content.remaining()));
            session.write(new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SUCCESS_OK, headers));
            session.write(new HttpContentChunk(content));
            session.write(new HttpEndOfContent());
            session.close(false);

        }
    }
}

此外,以下是我正在使用的依赖项。

<dependency>
            <groupId>org.apache.mina</groupId>
            <artifactId>mina-core</artifactId>
            <version>2.0.7</version>
        </dependency>

        <dependency>
            <groupId>org.apache.mina</groupId>
            <artifactId>mina-http</artifactId>
            <version>2.0.7</version>
        </dependency>

        <dependency>
            <groupId>org.apache.mina</groupId>
            <artifactId>mina-coap</artifactId>
            <version>2.0.7</version>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>LATEST</version>
        </dependency>

1 个答案:

答案 0 :(得分:0)

这是一个简单的Http Web服务器,您可以根据需要进行修改。该示例是对Apache Mina示例的示例轻量级组件的修改。

Main.java

def git():
#name , date , message
#https://api.github.com/repos/droptable461/Project-Project-Management/commits
#commit { author { name and date
#commit { message

    #with urlopen('https://api.github.com/repos/droptable461/Project Project-Management/commits') as response:
        #source = response.read()

    #data = json.loads(source)
    #state = []
    #for state in data['committer']:
        #state.append(state['name'])
        #print(state)

    link = 'https://api.github.com/repos/droptable461/Project-Project-Management/events'
    r = requests.get('https://api.github.com/repos/droptable461/Project-Project-Management/commits')
    #print(r)

    #one = r['commit']
    #print(one)
    for item in r.json():
        for c in item['commit']['committer']:
            print(c['name'],c['date'])

    return 'suc'

HttpProtocalHandler.java

import java.net.InetSocketAddress;

import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.asyncweb.common.codec.HttpCodecFactory;
import org.apache.asyncweb.examples.lightweight.HttpProtocolHandler;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

public class Main {
    public static void main(String[] args) throws Exception {
        SocketAcceptor acceptor = new NioSocketAcceptor();

        acceptor.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(new HttpCodecFactory()));

        acceptor.setReuseAddress(true);
        acceptor.getSessionConfig().setReuseAddress(true);
        acceptor.getSessionConfig().setReceiveBufferSize(1024);
        acceptor.getSessionConfig().setSendBufferSize(1024);
        acceptor.getSessionConfig().setTcpNoDelay(true);
        acceptor.getSessionConfig().setSoLinger(-1);
        acceptor.setBacklog(10240);

        acceptor.setHandler(new HttpProtocolHandler());
        acceptor.bind(new InetSocketAddress(9012));
    }
}