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