13. Tomcat與其他HTTP服務器集成
13.1 Tomcat與HTTP服務器集成的原理
?<!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->
??? <Connector port="8080" maxHttpHeaderSize="8192"
?????????????? maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
?????????????? enableLookups="false" redirectPort="8443" acceptCount="100"
?????????????? connectionTimeout="20000" disableUploadTimeout="true" />
?
<!-- Define an AJP 1.3 Connector on port 8009 -->
??? <Connector port="8009"
?????????????? enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />
?
第一個連接監聽8080端口,負責建立HTTP連接,在通過瀏覽器訪問TOMCAT服務器的WEB應用時,使用的就是這個連接。
第二個連接器監聽8009端口,負責和其他的HTTP服務器建立連接,在把TOMCAT與其他HTTP服務器集成時,就需要用到這個連接器。
?
13.2 在Windows下Tomcat與Apache服務器集成
1.install apache http server
2.copy jk into <APACHE_HOME>/modules
?
3.create workers.properties and copy it into <APACHE_HOME>/conf
workers.tomcat_home=C:\jakarta-tomcat? #讓mod_jk模塊知道Tomcat
workers.java_home=C:\j2sdk1.4.2? #讓mod_jk模塊知道j2sdk
ps=\? #指定文件路徑分割符
worker.list=worker1
worker.worker1.port=8009? #工作端口,若沒占用則不用修改
worker.worker1.host=localhost? #Tomcat服務器的地址
worker.worker1.type=ajp13? #類型
worker.worker1.lbfactor=1? #負載平衡因數
?
4.modify <APACHE_HOME>/conf/httpd.conf
# Using mod_jk2.dll to redirect dynamic calls to Tomcat
LoadModule jk_module modules\mod_jk_2.0.46.dll
JkWorkersFile "conf\workers.properties"
JkLogFile "logs\mod_jk2.log"
JkLogLevel debug
JkMount /*.jsp worker1
JkMount /helloapp/* worker1
5.test
6.banlance
(1)copy jk into <APACHE_HOME>/lib
?
(2)create workers.properties in <APACHE_HOME>/conf
ps=\? #指定文件路徑分割符
worker.list=worker1,worker2,loadbalancer
worker.worker1.port=8009? #工作端口,若沒占用則不用修改
worker.worker1.host=localhost? #Tomcat服務器的地址
worker.worker1.type=ajp13? #類型
worker.worker1.lbfactor=100? #負載平衡因數
worker.worker2.port=8009? #工作端口,若沒占用則不用修改
worker.worker2.host=anotherhost? #Tomcat服務器的地址
worker.worker2.type=ajp13? #類型
worker.worker2.lbfactor=100? #負載平衡因數
worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=worker1, worker2
?
(3)modify <APACHE_HOME>/conf/httpd.conf
# Using mod_jk2.dll to redirect dynamic calls to Tomcat
LoadModule jk_module modules\mod_jk_2.0.46.dll
JkWorkersFile "conf\workers.properties"
JkLogFile "logs\mod_jk2.log"
JkLogLevel debug
JkMount /*.jsp loadbalancer
JkMount /helloapp/* loadbalancer
(4)keep worker's name the same as jvmRoute property of <Engine> element in server.xml
eg. <Engine name="Catalina" defaultHost="localhost" debug="0" jmvRoute="worker1">
(5)test
?
if both of tomcat servers are running in the same server, at least the port of one of tomact servers should be modified.
shut down HTTP connection of tomcat server, cancel HTTP connector in server.xml
?
13.3 Tomcat與IIS服務器集成
1.prepare
(1)JK isapi_redirect.dll add it into <CATALINA_HOME>/bin
(2)create workers.properties in <CATALINA_HOME>/conf
workers.tomcat_home=C:\jakarta-tomcat? #讓mod_jk模塊知道Tomcat
workers.java_home=C:\j2sdk1.4.2? #讓mod_jk模塊知道j2sdk
ps=\? #指定文件路徑分割符
worker.list=worker1
worker.worker1.port=8009? #工作端口,若沒占用則不用修改
worker.worker1.host=localhost? #Tomcat服務器的地址
worker.worker1.type=ajp13? #類型
worker.worker1.lbfactor=1? #負載平衡因數
?
(3)create uriworkermap.properties in <CATALINA_HOME>/conf
/index.jsp=worker1
/helloapp/*=worker1
2.edit register
equals configurate attribuates of JK
?
3.add 'jakarta' vitural directory in IIS for JK
choose 腳本和可執行程序
?
4.把JK插件作為ISAPI篩選器加入IIS
?
14. MVC
14.1 用RequestDispatcher 實現MVC
1. 定義用以表示數據的bean
2. 使用一個servlet處理請求
– servlet讀取請求參數,檢查數據的缺失或異常等。
3. 填充bean
– 該servlet調用業務邏輯(與具體應用相關的代碼)或數據訪問代碼得到最終的結果。得出的結果被放在第一步中定義的bean中。
4. 將bean存儲在請求、會話或servlet的上下文中
– 該servlet調用請求、會話或servlet上下文對象的setAttribute存儲表達請求結果的bean的引用。
5. 將請求轉發到JSP頁面
– 該servlet確定哪個JSP頁面適合于處理當前的情形,并使用RequestDispatcher的forward方法將控制轉移到那個頁面。
6. 從bean中提取數據
– JSP頁面使用jsp:useBean和與第4步匹配的位置訪問之前存儲的bean,然后使用jsp:getProperty輸出bean的屬性。
– JSP頁面并不創建或修改bean;它只是提取并顯示由servlet創建的數據。
?
RequestDispatcher dispatcher =
request.getRequestDispatcher(address);
dispatcher.forward(request, response);
?
14.2 jsp:useBean在MVC中的使用與在獨立JSP頁面中有什么不同
? JSP頁面不應該創建對象
– 應該由servlet,而非JSP頁面,創建所有的數據對象。因此,為了保證JSP頁面不會創建對象,我們應該使用<jsp:useBean ... type="package.Class" />而不是<jsp:useBean ... class="package.Class" />
? JSP頁面也不應該修改已有的對象
– 因此,我們應該只使用jsp:getProperty,不使用jsp:setProperty。
?
14.3 基于請求的數據共享
? Servlet
ValueObject value = new ValueObject(...);
request.setAttribute("key", value);
RequestDispatcher dispatcher =request.getRequestDispatcher("/WEB-INF/SomePage.jsp");
dispatcher.forward(request, response);
? JSP
<jsp:useBean id="key" type="somePackage.ValueObject" scope="request" />
<jsp:getProperty name="key" property="someProperty" />
?
14.4 基于會話的數據共享
? Servlet
ValueObject value = new ValueObject(...);
HttpSession session = request.getSession();
session.setAttribute("key", value);
RequestDispatcher dispatcher =request.getRequestDispatcher("/WEB-INF/SomePage.jsp");
dispatcher.forward(request, response);
? JSP
<jsp:useBean id="key" type="somePackage.ValueObject" scope="session" />
<jsp:getProperty name="key" property="someProperty" />
?
14.5 基于ServletContext的數據共享
? Servlet
synchronized(this) {
ValueObject value = new ValueObject(...);
getServletContext().setAttribute("key", value);
RequestDispatcher dispatcher =request.getRequestDispatcher("/WEB-INF/SomePage.jsp");
dispatcher.forward(request, response);
}
? JSP
<jsp:useBean id="key" type="somePackage.ValueObject" scope="application" />
<jsp:getProperty name="key" property="someProperty" />
?
15. Expression Language
15.1 啟用表達式語言
? 僅能夠用于支持JSP 2.0 (servlets 2.4) 的服務器中
?
15.2 訪問作用域變量
? ${varName}
– 表示在PageContext,HttpServletRequest,HttpSession,和ServletContext中,依照所列的順序進行查找,輸出這個屬性名所對應的對象。
– PageContext不適用于MVC。
? 等價的形式
– ${name}
– <%= pageContext.findAttribute("name") %>
– <jsp:useBean id="name" type="somePackage.SomeClass" scope="...">
<%= name %>
?
15.3 訪問bean的屬性
? ${varName.propertyName}
– 表示查找給定名稱的作用域變量,并輸出指定的bean屬性
? 等價的形式
– ${customer.firstName}
– <%@ page import="coreservlets.NameBean" %>
<%NameBean person =(NameBean)pageContext.findAttribute("customer");%>
<%= person.getFirstName() %>
?
15.4 訪問集合
? ${attributeName[entryName]}
? Works for
– Array. Equivalent to
? theArray[index]
– List. Equivalent to
? theList.get(index)
– Map. Equivalent to
? theMap.get(keyName)
? Equivalent forms (for HashMap)
– ${stateCapitals["maryland"]}
– ${stateCapitals.maryland}
– But the following is illegal since 2 is not a legal var name
? ${listVar.2}
?
15.5 引用隱式對象(預定義變量名)
? pageContext. The PageContext object.
– E.g. ${pageContext.session.id}
? param and paramValues. Request params.
– E.g. ${param.custID}
? header and headerValues. Request headers.
– E.g. ${header.Accept} or ${header["Accept"]}
– ${header["Accept-Encoding"]}
? cookie. Cookie object (not cookie value).
– E.g. ${cookie.userCookie.value} or ${cookie["userCookie"].value}
? initParam. Context initialization param.
? pageScope, requestScope, sessionScope, appliationScope.
– Instead of searching scopes.
? Problem
– Using implicit objects usually works poorly with MVC model