在Struts中,擔(dān)任 MVC / Model 2 中Controller角色的是ActionServlet,所有的請(qǐng)求都必須先通過它,然而在Struts 1.1後,有關(guān)於請(qǐng)求的處理大部份已交由RequestProcessor,當(dāng)ActionServlet收到GET或POST的請(qǐng)求,其doGet() 或doPost()會(huì)呼叫process()方法來處理請(qǐng)求:
RequestUtils是個(gè)工具類,ActionServlet呼叫其selectApplication()方法,藉由 request.getServletPath()來取得請(qǐng)求路徑以選擇應(yīng)用程式模塊來處理請(qǐng)求,之後從ApplicationConfig物件取得 RequestProcessor物件,將使用者的請(qǐng)求委托它來進(jìn)行處理。
通常是將ActionServlet當(dāng)作黑盒子,您只要使用它,然而您也可以繼承ActionServlet來定義自己的控制器,但由於在Struts 1.1中大部份的請(qǐng)求已經(jīng)委托RequestProcessor來處理,繼承ActionServlet來定義自己的控制器請(qǐng)求處理意義已經(jīng)不大,通常的 目的是重新定義ActionServlet的init()方法,增加自己的初始化動(dòng)作:
預(yù)設(shè)的RequestProcessor物件是org.apache.struts.action.RequestProcessor,您可以藉由觀看 process()方法的原始碼來了解它作了哪些事情:
您可以繼承RequestProcessor,并改寫其中的processXXXXX()方法來自定義請(qǐng)求的處理方式,如果您要使用自己的 RequestProcessor,要在struts-config.xml中使用<controller>標(biāo)簽來定義,例如:
在Struts 1.1後,新增了<controller>標(biāo)簽,它可以用於指定ActionServlet的一些參數(shù),在Struts 1.1之前,這些參數(shù)是在<init-params>中加以指定,使用<controller>標(biāo)簽,應(yīng)用程式中不同的模組也可 以指定各自的參數(shù)給ActionServlet。
protected void process(HttpServletRequest request,
??????????????????????? HttpServletResponse response)
?????????????????? throws IOException, ServletException {
??? RequestUtils.selectApplication(request,
?????????????????????????????????? getServletContext());
??? getApplicationConfig(
???????? request).getProcessor().process(request, response);
}
???????????????????????? HttpServletResponse response)
?????????????????? throws IOException, ServletException {
??? RequestUtils.selectApplication(request,
?????????????????????????????????? getServletContext());
??? getApplicationConfig(
???????? request).getProcessor().process(request, response);
}
RequestUtils是個(gè)工具類,ActionServlet呼叫其selectApplication()方法,藉由 request.getServletPath()來取得請(qǐng)求路徑以選擇應(yīng)用程式模塊來處理請(qǐng)求,之後從ApplicationConfig物件取得 RequestProcessor物件,將使用者的請(qǐng)求委托它來進(jìn)行處理。
通常是將ActionServlet當(dāng)作黑盒子,您只要使用它,然而您也可以繼承ActionServlet來定義自己的控制器,但由於在Struts 1.1中大部份的請(qǐng)求已經(jīng)委托RequestProcessor來處理,繼承ActionServlet來定義自己的控制器請(qǐng)求處理意義已經(jīng)不大,通常的 目的是重新定義ActionServlet的init()方法,增加自己的初始化動(dòng)作:
public class CustomActionServlet extends ActionServlet {
??? public void init() throws ServletException {
??????? super.init();
??????? // 增加自己的初始化動(dòng)作
??????? ....
??? }
}
???? public void init() throws ServletException {
??????? super.init();
??????? // 增加自己的初始化動(dòng)作
??????? ....
??? }
}
預(yù)設(shè)的RequestProcessor物件是org.apache.struts.action.RequestProcessor,您可以藉由觀看 process()方法的原始碼來了解它作了哪些事情:
public void process(HttpServletRequest request,
???????????????????? HttpServletResponse response)
????????????????? throws IOException, ServletException {
??? // 處理 contentType 為 multipart/form-data 的 POST 請(qǐng)求
??? request = processMultipart(request);
??? // 取得 URI 路徑
??? String path = processPath(request, response);
??? if(path == null)
??????? return;
??? .....
??? // 確定客戶端的位置
??? // 是否要將一個(gè)Locale物件儲(chǔ)存在 session 中
??? // 配合 <controller> 的 locale 屬性使用
??? processLocale(request, response);
??? // 確定contentType,預(yù)設(shè)是 text/html
??? processContent(request, response);
??? // 判斷<controller>屬性nocache是否被確定
??? // 若是,在 response 中加入防止快取的header
??? processNoCache(request, response);
??? // 前置處理,預(yù)設(shè)返回 true
??? //子類可以重新定義它以決定要不要繼續(xù)處理
??? if(!processPreProcess(request, response)) {
??????? return;
??? }
??? // 從URI路徑確定ActionMapping
??? ActionMapping mapping =
?????????????????? processMapping(request, response, path);
??? if(mapping == null) {
??????? return;
??? }
??? ....
??? // 處理ActionForm
??? // 如果沒有就新增一個(gè),之後一直使用它
??? ActionForm form =
??????????? processActionForm(request, response, mapping);
???
??? // 將表單的欄位值填入ActionForm
??? processPopulate(request, response, form, mapping);
??? // 判斷是否執(zhí)行ActionForm的validate()方法
??? if(!processValidate(request, response, form, mapping)) {
??????? return;
??? }
??? // 判斷 標(biāo)簽的 forward 或 include 標(biāo)簽
// 是不是被設(shè)定,這兩個(gè)標(biāo)簽在設(shè)定一個(gè)路徑
// 其與 type 屬性是互斥的,當(dāng)設(shè)定其中一個(gè)屬性時(shí)
// 調(diào)用 RequestDispatcher 的 forward() 或 include()
// 其作用與設(shè)定ForwardAction或IncludeAction相同
// 直接繞送而不再使用Action物件進(jìn)行接下來的處理
??? if(!processForward(request, response, mapping)) {
??????? return;
??? }
??? if(processInclude(request, response, mapping)) {
??????? return;
??? }
??? // 處理Action,如果沒有就生成一個(gè),之後一直使用它
??? Action action =
??????????? processActionCreate(request, response, mapping);
??? if(action == null) {
??????? return;
??? }
??? // 呼叫Action的execute()或perform()方法
// 并返回ActionForward
??? ActionForward forward =
??????????????????? processActionPerform(request,
???????????????????????????????????????? response,
???????????????????????????????????????? action,
???????????????????????????????????????? for, mapping);
??? // 處理ActionForward
??? processActionForward(request, response, forward);
}
????????????????????? HttpServletResponse response)
????????????????? throws IOException, ServletException {
??? // 處理 contentType 為 multipart/form-data 的 POST 請(qǐng)求
??? request = processMultipart(request);
??? // 取得 URI 路徑
??? String path = processPath(request, response);
??? if(path == null)
??????? return;
??? .....
??? // 確定客戶端的位置
??? // 是否要將一個(gè)Locale物件儲(chǔ)存在 session 中
??? // 配合 <controller> 的 locale 屬性使用
??? processLocale(request, response);
??? // 確定contentType,預(yù)設(shè)是 text/html
??? processContent(request, response);
??? // 判斷<controller>屬性nocache是否被確定
??? // 若是,在 response 中加入防止快取的header
??? processNoCache(request, response);
??? // 前置處理,預(yù)設(shè)返回 true
??? //子類可以重新定義它以決定要不要繼續(xù)處理
??? if(!processPreProcess(request, response)) {
??????? return;
??? }
??? // 從URI路徑確定ActionMapping
??? ActionMapping mapping =
?????????????????? processMapping(request, response, path);
??? if(mapping == null) {
??????? return;
??? }
??? ....
??? // 處理ActionForm
??? // 如果沒有就新增一個(gè),之後一直使用它
??? ActionForm form =
??????????? processActionForm(request, response, mapping);
???
??? // 將表單的欄位值填入ActionForm
??? processPopulate(request, response, form, mapping);
??? // 判斷是否執(zhí)行ActionForm的validate()方法
??? if(!processValidate(request, response, form, mapping)) {
??????? return;
??? }
??? // 判斷 標(biāo)簽的 forward 或 include 標(biāo)簽
// 是不是被設(shè)定,這兩個(gè)標(biāo)簽在設(shè)定一個(gè)路徑
// 其與 type 屬性是互斥的,當(dāng)設(shè)定其中一個(gè)屬性時(shí)
// 調(diào)用 RequestDispatcher 的 forward() 或 include()
// 其作用與設(shè)定ForwardAction或IncludeAction相同
// 直接繞送而不再使用Action物件進(jìn)行接下來的處理
??? if(!processForward(request, response, mapping)) {
??????? return;
??? }
??? if(processInclude(request, response, mapping)) {
??????? return;
??? }
??? // 處理Action,如果沒有就生成一個(gè),之後一直使用它
??? Action action =
??????????? processActionCreate(request, response, mapping);
??? if(action == null) {
??????? return;
??? }
??? // 呼叫Action的execute()或perform()方法
// 并返回ActionForward
??? ActionForward forward =
??????????????????? processActionPerform(request,
???????????????????????????????????????? response,
???????????????????????????????????????? action,
???????????????????????????????????????? for, mapping);
??? // 處理ActionForward
??? processActionForward(request, response, forward);
}
您可以繼承RequestProcessor,并改寫其中的processXXXXX()方法來自定義請(qǐng)求的處理方式,如果您要使用自己的 RequestProcessor,要在struts-config.xml中使用<controller>標(biāo)簽來定義,例如:
- struts-config.xml
...
<controller
contentType="text/html;charset=Big5"
locale="true"
nocache="true"
processorClass="caterpillar.CustomRequestProcessor"/>
...
在Struts 1.1後,新增了<controller>標(biāo)簽,它可以用於指定ActionServlet的一些參數(shù),在Struts 1.1之前,這些參數(shù)是在<init-params>中加以指定,使用<controller>標(biāo)簽,應(yīng)用程式中不同的模組也可 以指定各自的參數(shù)給ActionServlet。