Java+MyEclipse+Tomcat (二)配置Servlet及簡單實現表單提交

Eastmount發表於2015-05-07

        在Java EE應用程式設計中Servlet是基礎,JSP是建立在Servlet基礎之上的,其他Web框架如Struts、WebWork和Spring MVC都是基於Servlet的。本文主要講述MyEclipse和Tomcat配置Servlet的過程和簡單實現表單提交功能。
        希望對大家有所幫助,參考書籍《Java EE企業級應用開發例項教程》。
        Java+MyEclipse+Tomcat (一)配置過程及jsp網站開發入門

一. Servlet程式設計

        1.Web基礎知識
        在講述Servlet之前,先了解下Web基礎知識。Web(World Wide Web,全球資訊網)本質就是Internet所有文件的集合,Web文件主要型別有HTML網頁、CSS、JavaScript、各種動態網頁、圖片、聲音和視訊等。
        Web文件儲存在Web站點(Site)上,Web站點駐留在Web伺服器上。Web伺服器是一種軟體系統,提供Web文件的管理和請求服務,常見的Web伺服器軟體有Apache、IIS、WebLogic和Tomcat等。每個伺服器都有一個唯一的IP地址,Web伺服器對外都有一個服務埠,預設時80或8080埠。
        Web文件都有一個唯一的地址,通過URL格式來進行定位,其格式為:
        協議://IP地址:埠/站點名/目錄/檔名
        其中協議主要有HTTP、HTTPS和FTP。根據不同的協議,預設埠可以省略,HTTP/HTTPS為80埠,FTP為21埠。例:
        http://210.30.108.30:8080/test/admin/login.jsp
        Web伺服器接收到請求後,根據URL定位到相應文件,根據文件型別進行對應的處理,將文件通過網路傳送到客戶端,一般是瀏覽器,使用者即可檢視或下載請求的文件。Web通過請求/響應(Request/Response)模式進行工作,即由瀏覽器使用URL對Web文件進行請求,Web伺服器接收並處理請求,處理結束後將響應內容傳送到瀏覽器。
        Web請求方式主要包括GET、POST、PUT、DELETE和HEAD。其中GET請求直接返回請求的文件,同時傳遞引數在URL中;POST請求將傳遞到Web伺服器的資料儲存到資料流中,只有通過表單提交形式才能實現。如下:

Get請求:
http://localhost:8080/web01/main.do?id=1&password=123456
POST請求:
<form action = "add.do" method = "post">
        <input type="text" name="username">
        <input type="submit" value="提交">
</form>

        這些知識大家應該都非常熟悉了,我就不再介紹了,引出表單就開始敘述Servlet。

        2.什麼是Servlet
        在Sun公司制定Java EE規範初期,為實現動態Web而引入了Servlet,用於替代笨重的CGI(通用閘道器介面),實現了Java語言程式設計的動態Web技術,奠定了Java EE的基礎。後來為進一步簡化動態Web網頁的生成,並且在微軟公司推出了ASP(Active X服務系統頁面)技術的競爭下,Sun推出了JSP規範,進一步簡化了Web網頁的程式設計。但JSP在進行HTTP請求處理方面不如Servlet方便和規範,Servlet在當今的MVC模式Web開發中牢牢佔據一地。並且現在流行的Web框架基本基於Servlet技術,如Struts、WebWork和Spring MVC等。只有掌握了Servlet才能真正掌握Java Web程式設計的核心和精髓。
        那麼,究竟Servlet是什麼東東呢?
        Servlet是執行在Web容器的類,能處理Web客戶的HTTP請求,併產生HTTP響應。
        Servlet是Java EE規範定義的Web元件,執行在Web容器中。由Web容器負責管理Servlet的宣告週期,包括建立和銷燬Servlet物件。客戶不能直接建立Servlet物件和呼叫Servlet的方法,只能通過向Web伺服器發出HTTP請求,間接呼叫Servlet的方法。這是Servlet與普通Java類的重要區別。
        Sun在如下兩個包中提供了Servlet的全部介面和類:
              1.javax.servlet包含支援所有協議的通用Web元件介面和類
              2.javax.servlet.http包含支援HTTP協議的介面和類

        Servlet可以完成Web元件具有的所有功能,如下:
              1.接收HTTP請求
              2.取得請求資訊,包括請求頭和請求引數資料
              3.呼叫其他Java類方法完成具體的業務功能
              4.生成HTTP響應,包括HTML和非HTML響應
              5.實現到其他Web元件的跳轉,包括重定向和轉發

        編寫Servlet需要引入的兩個包和Java I/O包:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
        編寫接收HTTP請求並進行HTTP響應的Servlet要繼承javax.servlet.http.HttpServlet。Servlet類的定義如下:
        public class LoginAction extends HttpServlet {}
        每個Servlet一般都需要重寫doGet方法和doPost方法。當使用者使用GET方式請求Servlet時,Web容器呼叫doGet方法處理請求;當使用者使用POST方法請求Servlet時,Web容器嗲用doPost方法。

        Servlet是生命週期時序圖如上圖所示,包括載入類和例項化階段、初始化階段、處理請求階段和銷燬階段。

