Abstract/decorate the Request
as well and get the Response
from it instead.
E.g. in your front controller servlet:
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
Request request = new RequestImpl(req, res);
Action action = ActionFactory.getAction(req); // Do whatever way you do to locate the `Action`.
Response = action.get(request);
// ...
}
wherein RequestImpl
look like this:
public class RequestImpl implements Request {
private HttpServletRequest request;
private HttpServletResponse response;
public RequestImpl(HttpServletRequest request, HttpServletResponse response) {
this.request = request;
this.response = response;
}
public Response newResponse(Status status) {
return new ResponseImpl(response, status);
// Add a boolean responseCreated to avoid creation of multiple responses? Illegal state!
}
public String getParameter(String name) { // Just another example of decorated method.
return request.getParameter(name);
}
// ...
}
and the ResponseImpl
look like this:
public class ResponseImpl implements Response {
private HttpServletResponse response;
public ResponseImpl(HttpServletResponse response, Status status) {
this.response = response;
this.response.setStatus(status.getCode());
}
public OutputStream getOutputStream() {
return response.getOutputStream();
}
// ...
}
which you finally use like this in your Action
:
public ActionImpl implements Action {
public Response get(Request request) {
Response response = request.newResponse(OK);
response.getOutputStream().write("body");
return response;
}
}
Alternatively, you can also create a Context
which takes both the HttpServletRequest
and HttpServletResponse
and pass that in instead of Request
. That's also less or more what the average MVC framework does. E.g.
protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
Context context = new ContextImpl(req, res);
Action action = ActionFactory.getAction(req); // Do whatever way you do to locate the `Action`.
action.execute(context);
context.render(); // Do here whatever you'd initially to do with the obtained Response.
}
with
public ActionImpl implements Action {
public void execute(Context context) {
context.getResponseOutputStream().write("body");
}
}
That said, instead of reinventing, I'd suggest to have a look to existing API's as well. Depending on what you'd like to do, JSF, JAX-RS or JAX-WS might be what you're actually after. Unless this is for pure hobby purposes ;)