I am writing a server like below
public class Server<T extends RequestHandler> {
public void start() {
try{
this.serverSocket = new ServerSocket(this.port, this.backLog);
} catch (IOException e) {
LOGGER.error("Could not listen on port " + this.port, e);
System.exit(-1);
}
while (!stopTheServer) {
socket = null;
try {
socket = serverSocket.accept();
handleNewConnectionRequest(socket);
} catch (IOException e) {
LOGGER.warn("Accept failed at: " + this.port, e);
e.printStackTrace();
}
}
}
protected void handleNewConnectionRequest(Socket socket) {
try {
executorService.submit(new T(socket));
} catch (IOException e) {
e.printStackTrace();
}
}
}
But in the handleNewConnectionRequest(...)
method, I can't create an instance of T as it is actually not a class. Also I can't use the method mentioned here as I want to pass the socket
instance so that the request handler can get OutputStream
and InputStream
on the socket
.
Can't I make a generic server like above and have different protocol handlers e.g
public class HttpRequestHandler extends RequestHandler {
...
}
public class FtpRequestHandler extends RequestHandler {
...
}
public class SmtpRequestHandler extends RequestHandler {
...
}
and then use them like below
Server<HttpRequestHandler> httpServer = new Server<HttpRequestHandler>();
Server<FtpRequestHandler> ftpServer = new Server<FtpRequestHandler >();
Server<SmtpRequestHandler> smtpServer = new Server<SmtpRequestHandler >();
You'll need an instance of the class. The generic type T isn't enough. So you'll do:
class Server <T extends RequestHandler> {
Class<T> clazz;
public Server(Class<T> clazz) {
this.clazz = clazz;
}
private T newRequest() {
return clazz.newInstance();
}
}
Maybe make different Server
subclasses befitting various handler types. One example:
public class HttpServer extends Server<HttpRequestHandler> {
protected HttpRequestHandler wrapSocket(Socket socket) {
return new HttpRequestHandler(socket);
}
}
And adapt Server like so:
public abstract class Server<T extends RequestHandler> {
protected abstract T wrapSocket(Socket socket);
protected void handleNewConnectionRequest(Socket socket) {
try {
executorService.submit(wrapSocket(socket));
} catch (IOException e) {
e.printStackTrace();
}
}
}
Just a thought...
You don't. It doesn't make sense. In this case I'd probably avoid generics. Plain old interface or abstract class does job. You can make abstract server with abstract factory method.
abstract class Server {
abstract protected RequestHandler newRequest(Socket socket);
... same as before
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With