二. 配置Servlet

        Servlet作為Web元件可以處理HTTP請求/響應,因而對外要求一個唯一的URL地址。但由於Servlet是一個Java類檔案,不像JSP那樣直接存放在Web目錄下就能獲得URL請求訪問地址。Servlet必須在Web的配置檔案/WEB-INF/web.xml中進行配置和對映才能響應HTTP請求。
        1.Servlet宣告
        它的任務是通知Web容器Servlet的存在,宣告語法如下:

  <servlet>
  <servlet-name>HomePageAction</servlet-name>
  <servlet-class>servlet.HomePageAction</servlet-class>
  </servlet>

        其中<servlet-name>宣告Servlet的名字,一般與Servlet的類名相同即可,要求在一個web.xml檔案內名字唯一。<servlet-class>指定Servlet的全名,即包名.型別。Web容器會根據此定義載入類檔案到內容中,進而呼叫預設構造方法建立Servlet物件。
        Servlet初始引數如資料庫Driver、URL、賬號和密碼等資訊,在Servlet中可以讀取這些資訊,如下定義了一個初始引數,即資料庫的JDBC驅動。

  <servlet>
  <servlet-name>HomePageAction</servlet-name>
  <servlet-class>servlet.HomePageAction</servlet-class>
  <init-param>
	<param-name>driveName</param-name>
 	<param-value>sun.jdbc.odbc.JdbcOdbcDriver</param-value>
  </init-param>	
  </servlet>

        在Servlet中可以通過ServletConfig取得定義的初始化引數,取得以上定義的引數的程式碼如下:

