Tomcat中的servlet配置理解

        剛開始使用Servlet時,由於web.xml的url-pattern和html中form表單的action的訪問路徑配置不對,老是出現404頁面不存在的錯誤。根本緣由是對Tomcat處理Http請求的過程理解不深。html

        Tomcat處理Http請求過程:web

        假設來自客戶的請求爲:
        http://localhost:8080/TestTomcat/loginSucceed瀏覽器

        1) 請求被髮送到本機端口8080,被在那裏偵聽的Coyote HTTP/1.1 Connector得到
        2) Connector把該請求交給它所在的Service的Engine來處理,並等待來自Engine的迴應
        3) Engine得到請求localhost/TestTomcat/loginSucceed,匹配它所擁有的全部虛擬主機Host
        4) Engine匹配到名爲localhost的Host
        5) localhost Host得到請求/TestTomcat/loginSucceed,匹配它所擁有的全部Context
        6) Host匹配到路徑爲/TestTomcat的Context
        7) path="/TestTomcat"的Context得到請求/loginSucceed,在它的mapping table中尋找對應的servlet
        8) Context匹配到URL PATTERN爲/loginSucceed的servlet,對應於HelloServlet類
        9) 構造HttpServletRequest對象和HttpServletResponse對象,做爲參數調用HelloServlet的doGet或doPost方法
        10)Context把執行完了以後的HttpServletResponse對象返回給Host
        11)Host把HttpServletResponse對象返回給Engine
        12)Engine把HttpServletResponse對象返回給Connector
        13)Connector把HttpServletResponse對象返回給客戶browser服務器

    對以上過程不理解的能夠查看我轉載的博文:Tomcat工做原理詳解app

從以上過程能夠看出:一個完整的Http URL在Tomcat中被層層剝離,首先經過域名(上面的localhost)匹配虛擬主機,並將/TestTomcat/loginSucceed傳給對應主機;而後主機經過/TestTomcat匹配Context的path,將/loginSucceed傳給特定的Context(其實就是web應用,由於一臺主機上能夠同時運行多個web應用,即爲多個web應用提供服務器的功能);Context根據/loginSucceed來匹配Servlet,經過和url-pattern來匹配。因此咱們在web.xml中的url-pattern中不能帶項目名。而form表單中的action指向的URL是主機名後的部分,如上面的/TestTomcat/loginSucceed,因此此處必定要加上項目名(用來匹配哪一個Context,即web應用)webapp

 

    如下是相似實踐:jsp

    我建了個TestTomcat項目,建包com.heyujun.servlet,包下建類HelloServletui

HelloServlet類:url

注意:在類中的URL路徑配置有兩種方法:spa

一、response.sendRedirt("/TestTomcat/loginSucceed1.html");
//此處若是想讓瀏覽器訪問longinSucceed.html文件,必定要加上項目名,和.html;並且這會使瀏覽器顯示的URL改變

二、response.sendRedirt("loginSucceed1.html");若是不想帶上項目名,就直接寫HTML、JSP等文件的名字,必定不要加"/",不要寫成response.sendRedirt("/loginSucceed1.html");

猜想源碼是根據URL前是否有"/",若是有就將緊跟"/"的文件名做爲項目名。若是過寫成response.sendRedirt("/loginSucceed1.html");可能會把loginSucceed1.html做爲項目名,而機器上並不存在該項目,因此報404錯誤

public class HelloWorld extends HttpServlet {
	 
	  private String message;

	  public void init() throws ServletException
	  {
	      // 執行必需的初始化
	      message = "Hello World";
	  }

	  public void doGet(HttpServletRequest request,
	                    HttpServletResponse response)
	            throws ServletException, IOException
	  {
	      response.sendRedirt("/TestTomcat/loginSucceed1.html");
       // response.sendRedirt("loginSucceed1.html");
	  }
	  
	  public void destroy()
	  {
	      // 什麼也不作
	  }
	}

web.xml:

 <url-pattern>/loginSucceed</url-pattern>//注意此處必定不要再加上項目路徑即Context的path,並且前面必定要加"/",不然啓動失敗

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
    <welcome-file-list>
	<welcome-file>welcome.html</welcome-file>
	<welcome-file>welcome.htm</welcome-file>
	<welcome-file>welcome.jsp</welcome-file>
	</welcome-file-list>
  <servlet>  
     <!-- 類名 -->  
    <servlet-name>HelloServlet</servlet-name>  
    <!-- 所在的包 -->  
    <servlet-class>com.heyujun.servlet.HelloServlet</servlet-class>  
  </servlet>  
  <servlet-mapping>  
    <servlet-name>HelloServlet</servlet-name>  
    <!-- 訪問的網址 -->  
     <url-pattern>/loginSucceed</url-pattern>//注意此處必定不要再加上項目路徑即Context的path
    </servlet-mapping>  
</web-app>

welcome.html:

下面提交表單的action="/TestTomcat/loginSucceed",我以爲這裏的路徑配置也是和上面同樣有兩種方法,理由同HelloServlet類中所述

一、action="/TestTomcat/loginSucceed"

二、action="loginSucceed"  

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>login page</title>
</head>
<body>
	<form action="/TestTomcat/loginSucceed">
   //注意:此處必定要加上項目路徑即Context的path,用來找特定的webapp,後面的/loginSucceed纔是Servlet對應的url
   //而web.xml中的 url-pattern就是此處的/loginSucceed
  First name: <input type="text" name="fname"><br>
  Last name: <input type="text" name="lname"><br>
  <input type="submit" value="提交">
	</form>
</body>
</html>
相關文章
相關標籤/搜索