自從接觸java一來,經常在論壇上看到一些大牛談論框架雲雲,每每都覺得他們這些懂框架的都是真的大牛啊。羨慕嫉妒恨不能當飯吃,咱也跟隨巨人的步伐,開始研究框架之旅。struts是所有框架中最簡單、最經典的,從struts開始入手,算是一步捷徑。
本篇作為預備篇,先從緣起緣滅開始吧——MVC基本原理。
MVC框架3個部分間的功能協作過程,已經很清楚了,不過這裡可以再簡單提一下:
擇顯示這些數據的相應的視圖,並將視圖返回給用戶。
1、終端用戶發出一個請求,該請求到達Controller控制器。
2、控制器接受請求後,會檢查該請求,然後決定使用什麼業務邏輯來處理該請求,這時控制器會將該請求轉發給一個相應的業務邏輯去處理;
3、模型中包含處理該用戶請求的所有業務組件,並且也執行用戶所需要的全部數據存取,代表終端用戶查詢檢索出的任何數據都被打包返回給控制器。
4、控制器接受從模型返回的數據,並選
下面,先來采用一個不靈活的Servlet進行實現:
[java]
package com.xxjstgb.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 {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String requestURI = request.getRequestURI();
int start=requestURI.indexOf("/",1);
int end=requestURI.indexOf(".");
String path=requestURI.substring(start,end);
System.out.println("path=" + path);
String username = request.getParameter("username");
UserManager userManager = new UserManager();
String forward = "";
if ("/servlet/delUser".equals(path)) {
userManager.del(username);
forward = "/del_success.jsp";
}else if ("/servlet/addUser".equals(path)) {
userManager.add(username);
forward = "/add_success.jsp";
}else if ("/servlet/modifyUser".equals(path)) {
userManager.modify(username);
forward = "/modify_success.jsp";
}else if ("/servlet/queryUser".equals(path)) {
List userList = userManager.query(username);
request.setAttribute("userList", userList);
forward = "/query_success.jsp";
}else {
throw new RuntimeException("請求失敗");
}
request.getRequestDispatcher(forward).forward(request, response);
}
}
package com.xxjstgb.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 {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String requestURI = request.getRequestURI();
int start=requestURI.indexOf("/",1);
int end=requestURI.indexOf(".");
String path=requestURI.substring(start,end);
System.out.println("path=" + path);
String username = request.getParameter("username");
UserManager userManager = new UserManager();
String forward = "";
if ("/servlet/delUser".equals(path)) {
userManager.del(username);
forward = "/del_success.jsp";
}else if ("/servlet/addUser".equals(path)) {
userManager.add(username);
forward = "/add_success.jsp";
}else if ("/servlet/modifyUser".equals(path)) {
userManager.modify(username);
forward = "/modify_success.jsp";
}else if ("/servlet/queryUser".equals(path)) {
List userList = userManager.query(username);
request.setAttribute("userList", userList);
forward = "/query_success.jsp";
}else {
throw new RuntimeException("請求失敗");
}
request.getRequestDispatcher(forward).forward(request, response);
}
}
配置文件:
[html]
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>com.xxjstgb.servlet.testServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>com.xxjstgb.servlet.testServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
當用戶發出請求時(比如請求為:http://localhost:8080/struts_dispatchaction/servlet/delUser.do),根據用戶請求的具有一定特點的URL(該URL以/servlet/開頭或者是*.do結尾),訪問到相應的Servlet。
根據配置文件可知:這裡配置的是以".do"結尾的請求,都能夠訪問到TestServlet。該Servlet又截取了每個請求中特有的部分"/servlet/delUser",根據這個串兒,調用相應的業務邏輯,並作相應的轉向。
不過這種實現方式,大家一看便會覺得很不妥,這個Servlet的任務太重了。在這裡調用了模型層邏輯,同時也進行了所有的頁面轉向。另外,包含了大量的if…else語句,由於業務的不穩定性,這裡如果經常需要添加或者刪除else語句的話,這將是一個非常糟糕的設計。
下面改良設計,我們將控制器細化為前端控制器TestServlet和業務控制器Action。
前端控制器有兩個任務:1、根據一定規則,截取url;2、根據url分發到相應的Action。
業務控制器負責:1、接受表單數據;2、調用業務邏輯;3、返回轉向信息。
Action:
[java]
package com.xxjstgb.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.xxjstgb.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Action {
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception;
}
delUserActiion:
[java]
package com.xxjstgb.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DelUserAction implements Action {
public String execute(HttpServletRequest request,
HttpServletResponse response) throws Exception {
//接收表單參數
String username = request.getParameter("username");
//調用業務邏輯
UserManager userManager = new UserManager();
try {
userManager.del(username);
}catch(Exception e) {
return "del_error.jsp"; //轉向路徑可以通過配置文件讀取
}
//轉向信息
return "/del_success.jsp"; //轉向路徑可以通過配置文件讀取
}
}
package com.xxjstgb.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DelUserAction implements Action {
public String execute(HttpServletRequest request,
HttpServletResponse response) throws Exception {
//接收表單參數
String username = request.getParameter("username");
//調用業務邏輯
UserManager userManager = new UserManager();
try {
userManager.del(username);
}catch(Exception e) {
return "del_error.jsp"; //轉向路徑可以通過配置文件讀取
}
//轉向信息
return "/del_success.jsp"; //轉向路徑可以通過配置文件讀取
}
}
改良設計後的TestServlet:
[java]
package com.xxjstgb.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String requestURI=request.getRequestURI();
int start=requestURI.indexOf("/",1);
int end=requestURI.indexOf(".");
String path=requestURI.substring(start,end);
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 ModifyUserAction();
}else if ("/servlet/queryUser".equals(path)) {
action = new QueryUserAction();
}else {
throw new RuntimeException("請求失敗");
}
String forward = null;
try {
forward = action.execute(request, response);
} catch (Exception e) {
e.printStackTrace();
}
request.getRequestDispatcher(forward).forward(request, response);
}
}
package com.xxjstgb.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String requestURI=request.getRequestURI();
int start=requestURI.indexOf("/",1);
int end=requestURI.indexOf(".");
String path=requestURI.substring(start,end);
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 ModifyUserAction();
}else if ("/servlet/queryUser".equals(path)) {
action = new QueryUserAction();
}else {
throw new RuntimeException("請求失敗");
}
String forward = null;
try {
forward = action.execute(request, response);
} catch (Exception e) {
e.printStackTrace();
}
request.getRequestDispatcher(forward).forward(request, response);
}
}
在這個Servlet中,已經將模型層的調用、頁面轉向分離到Action中。在具體的Action中負責調用模型層邏輯以及負責頁面的轉向。這就是MVC基本框架的簡單實現。