private Connection cn=null;     //定義資料庫連線物件
private String driverName=null;  //資料庫驅動器
//取得Servlet定義的初始引數
driverName=config.getInitParameter("driverName");
//根據Servlet初始引數連線資料庫
Class.forName(driverName);
cn=DriverManager.getConnection("jdbc:odbc:cityoa");
        其中config是在Servlet中定義的ServletConfig型別的屬性變數,由init方法取得它的例項。可見連線不同資料庫,直接修改配置檔案即可,不需要程式碼的修改和重新編譯。

        2.Servlet對映
        任何Web文件在Internet上都要有一個URL地址才能被請求訪問,Servlet不能像JSP一樣直接放在Web的釋出目錄下,因此Servlet需要單獨對映URL地址。在WEB-INF/web.xml中進行Servlet的URL對映。

  <servlet-mapping>
  	<servlet-name>HomePageAction</servlet-name>
  	<url-pattern>/loginAction.do</url-pattern>
  </servlet-mapping>
        上面程式碼是絕對地址方式對映,只能對映到一個地址。其中Servlet-name名稱和Servlet宣告中要一致,URL的格式如下:/目錄/目錄/檔名.副檔名。而匹配目錄模式對映方式如下,可以請求多個URL。
  <servlet-mapping>
  	<servlet-name>MainAction</servlet-name>
  	<url-pattern>/main/*</url-pattern>
  </servlet-mapping>
        只要是以/main為開頭的任何URL都能請求此Servlet。如下:
            http://localhost:8080/web01/main/login.jsp
            http://localhost:8080/web01/main/info/add.do
        同樣能你還能使用匹配副檔名模式對映方式,也可以響應多地址的請求。

  <servlet-mapping>
  	<servlet-name>MainAction</servlet-name>
  	<url-pattern>*.action</url-pattern>
  </servlet-mapping>
        以上配置中副檔名為action的任何請求均能被Servlet響應。如:
            http://localhost:8080/web01/login.action
            http://localhost:8080/web01/main/info/add.action
        注意:你不能混合使用兩種匹配模式,否則會對映出錯,如/main/*.action這種是錯誤的混合模式。

三. 簡單實現表單提交功能

        建立Web Project專案,專案名稱為TestServlet。專案結構如下圖所示:


        在WebRoot資料夾下建立images資料夾,並新增圖片logo.jpg。新增inc資料夾,新建style.css檔案,程式碼如下:
.main {
	width: 1024px;
	text-align:left;
}
.font {
	font-family: "Trebuchet MS";
	font-size: 14px;
	font-weight: bold;
	color: #FFFFFF;
}
.div {
	margin: 0px;
	padding: 0px;
	width: 1014px;
}
.tdBgColor{
	background-color:#6b1101;
}
a{
	font-family: "Trebuchet MS";
	font-size: 14px;
	font-weight: bold;
	color: #FFFFFF;
	line-height:50px;
	text-decoration:none;

}
a.hover{
	font-family: "Trebuchet MS";
	font-size:14px;
	font-weight: bold;
	color:#0000FF;
	line-height:50px;
	text-decoration:underline;
	padding-bottom:1px;

}
a.visited{
	font-family: "Trebuchet MS";
	font-size:14px;
	font-weight: bold;
	color:#000066;
	line-height:50px;
	text-decoration:none;
}
a.active{
	font-family: "Trebuchet MS";
	font-size:14px;
	font-weight: bold;
	color:#0000FF;
	line-height:50px;
	text-decoration:none;
	padding-bottom:1px;
}
        然後修改index.jsp主頁,程式碼如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>火車票訂票系統</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>
	   <!-- 介面佈局 -->	
	   <div align="center">
	   <div class="style">
	   <table width="1024"  height="150" cellpadding="0" cellspacing="0" >
	   		<!-- 動態首頁訂票介面 同時獲取年月日和動態滾動訊息 -->
			<tr>
				<td colspan="2">
					<img src="./images/logo.jpg" alt="logo" width="1024" height="149">
				</td>
			</tr>		
			<tr>
				<td width="205"  bgcolor="#b7d7ec">
					<p align="center">
					<!-- 注意:方法today.getYear()已經過時,需要新增1900 -->
					<script language=JavaScript>
					today = new Date();
					function initArray(){
					this.length=initArray.arguments.length;
					for(var i=0;i<this.length;i++)
					this[i+1]=initArray.arguments[i];  }
					var d=new initArray(
					"星期日","星期一","星期二","星期三","星期四",	"星期五","星期六");
					document.write("<font color=##ff0000 style='font-size:12pt;font-family: 宋體'> ",
					today.getYear()+1900,"年",today.getMonth()+1,"月",today.getDate(),"日    ",d[today.getDay()+1],
								  "</font>" );
					</script> 
					</p>	
			    </td>	
				<td width="819" bgcolor="#b7d7ec">
					<marquee  direction="left" onmouseover=this.stop() onmouseout=this.start() scrollAmount=3 scrollDelay=100>
	             	<FONT style="FONT-SIZE: 18px"color=blue>歡迎使用火車票訂票系統管理系統 ,如有不足,敬請指導!</FONT>
	            	</marquee>
	            </td>
	        </tr>
	  </table>
	  </div>
	  
	  <table width="100%" height="75%" border="0" align="center">
		  <tr>
		    <td width="40%" height="20%"> </td>
		    <td width="20%" >	
          	<!-- 中間登入部分佈局 提交表單  配置web.xml -->
          	<form action="loginAction.do">
          	<table width="500" height="80%" border="2" bordercolor="#12A0F5"  bgcolor="#dfeaf1">
               <tr>
                 <td></td>
                 <td align="center"><br />系統管理員登入 <br/><br/>
       				使用者名稱:<input type="text" name="userid" size="19" maxlength="19" /><br/><br/>
       				密 碼:<input type="password" name="password" size="20" maxlength="19" /><br /><br />
                	<input type="submit" name="Submit" value="登入"/>    
                	<input type="reset" name="Submit" value="重置" /><br/>                           		
                </td>
                <td></td>
              </tr>
          </table>
          </form>
          </td>
		  <td width="40%"></td>
		  </tr>
		  <tr><td height="67" colspan="3">  
		 	<!-- 底部版權所有介面 -->
			<TABLE class=wrapper border=0 cellSpacing=0 cellPadding=0 width="100%" align=center>
			 <TBODY>
			  <TR>
			  	  <TD style="LINE-HEIGHT: 150%" align="center"> 
			      <HR style="WIDTH: 96%; HEIGHT: 4px; COLOR: #02457c">
			      <font size="2"> <SCRIPT language=javascript src=""></SCRIPT>
			      <!-- target=_blank開啟新的網頁 -->
			      <BR><A href="aboutme.jsp" target=_blank>關於我們</A> | <A href="wzsm.jsp">網站宣告</A>
			       <BR>版權所有&copy;2014-2015 北京理工大學 Eastmount <BR>京ICP備10009636號 </font>
			      </TD>
			  </TR>
			 </TBODY>
			</TABLE>
		  </td>
		 </tr>
		</table>
	  </div>
  </body>
</html>
        此時執行Web網站,點選Run As=》MyEclipse Server Application。如圖所示:


        此時,輸入使用者名稱和密碼登入效果如下圖所示:

        然後在src中新建資料夾Servlet,新建HomePageAction.java檔案,程式碼如下:
package servlet;

import java.io.IOException;
import java.sql.*; //匯入資料庫處理所有庫
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.JOptionPane;

//使用者登入處理Servlet 系統登入主頁處理表單
public class HomePageAction extends HttpServlet {
	
	private Connection cn=null;     //定義資料庫連線物件
	private String driverName=null; //資料庫驅動器
	private String url=null;        //資料庫地址URL
	
	//初始化方法,取得資料庫連線物件
	public void init(ServletConfig config) throws ServletException
	{
		super.init(config);
		driverName=config.getInitParameter("driverName");
		url=config.getInitParameter("url");
		
		try {
			Class.forName(driverName);
			cn=DriverManager.getConnection(url);
		} catch(Exception e) {
			System.out.println("取得資料庫連線錯誤:"+e.getMessage());
		}
	}
	
	//處理GET請求方法
	public void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException
	{
		//取得使用者登錄檔單提交的資料
		String userid=request.getParameter("userid");
		String password=request.getParameter("password");
		//判斷登入賬號為空,則自動跳轉到註冊頁面
		if(userid==null||userid.trim().length()==0) {
			response.sendRedirect("index.jsp");
			JOptionPane.showMessageDialog(null, "User name or password can't be empty!");
		}
		//判斷登入密碼為空
		if(password==null||password.trim().length()==0) {
			response.sendRedirect("index.jsp");
			JOptionPane.showMessageDialog(null, "User name or password can't be empty!");
		}
		//查詢資料庫和跳轉到登入主介面
		try {
			//查詢資料庫操作
			
			//跳轉到主介面
			response.sendRedirect("success.jsp");
		} catch(Exception e) {
			System.out.println("錯誤:"+e.getMessage());
			response.sendRedirect("index.jsp");
		}
	}
	
	//處理POST請求方法
	public void doPost(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException 
	{
		doGet(request,response);
	}
	
	//銷燬方法
	public void destroy() {
		super.destroy();
		try {
			cn.close();
		}catch(Exception e) {
			System.out.println("關閉資料庫錯誤:"+e.getMessage());
		}
	}		
}
        同時在WEB-INF資料夾web.xml檔案中配置Servlet,程式碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name></display-name>	
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <!-- 配置Servlet -->
  <servlet>
  <servlet-name>HomePageAction</servlet-name>
  <servlet-class>servlet.HomePageAction</servlet-class>
  <init-param>
	<param-name>driveName</param-name>
 	<param-value>sun.jdbc.odbc.Jdbc0dbcDriver</param-value>
  </init-param>
  <init-param>
 	<param-name>url</param-name>
 	<param-value>jdbc:odbc:cityoa</param-value>
  </init-param>	
  </servlet>
  <servlet-mapping>
  	<servlet-name>HomePageAction</servlet-name>
  	<url-pattern>/loginAction.do</url-pattern>
  </servlet-mapping>
    
</web-app>
        最後新建success.java檔案,跳轉後顯示的頁面。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>驗證成功介面</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
    	介面表單提交跳轉成功 <br>
    	<a href="index.jsp">返回</a>
  </body>
</html>
       顯示效果如下圖所示:


        此時Servlet配置成功,而且表單跳轉功能也實現了。你可能遇到如下錯誤:

        解決方案如下:

        最後希望文章對你有所幫助,下一篇文章準備講述JSP網站的一種經典網站模型和MyEclipse資料庫配置相關知識。如果文章有不足或錯誤的地方,還請海涵!
        (By:Eastmount 2015-5-7 清晨4點   http://blog.csdn.net/eastmount/
       

相關文章