I'm refactoring an existing (Ajax) Java Web application, which currently holds lots of its logic directly in the servlets. (The servlets even call each other, using a few nasty tricks ...)
The refactoring itself is painful, but pretty much straightforward (refactoring everything to use Dependency Injection now).
My problem is, that I really can't come up with the perfect naming scheme:
The refactored Servlets are now holding just a minimum amount of logic (just so much that they process the ServletRequest and ServletResponse, send an HTTP error code, etc.), then they call what I currently refer to as Processors (good/bad name?!?), which can be reused by several Servlets, Test classes, ... The processors perform the logic required for the action, similar to what a Session Bean would do if we were using EJBs.
I never thought, that "Session Bean" would be a good name anyway. And I'm also not very keen on defining a monolithic "Facade". I'm looking primarily for a better name than "Processor", or maybe some ideas how you structure your Servlet processing code.
Example
开发者_JAVA百科This is a simplified example (the real application uses GWT with Gilead, ... but that's not so important):
public class UserRegistrationServlet extends HttpServlet {
@Inject
UserRegistrationProcessor userRegistrationProcessor;
@Override
protected void doPost(final HttpServletRequest req,
final HttpServletResponse resp)
throws ServletException, IOException {
RegistrationRequest registrationRequest = parseRegistrationRequest(req);
RegistrationResult registrationResult =
userRegistrationProcessor.process(registrationRequest);
pw.print(toJson(registrationResult));
...
}
}
As the example suggests, I prefer to have specialized processors, which are responsible for one task only (or maybe a few very strongly related tasks) - opposed to a big class that handles lots of different actions.
Here is my example based on previous discussion:
public class UserRegistrationServlet extends HttpServlet {
@Inject
private UserRequestExtractor userRequestExtractor;
@Inject
private UserRegistrationService userRegistrationService;
@Override
protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
PrintWriter pw = response.getWriter();
pw.print(createResponse(userRequestExtractor.extract(request)));
}
protected String createResponse(User newUser) {
if (newUser == null) {
return "{'message' : 'the user parameters are not valid'}";
}
else {
UserRegistrationResult result = userRegistrationService.register(newUser);
switch (result) {
case SUCCESS:
return "{'message' : 'hurray'}";
case EMAIL_IN_USE:
return String.format("{'message' : 'the email address %s is already in use'}", newUser.email);
case USERNAME_IN_USE:
return String.format("{'message' : 'the user name %s is already in use'}", newUser.username);
default:
return "{'message' : 'an error occurred'}";
}
}
}
}
public class User {
private String username;
private String email;
public boolean isValid() {
return username != null && email != null;
}
}
/**
* Extractor which instantiates an object of type T from a request
*
* @param <T>
*/
public interface RequestExtractor<T> {
public T extract(HttpServletRequest request);
}
public class UserRequestExtractor implements RequestExtractor<User> {
public User extract(HttpServletRequest request) {
User user = new User();
user.username = request.getParameter("username");
user.email = request.getParameter("email");
// validation could also be a responsibility of the RequestExtractor
if (!user.isValid()) {
return null;
}
return user;
}
}
public interface UserRegistrationService {
public UserRegistrationResult register(User user);
}
// implementation of UserRegistrationService omitted
public enum UserRegistrationResult {
SUCCESS, EMAIL_IN_USE, USERNAME_IN_USE;
}
/**
* Unit test
*/
public class UserRegistrationServletTest {
@Test
public void test() {
UserRegistrationServlet cut = new UserRegistrationServlet();
User user = new User();
user.username = null;
user.email = "test@test.test";
String response = cut.createResponse(user);
Assert.assertEquals("{'message' : 'the user parameters are not valid'}", response);
}
}
Hope this helps.
Why not call them what they are: Servlet
s?
As in:
com.mycompany.app.admin.user.SaveServlet.java
com.mycompany.app.admin.user.ListServlet.java
精彩评论