Grizzly 2.2.19 FilterChain vs HttpHandler

时间:2014-01-07 04:33:18

标签: java servlets soapui grizzly

我试图实现一个简单的Grizzly网络服务器,在收到HTTP请求后,将会:

  • 处理指定的过滤器
  • 将请求回复给发件人

我正在提交soapUI的请求并查看我不期望的行为:

RunServer.java:

public class RunServer{
    public static final String HOST = "localhost";
    public static final int PORT = 5151;

    public static void main(String[] args) {
        final HttpServer server = HttpServer.createSimpleServer();

        NetworkListener listener = new NetworkListener("echoCalls", "localhost", 5151);

        FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless();

        filterChainBuilder.add(new TransportFilter());

        filterChainBuilder.add(new StringFilter(Charset.forName("UTF-8")));
        //filterChainBuilder.add(new StringFilter(Charset.forName("ISO-8859-1")));
        //filterChainBuilder.add(new StringFilter(Charset.forName("ASCII")));

        filterChainBuilder.add(new MyEchoFilter());

        listener.setFilterChain(filterChainBuilder.build());

        server.addListener(listener);

        server.getServerConfiguration().addHttpHandler(new MyEchoHandler(), "/echo");

        try{
            server.start();
            System.out.println("Press any key to stop the server...");
            System.in.read();
        }catch(IOException ioe){
            System.err.println(ioe.toString());
        }finally{
            server.stop();
        }

    }

}

MyEchoFilter.java:

public class MyEchoFilter extends BaseFilter{

    public NextAction handleRead(FilterChainContext ctx)throws IOException{

        System.err.println(">>>MyEchoFilter.handleRead()...");

        //|why not working? no response, eventual time out. soapui just hangs up after return NextAction...

        final Object peerAddress = ctx.getAddress();
        final Object message = ctx.getMessage();
        ctx.write(peerAddress, message, null);

        return ctx.getStopAction();
    }

    public NextAction handleWrite(FilterChainContext ctx) throws IOException{
        System.err.println(">>>MyEchoFilter.handleWrite()...");

        return ctx.getStopAction();
    }

    public NextAction handleConnect(FilterChainContext ctx) throws IOException{
        System.err.println(">>>MyEchoFilter.handleConnect()...");

        return ctx.getStopAction();
    }

    public NextAction handleAccept(FilterChainContext ctx) throws IOException{
        System.err.println(">>>MyEchoFilter.handleAccept()...");

        return ctx.getStopAction();
    }

    public NextAction handleClose(FilterChainContext ctx) throws IOException{
        System.err.println(">>>MyEchoFilter.handleClose()...");

        return ctx.getStopAction();
    }

}

MyEchoHandler:

public class MyEchoHandler extends HttpHandler{

    public void service(Request req, Response res) throws Exception{

        System.err.println(">>>handler service method...");

        BufferedReader requestStream = new BufferedReader(new InputStreamReader(req.getInputStream()));

        String reqStrLn;
        StringBuffer callContent = new StringBuffer();
        while((reqStrLn = requestStream.readLine()) != null) callContent.append(reqStrLn);

        res.setContentLength(callContent.length());
        res.getWriter().write(callContent.toString());
    }
}

使用上面的代码,按原样,在启动soapUI请求时触发handleAccept()方法。奇怪的是,handleRead()方法会强制,除非我在RunServer中注释掉UTF-8字符串过滤器:

//filterChainBuilder.add(new StringFilter(Charset.forName("UTF-8")));

我无法弄清楚,如果有人能解释,我会很感激。

但是,更重要的是,MyEchoHandler中的service()方法也不会触发。

只有当我在RunServer中注释掉将FilterChain设置为NetworkListener的行时才会触发:

//listener.setFilterChain(filterChainBuilder.build());

当我避免使用FilterChain时,我确实得到了回复soapUI的回复,但我真的需要FilterChain。

似乎我在这里忽略了一点,我应该避免使用处理程序,支持使用过滤器,但我还没有得到回复soapUI的回复使用过滤器时。

任何人都可以帮我查明我的错误吗?

提前谢谢!

2 个答案:

答案 0 :(得分:1)

当我遇到这个问题时,我花了很长时间才弄明白。

filterChainBuilder.add(new StringFilter(Charset.forName("UTF-8")));

StringFilter将字符串解码/编码为字节,因此使用特殊长度前缀。如果传入的消息无法解码,则会跳过它。因此,看起来方法'handleRead'不会触发。

答案 1 :(得分:0)

因此,简而言之,您的HttpHandler未被调用的原因是,您正在破坏默认情况下安装的FilterChain,它提供了HttpHandler支持。

就分块编码支持而言,已经为您提供了。如果在提交响应时尚未设置内容长度,则响应将使用分块传输编码。