dimanche 31 janvier 2016

How to implement Template Method in Servlet

I'd like to create two HttpServlets with some variation of template method (GOF). So I created abstract class extended from HttpServlet:

abstract public class AbstractServlet extends HttpServlet {

    abstract void doSomeAction();

    @Override
    protected void service(HttpServletRequest rq, HttpServletResponse rs){

        try {
            //here some logging, getting headers etc.
            System.out.println("Nothing really matters");

            //invoke concrete class
            doSomeAction();

            //write response
            rs.getOutputStream().write(new String("Simple response from class " + this.getClass().getCanonicalName()).getBytes());

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

And two concrete class:

public class A extends AbstractServlet {

    @Override
    void doSomeAction() {
        System.out.println("I'm doing something in A");
    }
}


public class B extends AbstractServlet {
    @Override
    void doSomeAction() {
        System.out.println("I'm doing something in B");
    }
}

After invoke (successfully) one of those services, I can't get any response. After some debugging, it'seems like Tomcat has some problem with NIO channels and latch:

2016-01-31 19:13:52 Http11NioProtocol [DEBUG] Socket: [org.apache.tomcat.util.net.NioEndpoint$KeyAttachment@6bc6f271:org.apache.tomcat.util.net.NioChannel@2072289:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:57585]], Status in: [OPEN_READ], State out: [CLOSED]

2016-01-31 19:13:52 LimitLatch [DEBUG] Counting down[http-nio-8080-exec-2] latch=1

But to be honest, I don't know what's going on. The funny part is, when servlet consume all servletrequest input stream by for example IOUtils.toByteArray(InputStream is), everything works fine!

abstract public class AbstractServlet extends HttpServlet {

    abstract void doSomeAction();

    @Override
    protected void service(HttpServletRequest rq, HttpServletResponse rs){

        try {
            //here some logging, getting headers etc.


        //Consume all inputStream
        org.apache.commons.io.IOUtils.toByteArray(rq.getInputStream());

        //invoke concrete class
        doSomeAction();

        //write response
        rs.getOutputStream().write(new String("Simple response from class " + this.getClass().getCanonicalName()).getBytes());

    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

Where is the problem?

Best regards.

Aucun commentaire:

Enregistrer un commentaire