Servlet是一種服務器端的編程語言,是J2EE中比較關鍵的組成部分,Servlet技術的推出,擴展了Java語言在服務器端開發的功能,鞏固了Java語言在服務器端開發中的地位,而且現在使用非常廣泛的JSP技術也是基於Servlet的原理.
JSP+JavaBeans+Servlet成爲實現MVC模式的一種有效的選擇。
如果我們要實現一個對用戶的增刪改查,並且要求符合對擴展開發,對修改關閉的原則,該怎麼做呢?
首先,這是我們的類圖以及類與類之間調用的時序圖。
根據UML圖來實現代碼:
TestServlet類
package com.bjpowernode.servlet;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String requestURI = request.getRequestURI();
System.out.println("requestURI=" + requestURI);
String path = requestURI.substring(requestURI.indexOf("/",1),requestURI.indexOf("."));
System.out.println("path = " +path);
String username = request.getParameter("username");
Action action = null;
if("/servlet/delUser".equals(path)){
action = new DelUserAction();
}else if("/servlet/addUser".equals(path)){
action = new AddUserAction();
}else if("/servlet/modifyUser".equals(path)){
action = new ModifyAction();
}else if("/servlet/queryUser".equals(path)){
action = new QueryUserAction();
}else{
throw new RuntimeException("請求失敗");
}
String forward ="";
try {
forward= action.execute(request, response);
} catch (Exception e) {
e.printStackTrace();
}
request.getRequestDispatcher(forward).forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}
抽象接口Action
package com.bjpowernode.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Action {
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception;
}
添加類,這裏就只寫添加類了,其他類一樣
package com.bjpowernode.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class AddUserAction implements Action {
public String execute(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String username = request.getParameter("username");
//int age = Integer.parseInt(request.getParameter("username"));
//String sex = request.getParameter("sex");
//調用業務邏輯
UserManager userManager = new UserManager();
userManager.add(username);
return "/add_success.jsp";
}
}
Web.xml配置
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>com.bjpowernode.servlet.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<!--
<url-pattern>/servlet/TestServlet</url-pattern>
-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
這裏我們發現,在testAction類中,用到了大量的if和else,而當我們需要擴展一個上傳類的時候,就需要修改if/else,所以,這就不符合對擴展開發,對修改關閉原則,所以,我們需要把這部分提取出來,配置到配置文件裏,用反射進行配置。
我們需要先配置配置文件
<action-config>
<action path ="/servlet/delUser" type = "com.bjpowernode.servlet.DelUserAction">
<forward name = "success">del_success.jsp</forward>
<forward name = "error">del_error.jsp</forward>
</action>
<action path ="/servlet/addUser" type = "com.bjpowernode.servlet.AddUserAction">
<forward name = "success">add_success.jsp</forward>
<forward name = "error">add_error.jsp</forward>
</action>
<action path ="/servlet/modifyUser" type = "com.bjpowernode.servlet.ModifyAction">
<forward name = "success">modify_success.jsp</forward>
<forward name = "error">modify_error.jsp</forward>
</action>
<action path ="/servlet/queryUser" type = "com.bjpowernode.servlet.QueryUserAction">
<forward name = "success">query_success.jsp</forward>
<forward name = "error">query_error.jsp</forward>
</action>
</action-config>
需要獲取actionMapping對象
ActionMapping{
private String path;
private String type;
Map forwardMap;
}
forwardMap{
key = "success";
value ="/del_success.jsp"
key ="error"
value ="del_error.jsp";
}
Map map = new HashMap();
map.put("/servlet/delUser",actionMapping);
map.put("/servlet/addUser",actionMapping);
map.put("/servlet/modifyUser",actionMapping);
map.put("/servlet/queryUser",actionMapping);
// 如果是刪除ActionMapping存儲如下:
actionMapping{
path ="/servlet/delUser";
type ="com.bjpowernode.servlet.DelUserAction"
forwardMap{
key ="success",value ="/del_success.jsp"
key ="error",value"/del_error.jsp"
}
}
最後根據獲取的對象採用反射來動態實例化Action,達到我們的目的。
String path = "/servlet/delUser";
// 根據截取的URL請求,到Map中取得本次請求對應的Action
ActionMapping actionMapping =(ActionMapping)map.get(path);
//取得本次請求對應的Action類的完整路徑
String type = actionMapping.getType(); //com.bjpowernode.servlet.DelUserAction
// 採用反射動態實例化Action
Action action = (Action)class.forName(type).newInstance();
//動態待用Action中的execute方法
String forward = action.execute(request.response);
//根據路徑完成轉向
request.getRequestDispatcher(forward).forward(request, response);
這樣,我們基本就是實現了對擴展開發,對修改封閉的原則,但是,這僅僅是一個功能我們就需要做這麼多事情,寫這麼多代碼,對程序員來說這是一項不小的工作量,那麼我們有沒有其他的辦法讓我們的工作量小一點呢?