熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

開源技術基礎:TOMCAT的用法

2013-11-23 20:06:49  來源: Java開源技術 

  謹以此文送給所有正在使用TOMCAT或者打算使用的人們向TOMCAT的所有開發人員致敬!

  小貓TOMCAT其實很可愛

  年底我換公司了同樣也換了WEBAPPTOMCAT出現在我的面前(以前使用weblogic)我有點茫然免費的東西真的能用的好麼?擔心ING……(其實是在火星呆太久)出門一打聽原來此貓出自名門-jakarta項目年度最具創新的java產品(Most Innovative Java Product)又有JAVA的老大SUN的力捧(官方推薦的servlet和jsp容器)以後就靠它吃飯了不說二話搞起來先

    安裝

  TOMCAT最新版本是()

  如果在WINDOWS下它可以自動找到你的JDK或者set JAVA_HOME=c:/jdk

  在LINUX下需要先解壓然後設置JAVA_HOME

  export JAVA_HOME=/usr/local/jdk

    RUN

  設置完畢後就可以運行tomcat服務器了進入tomcat的bin目錄WINDOWS下用startup啟動tomcatlinux下用startupsh相應的關閉tomcat的命令為shutdown和shutdownsh

  啟動服務後在浏覽器裡輸//localhost:/來測試一下

    目錄結構

  Bin存放啟動和關閉tomcat腳本

  Conf包含不同的配置文件serverxml(Tomcat的主要配置文件)

  Work存放jsp編譯後產生的class文件

  Webapp存放應用程序示例以後你要部署的應用程序也要放到此目錄

  Logs存放日志文件

  Comm/server/shared這三個文件夾下的LIB文件夾放jar文件

    配置serverxml文件

  沒有什麼好說的看TOMCAT的文檔比較有用這裡提供一些主要的東西吧

  

  元素名

  屬性

  解釋

  server

  port

  指定一個端口這個端口負責監聽關閉tomcat的請求

  shutdown

  指定向端口發送的命令字符串

  service

  name

  指定service的名字

  Connector(表示客戶端和service之間的連接)

  port

  指定服務器端要創建的端口號並在這個斷口監聽來自客戶端的請求

  minProcessors

  服務器啟動時創建的處理請求的線程數

  maxProcessors

  最大可以創建的處理請求的線程數

  enableLookups

  如果為true則可以通過調用requestgetRemoteHost()進行DNS查詢來得到遠程客戶端的實際主機名若為false則不進行DNS查詢而是返回其ip地址

  redirectPort

  指定服務器正在處理http請求時收到了一個SSL傳輸請求後重定向的端口號

  acceptCount

  指定當所有可以使用的處理請求的線程數都被使用時可以放到處理隊列中的請求數超過這個數的請求將不予處理

  connectionTimeout

  指定超時的時間數(以毫秒為單位)

  Engine(表示指定service中的請求處理機接收和處理來自Connector的請求)

  defaultHost

  指定缺省的處理請求的主機名它至少與其中的一個host元素的name屬性值是一樣的

  Context(表示一個web應用程序通常為WAR文件關於WAR的具體信息見servlet規范)

  docBase

  應用程序的路徑或者是WAR文件存放的路徑

  path

  表示此web應用程序的url的前綴這樣請求的//localhost:/path/****

  reloadable

  這個屬性非常重要如果為true則tomcat會自動檢測應用程序的/WEBINF/lib 和/WEBINF/classes目錄的變化自動裝載新的應用程序我們可以在不重起tomcat的情況下改變應用程序

  host(表示一個虛擬主機)

  name

  指定主機名

  appBase

  應用程序基本目錄即存放應用程序的目錄

  unpackWARs

  如果為true則tomcat會自動將WAR文件解壓否則不解壓直接從WAR文件中運行應用程序

  Logger(表示日志調試和錯誤信息)

  className

  指定logger使用的類名此類必須實現orgapachecatalinaLogger 接口

  prefix

  指定log文件的前綴

  suffix

  指定log文件的後綴

  timestamp

  如果為true則log文件名中要加入時間如下例:localhost_logtxt

  Realm(表示存放用戶名密碼及role的數據庫)

  className

  指定Realm使用的類名此類必須實現orgapachecatalinaRealm接口

  Valve(功能與Logger差不多其prefix和suffix屬性解釋和Logger 中的一樣)

  className

  指定Valve使用的類名如用orgapachecatalinavalvesAccessLogValve類可以記錄應用程序的訪問信息

  directory

  指定log文件存放的位置

  pattern

  有兩個值common方式記錄遠程主機名或ip地址用戶名日期第一行請求的字符串HTTP響應代碼發送的字節數combined方式比common方式記錄的值更多

    管理

  TOMCAT管理能力很強大進//localhost:/自己慢慢管吧實踐出真知我喜歡這樣搞

  ^_^一切盡在掌//localhost:/manager/html

  讓數據庫連接池轉起來

  作為一個JEE程序員大家手上可能會有現成的JDBC 數據庫連接池其實這沒有太大的必要因為象weblogic……企業級WEBAPP都有自己的連接池大家不要費力直接使用吧效率也很不錯再也不用羨慕NET的ADO了(以前作MS從來不擔心數據連接ADO確實用起來很爽)如果想實現一個 JDBC connection pool 的注意事項有

   有一個簡單的函數從連接池中得到一個 Connection

   close 函數必須將 connection 放回 數據庫連接池

   當數據庫連接池中沒有空閒的 connection 數據庫連接池必須能夠自動增加 connection 個數

   當數據庫連接池中的 connection 個數在某一個特別的時間變得很大但是以後很長時間只用其中一小部分應該可以自動將多余的 connection 關閉掉

   如果可能應該提供debug 信息報告沒有關閉的 new Connection

  網上有各種各樣的連接池代碼抄過來改改吧嘿嘿~

  這裡介紹如何配置TOMCAT的連接池以SQLSERVER為例

  步驟安裝SQLSERVER的JDBC驅動

  SQLSERVER的JDBC驅動其實就是三個JAR文件msbasejar/mssqlserverjar/msutiljar將這三個文件拷貝到你的/tomcat_home/common/lib目錄下去就可以了

  步驟修改serverxml文件

  具體代碼如下

  <Context path=test docBase=F:\yourroot debug= reloadable=true crossContext=true>

  <Logger className=orgapachecatalinaloggerFileLogger prefix=localhost_DBTest_log suffix=txt timestamp=true/>

  <Resource name=jdbc/SqlServerDB auth=Container type=javaxsqlDataSource/>

  <ResourceParams name=jdbc/SqlServerDB>

  <parameter>

  <name>factory</name>

  <value>monsdbcpBasicDataSourceFactory</value>

  </parameter>

  <! Maximum number of dB connections in pool Make sure you configure your mysqld max_connections large enough to handle all of your db connections Set to for no limit>

  <parameter>

  <name>maxActive</name>

  <value></value>

  </parameter>

  <! Maximum number of idle dB connections to retain in pool        Set to for no limit>

  <parameter>

  <name>maxIdle</name>

  <value></value>

  </parameter>

  <! Maximum time to wait for a dB connection to become available        in ms in this example seconds An Exception is thrown if    this timeout is exceeded Set to to wait indefinitely >

  <parameter>

  <name>maxWait</name>

  <value></value>

  </parameter>

  <! msSQL dB username and password for dB connections >

  <parameter>

  <name>username</name>

  <value>sa</value>

  </parameter>

  

  <parameter>

  <name>password</name>

  <value>sa</value>

  </parameter>

  <! Class name for SQLServer JDBC driver >

  <parameter>

  <name>driverClassName</name>

  <value>commicrosoftjdbcsqlserverSQLServerDriver</value>

  </parameter>

  <! The JDBC connection url for connecting to your MS SQL Server dBThe autoReconnect=true argument to the url makes sure that the mmSql Server JDBC Driver will automatically reconnect if mysqld closed the connection mysqld by default closes idle connections after hours>

  <parameter>

  <name>url</name>

  <value>jdbc:microsoft:sqlserver://:;databaseName=yourdb</value>

  <!must use &amp; not use  & >

  </parameter>

  </ResourceParams>

  </Context>

  步驟三程序調用

  package dbmanage;

  import javasqlCallableStatement;

  import javasqlConnection;

  import javasqlDate;

  import javasqlPreparedStatement;

  import javasqlResultSet;

  import javasqlSQLException;

  import javasqlStatement;

  import javautilEnumeration;

  import javautilHashtable;

  import javautilVector;

  import javaxnamingContext;

  import javaxnamingInitialContext;

  import javaxsqlDataSource;

  import utilsmartDateFormat;

  public class dbManager {

  /************************************

  * @param static private boolean VERBOSE ;

  * @param Statement theStatement;

  * @param PreparedStatement thePstmt;

  * @param Connection theConnection;

  ************************************/

  final static private boolean VERBOSE = true; //打印控制台控制

  //static Logger logger = LoggergetLogger(dbManagerclassgetName());

  private Context initCtx = null;

  private Context ctx = null;

  private DataSource ds = null;

  private long timeout = ;

  private Statement theStatement = null;

  private PreparedStatement thePstmt = null;

  /************************************

  * 初試化initCtx

  * 取得數據源對象

  ************************************/

  public

  dbManager() {

  try {

  initCtx = new InitialContext();

  //init contextread config webxml

  if (initCtx == null) {

  throw new Exception(Initial Failed!);

  }

  ctx = (Context) initCtxlookup(java:comp/env);

  //find jdbc/SqlServerDB object  this configruation in the SERVERXML of Tomcat

  if (ctx != null) {

  ds = (DataSource) ctxlookup(jdbc/SqlServerDB);

  }

  if (ds == null) {

  throw new Exception(Look up DataSource Failed!);

  }

  }

  catch (Exception e) {

  log(e Cant get the Context!);

  }

  }

  /************************************

  * get Connection

  * @return Connection

  ************************************/

  public synchronized

  Connection getConnection() {

  //get connection and set to delay time

  long startTime = new javautilDate()getTime();

  Connection con = null;

  while (con == null) {

  con = newConnection();

  if (con != null) {

  //log(Create New Connection!);

  break;

  }

  try {

  log(連接超時重新連接等待 + timeout + ms);

  wait(timeout);

  }

  catch (InterruptedException e) {

  log(e 連接超時!);

  }

  if ( (new javautilDate()getTime() startTime) >= timeout) {

  log(Connection timeout!);

  break;

  }

  }

  return con;

  }

  private

  Connection newConnection() {

  Connection con = null;

  try {

  con = dsgetConnection();

  if (con == null) {

  throw new Exception(Create Connection Failed!);

  }

  }

  catch (Exception e) {

  log(Create Connection Failed!);

  Systemoutprintln(egetMessage());

  }

  return con;

  }

  /************************************

  * release the connection

  * @param conn Connection

  * @param stmt Statement

  * @param pstmt PreparedStatement

  ************************************/

  public synchronized

  void freeConnection(Connection conn

  Statement stmt

  PreparedStatement pstmt) {

  try {

  //close Statement

  if (stmt != null) {

  stmtclose();

  stmt = null;

  //log(Close Statement);

  }

  //close  PreparedStatement

  if (pstmt != null) {

  pstmtclose();

  pstmt = null;

  //log(Close PreparedStatement);

  }

  }

  catch (Exception e) {

  Systemoutprintln(egetMessage());

  }

  try {

  //close Connection

  if (conn != null) {

  connclose();

  conn = null;

  //log(Close Connection);

  }

  }

  catch (SQLException e) {

  log(e 釋放資源出錯!);

  }

  }

  /************************************

  * write log file

  * @param s String

  ************************************/

  private

  void log(String s) {

  if (VERBOSE) {

  Systemoutprintln(new javautilDate() + : + s);

  //(new javautilDate()+s);

  }

  }

  /************************************

  * write log file

  * @param ex Object

  ************************************/

  private

  void logerr(Object ex) {

  if (VERBOSE) {

  //Systemoutprintln(new javautilDate()+:+s);

  //loggererror(ex);

  }

  }

  /************************************

  * write log file

  * @param e Throwable

  * @param msg String

  ************************************/

  private

  void log(Throwable e String msg) {

  Systemoutprintln(new javautilDate() + : + msg);

  //(new javautilDate() + : + msg e);

  }

  ……

  }

  OK你現在可以方便的使用連接池了想要一個得一個記得要釋放哦連接池的數量總是有限的

  中文問題照樣很簡單

  每個國家(或區域)都規定了計算機信息交換用的字符編碼集如美國的擴展 ASCII碼 中國的 GB日本的 JIS 等作為該國家/區域內信息處理的基礎有著統一編碼的重要作用字符編碼集按長度分為 SBCS(單字節字符集)DBCS(雙字節字符集)兩大類早期的軟件(尤其是操作系統)為了解決本地字符信息的計算機處理出現了各種本地化版本(LN)為了區分引進了 LANG Codepage 等概念但是由於各個本地字符集代碼范圍重疊相互間信息交換困難軟件各個本地化版本獨立維護成本較高因此有必要將本地化工作中的共性抽取出來作一致處理將特別的本地化處理內容降低到最少這也就是所謂的國際化(IN)各種語言信息被進一步規范為 Locale 信息處理的底層字符集變成了幾乎包含了所有字形的 Unicode

  現在大部分具有國際化特征的軟件核心字符處理都是以 Unicode 為基礎的在軟件運行時根據當時的 Locale/Lang/Codepage 設置確定相應的本地字符編碼設置並依此處理本地字符在處理過程中需要實現 Unicode 和本地字符集的相互轉換甚或以 Unicode 為中間的兩個不同本地字符集的相互轉換這種方式在網絡環境下被進一步延伸任何網絡兩端的字符信息也需要根據字符集的設置轉換成可接受的內容

  Java 語言內部是用 Unicode 表示字符的遵守 Unicode VJava 程序無論是從/往文件系統以字符流讀/寫文件還是往 URL 連接寫 HTML 信息或從 URL 連接讀取參數值都會有字符編碼的轉換這樣做雖然增加了編程的復雜度容易引起混淆但卻是符合國際化的思想的從理論上來說這些根據字符集設置而進行的字符轉換不應該產生太多問題而事實是由於應用程序的實際運行環境不同Unicode 和各個本地字符集的補充完善以及系統或應用程序實現的不規范轉碼時出現的問題時時困擾著程序員和用戶

  其實解決 JAVA 程序中的漢字編碼問題的方法往往很簡單但理解其背後的原因定位問題還需要了解現有的漢字編碼和編碼轉換相信這樣的東西大家都見過了

  new String(requestgetParameter(test)getBytes(iso)GBK)

  但這樣的代碼相信不是一個解決的辦法這樣會增加程序的復雜度寫數據庫提交表單URL中傳中文參數到處都是中文問題!作為一個連走路都要算計最短距離的懶人當然不願天天叨念著new String(requestgetParameter(test)getBytes(iso)GBK)然漢戰戰兢兢的處理各種字符轉換的問題我跋山涉水翻山越嶺終於找到了完美的解決方式在TOMCAT中只需要簡單的配置引入個文件就可以輕松搞定

  前提條件每個頁面使用

  <%@ page contentType=text/html; charset=GBK language=java import=javasql* errorPage= %>

  <meta httpequiv=ContentType content=text/html; charset=GBK>

  地球人都知道的東西

  步驟添加過濾器

  在TOMCAT中找到這個文件RequestDumperFilterjavaSetCharacterEncodingFilterjava他們位於D:\Tomcat\webapps\jspexamples\WEBINF\classes\filters加到你的工程文件裡去編譯他們

  步驟配置WEBXML

  在webxml裡加入這一段

  ……

  <filter>

  <filtername>Set Character Encoding</filtername>

  <filterclass>filtersSetCharacterEncodingFilter</filterclass>

  <initparam>

  <paramname>encoding</paramname>

  <paramvalue>GBK</paramvalue>

  </initparam>

  </filter>

  <filtermapping>

  <filtername>Set Character Encoding</filtername>

  <urlpattern>/*</urlpattern>

  </filtermapping>

  ……

  看到沒有?這樣你就不用寫那些麻煩的轉換代碼了當然這樣還不足以解決問題

  步驟修改serverxml

  在serverxml修改個地方

  <Connector port=

  maxThreads= minSpareThreads= maxSpareThreads=

  enableLookups=false redirectPort= acceptCount=

  debug= connectionTimeout=

  disableUploadTimeout=true URIEncoding=GBK/>

  <Connector className=yotetomcatCoyoteConnector

  port= minProcessors= maxProcessors=

  enableLookups=true redirectPort=

  acceptCount= debug= connectionTimeout=

  useURIValidationHack=false protocol=AJP/

  protocolHandlerClassName=orgapachejkserverJkCoyoteHandler

  URIEncoding=GBK/>

  OK搞定!

  APACHE和TOMCAT他們倆關系非同一般

  Apache和tomcat都是很優秀的軟件更可貴的是它們是免費的其實他們個都是jakarta項目的重要組成部分按輩分來講TOMCAT是APACHE的兒子APACHE的專長是解析靜態文件CGIPHP……圖片……兒子當然不能搶了老爹的飯碗所以TOMCAT只有在JEE這個上面發憤圖強其實TOMCAT並非不能干他老爹的活只是穩定性差點而已(偶沒有明顯的感覺可能是商業炒作吧)現在大家明白為什麼把他們個扯一起了吧上陣還靠父子兵呢~

  把個家伙整一起有大致有種方法一種是利用mod_jkso一種是利用mod_jk__dll個東東叫聯接器(TOMCAT就是通過這家伙與apache勾搭上的)

    利用mod_jk__dll在WINDOWS下整合

  步驟准備材料

  apache

  _winxno_sslmsi

  tomcat

  /v/bin/jakartatomcatexe

  JDK(這個不用說了吧^_^)

  mod_jk__dll(關鍵是這個東東啊找了我N久)據說在下面連接可以下到最後在我同事那找到的

  connectors/jk/binaries/win/mod_jk__dll

  安裝apache\ tomcat\JDK

  步驟安裝後設置環境變量

  設置我的電腦\屬性\高級\環境變量\新建系統變量 變量名JAVA_HOME 變量值C:\JBuilderX\jdk (指向JDK的實際安裝路徑)TOMCAT_HMOM 變量值Tomcatlasspath 編輯變量值中加上 ……;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%TOMCAT_HOME%\bin;;

  測試一下訪////localhost:默認安裝是不會有什麼錯誤的^_^

  把連接器mod_jk__dll COPY到D:\Apache\modules\下

  步驟apache配置

  在d:\Apache\conf下找到後添加indexjsp查找listen用於本機測試時Listen :我的是這樣設置的Listen *:

  查找AddDefaultCharset設置為AddDefaultCharset off這樣APACHE將以你頁面定義的字符集解析頁面

  在最後添加如下代碼

  <VirtualHost *:> #localhost為本機你可用本機ip

  ServerAdmin #你的mail地址

  DocumentRoot F:/uutang/uutang #你的項目組根目錄

  ServerName dark #你的服務名若你的機器有域名設為域名

  ErrorLog logs/ErrorLogtxt #錯誤日志

  CustomLog logs/CustomLogtxt common #訪問日志

  JkMount /servlet/* ajp #讓Apache支持對servlet傳送用以Tomcat解析

  JkMount /*jsp ajp #讓Apache支持對jsp傳送用以Tomcat解析

  JkMount /*do ajp #讓Apache支持對struts的action傳送用以Tomcat解析

  </VirtualHost>

  LoadModule jk_module modules/mod_jk__dll

  JkWorkersFile D:/Tomcat/conf/workersproperties

  JkLogFile D:/Tomcat/logs/mod_jklog

  JkLogLevel info

   

  步驟tomcat配置

  在d:\Tomcat\conf下新建一個workersproperties文件 內容如下: 

  workerstomcat_home=d:\Tomcat #讓mod_jk模塊知道Tomcat

  workersjava_home=d:\jdk  #讓mod_jk模塊知道jsdk

  ps=\

  workerlist=ajp #模塊版本現有ajp不要修改

  workerajpport= #工作端口若沒占用則不用修改

  workerajphost=localhost #主機若上面的Apache主機不為localhost作相應修改

  workerajptype=ajp #類型

  workerajplbfactor= #代理數不用修改

  修改TOMCAT的serverxml文件

  <! Define a Coyote/JK AJP Connector on port >

  <Connector className=yotetomcatCoyoteConnector

  port= minProcessors= maxProcessors=

  enableLookups=true redirectPort=

  acceptCount= debug= connectionTimeout=

  useURIValidationHack=false protocol=AJP/

  protocolHandlerClassName=orgapachejkserverJkCoyoteHandler

  URIEncoding=GBK/>

  讓TOMCAT知道ajp協議apache和tomcat倆父子間靠這個協議溝通

  測試一下訪////localhost:看到相同的頁面沒有?細心點其實很簡單看看E文的幫助搞定不成問題

    利用mod_jkso(也叫JK)整合

  jk是一個jakartatomcatconnectorsjkwinapachezip文件主要用的是其中的mod_jkso其實利用mod_jkso整合和利用mod_jk__dll整合大同小異只是換了個聯接器而已現在一步一步整起來~

  步驟沒有多說的安裝好TOMCAT和APACHE

  下載jakartatomcatconnectorsjkwinapachezip解壓將mod_jk放到apache的安裝文件夾下的modules文件夾中

  步驟apache配置

  在/conf中加入一個workproperties文件其內容如下

  <!這個文件的作用不是很清楚總之路徑設置正確就行了我的apache裝在D:/Apache根據情況自己修改>

  [shm]

  file=D:/ /Apache/logs/shmfile

  size=

  <!這個socket channel是必須的port和host對應於tomcat端的設置>

  #The socket channel

  [channelsocket:localhost:]

  port=

  host=localhost

  <!worker必須的>

  #define the worker

  [ajp:localhost:]

  channel=channelsocket:localhost:

  <!url mapping我的主要是jsp和struts的doservlet的話設置成[uri:/xxx/*]之類的>

  #uri mapping

  [uri:/*] #和第一種方式一樣吧^_^

  [uri:/*jsp]

  [uri:/*do]

  worker=ajp:localhost:

  在中在LoadModule那裡加入這句

  LoadModule jk_module modules/mod_jkso

  在最後加入這句

  JkSet configfile conf/workproperties

  這是告訴apache去哪裡找jk的配置的根據具體情況修改

  還要修改一下DirectoryIndexDirectoryIndex l lvar indexjsp查找listen用於本機測試時Listen :我的是這樣設置的Listen *:

  當然還有我們的虛擬目錄

  <VirtualHost *:>

  ServerAdmin

  DocumentRoot F:/uutang/uutang

  ServerName dark

  ErrorLog logs/ErrorLogtxt

  CustomLog logs/CustomLogtxt common

  #JkMount /servlet/* ajp

  #JkMount /*jsp ajp

  #JkMount /*do ajp

  </VirtualHost>

  步驟tomcat配置

  Tomcat的端口設置為

  在/conf文件夾加入jkproperties文件其內容如下

  # Set the desired handler list

  handlerlist=aprrequestchannelSocket

  #

  # Override the default port for the socketChannel

  channelSocketport=

  TOMCAT自己已經生成了這個文件找到相關的地方把注視去掉改一下就成

  注意用這種方式整合最好是自己編譯mod_jkso文件特別是在unix/linux下我沒有環境制作mod_webappso沒有自己作過具體方法自己去找吧


From:http://tw.wingwit.com/Article/program/Java/ky/201311/27947.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.