Servlet的配置


 

配置Servlet映射

 <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>servlet.TestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/TestServlet</url-pattern>
    </servlet-mapping>

只能使用/TestServlet來訪問,使用其他的比如/TestServlet/xxx是訪問不了的。

url-pattern必須以/開始,引用時引用url-pattern中/后面的部分。比如<url-pattern>/handlerServlet</url-pattern>,表單action="handlerServlet";比如<url-pattern>/servlet/handlerServlet</url-pattern>,表單action="servlet/handlerServlet"。

引用的是url-pattern,不是servlet-name。

 

 

可以使用. 

<url-pattern>/servlet.TestServlet</url-pattern> 

訪問時以 /servlet.TestServlet 來訪問。注意不是通過/servlet/TestServlet來訪問。

 

 

可以使用/

<url-pattern>/servlet/TestServlet</url-pattern>

訪問時以 /servlet/TestServlet 來訪問

 

 

可以使用通配符*

<url-pattern>/*</url-pattern>

匹配所有請求。

  

 

多重映射:一個Servlet配置多個<url-pattern>,可通過多個路徑來訪問。

<servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/TestServlet1</url-pattern>
        <url-pattern>/TestServlet2</url-pattern>
    </servlet-mapping>

既可通過/TestServlet1來訪問,又可通過/TestServlet2來訪問。

 

 

配置 load-on-startup

<servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>servlet.TestServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

配置了<load-on-startup></load-on-startup>的Servlet會在Servlet容器(比如Tomcat)啟動時就創建此Servlet的實例。

參數是一個整數,值越小的越先創建(初始化)。

 

 

 

 

 

默認Servlet

 <url-pattern>/</url-pattern>

只有一個/,當找不到匹配的Servlet時,就執行這個默認的Servlet(用默認的Servlet來響應)。

注意默認Servlet是/,不是/*。

默認Servlet與Tomcat處理靜態資源有很大聯系。

 

 

 

Tomcat處理請求的流程

瀏覽器要訪問某個web資源(頁面),Tomcat是如何處理這個請求的呢?

(1)Tomcat先在此WebApp的web.xml中根據<url-pattern>找有沒有匹配的Servlet,有就調用來處理這個請求

 

(2)如果沒有,就查找此WebApp的web.xml中有沒有配置默認Servlet,有就調用默認的Servlet來處理這個請求。

這個就很有意思了,比如瀏覽器請求的是xxx.html,此WebApp下也有這個xxx.html,但你配置了一個默認的Servlet,那Tomcat會調用默認的Servlet來響應,而不是調用xxx.html來響應!

 

(3)如果此WebApp沒有配置默認的Servlet,那就到Tomcat -> conf -> web.xml 中查找,這個web.xml是Tomcat的全局配置,對所有WebApp均有效。

先根據<url-pattern>找有沒有匹配的Servlet,全局的web.xml中自然是找不到匹配的Servlet的;

然后找有沒有默認的Servlet,全局的web.xml中配置了一個默認的Servlet,此Servlet的處理方式是:在當前WebApp的資源找有沒有請求的這個資源|文件,有就用這個資源|文件來響應,比如請求的是xxx.html,就在當前這個WebApp的資源中找有沒有xxx.html這個資源|文件,有就用它來響應。如果當前WebApp中沒有這個資源|文件,就報404錯誤。

 

如果瀏覽器請求的是靜態資源,比如xxx.html,這要走完整個流程。

人家請求的是靜態資源,你遍歷2個web.xml,在一堆Servlet配置中找!簡直傻X。

所以說Tomcat處理靜態資源不給力。處理靜態資源一般用Nginx,不用Tomcat。

 

 

 

 

配置某個Servlet的初始化參數

<servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>servlet.TestServlet</servlet-class>
        <init-param>
            <param-name>name</param-name>
            <param-value>張三</param-value>
        </init-param>
        <init-param>
            <param-name>age</param-name>
            <param-value>18</param-value>
        </init-param>
    </servlet>

一個<init-param>設置一個參數。可以設置多個。

 

 

在Servlet中使用ServletConfig獲取當前Servlet的初始化參數

 1 public class TestServlet extends HttpServlet {
 2     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 3         doGet(request, response);
 4     }
 5 
 6     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 7         response.setContentType("text/html;charset=utf-8");  // //設置響應輸出流的編碼格式。若不設置,中文會亂碼。
 8         PrintWriter writer = response.getWriter();  //獲取響應輸出流
 9         ServletConfig servletConfig=this.getServletConfig();  //this表示當前Servlet。可缺省this,直接調用getServletContext()
10 
11         //獲取單個參數值
12         String name = servletConfig.getInitParameter("name"); //返回值是String
13         String age = servletConfig.getInitParameter("age");
14         writer.write("name:"+name+"<br />");   //輸出會以html的形式顯示,所以可以使用html標簽。
15         writer.write("age:"+age);
16 
17         writer.write("<hr />");
18 
19         //遍歷
20         Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();  //里面的元素是參數名
21         while (initParameterNames.hasMoreElements()){
22             String paramName=initParameterNames.nextElement();  //參數名
23             String paramValue=servletConfig.getInitParameter(paramName);  //參數值
24             writer.write(paramName+":"+paramValue+"<br />");
25         }
26 
27 
28     }
29 }

 

 

說明

  • 如果響應中包含中文,需要設置設置響應的編碼字符集。有2種設置方式

    response.setContentType("text/html;charset=utf-8");  
    response.setCharacterEncoding("utf-8");

這兩種方式都可以解決響應中文亂碼的問題(准確來說不是亂碼,是顯示為?識別不了)。區別是:第一種設置了輸出文檔是html,所以可以輸出html文檔中的內容,比如:

    PrintWriter writer = response.getWriter();  
        writer.write("<h2>hello</h2>");   
        writer.write("<script>alert('hello')</script>");

這些html標簽都會被解析,js腳本是有效的。

第二種只設置了響應字符集為utf-8,並沒有設置響應是html文檔,解析不了響應中的html標簽。

 

 

  • 設置響應字符集的這句代碼必須放在獲取響應輸出流的代碼之前。

    response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();

如果放在了獲取響應輸出流的代碼之后,則設置的字符集無效。

 

 

  • 解決請求參數中的中文亂碼

request.setCharacterEncoding("utf-8");

習慣上把設置request、response字符集的這兩句代碼放在doGet() | doPost() 里的最前面。

 

 

  • 如果我們想在響應輸出流中輸出換行,使用<br />,而非\n。

     response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.write("hello<br />");

設置響應輸出流是html文檔,換行自然要用<br />,\n在html中換不了行。

 

 

 

 

 

配置整個web應用的初始化參數,所有Servlet共享

既然是所有servlet公有的,那就應該直接放在<web-app>下。

<context-param>
        <param-name>name</param-name>
        <param-value>chy</param-value>
    </context-param>

    <context-param>
        <param-name>age</param-name>
        <param-value>20</param-value>
    </context-param>

一個<context-param>配置一個參數,可配置多個參數。

 

 

在servlet中獲取參數值

 1 response.setContentType("text/html;charset=utf-8");
 2         PrintWriter writer = response.getWriter();
 3         ServletContext context=this.getServletContext();  //可缺省this,直接調用getServletContext()
 4 
 5         //獲取單個參數值
 6         String name = context.getInitParameter("name");
 7         String age = context.getInitParameter("age");
 8         writer.write("name:"+name+"<br />");
 9         writer.write("age:"+age);
10 
11         writer.write("<hr />");
12 
13         //遍歷
14         Enumeration<String> initParameterNames =context.getInitParameterNames();  //里面的元素是參數名
15         while (initParameterNames.hasMoreElements()){
16             String paramName=initParameterNames.nextElement();  //參數名
17             String paramValue=context.getInitParameter(paramName);  //參數值
18             writer.write(paramName+":"+paramValue+"<br />");
19         }

 

我們注意到通過ServletContext對象獲取東西參數名、參數值、Enumeration對象的三個方法都是getInitParameterXxx()。為什么是init?

 

ServletConfig表示當前Servlet的初始化配置。

 

ServletContext表示整個Web應用中所有Servlet的共享數據。共享數據有2個部分:

  • 在xml中通過<context-param>配置的初始化參數,這部分數據要通過ServletContext實例的getInitParameterXxx()來獲取
  • 另一部分共享數據是在web應用運行中通過setAttribute()添加|設置的,需要使用getAttribute()來獲取。

這2部分數據是分開的、獨立的,操作數據的方法也是獨立的一套。

 

 

 

 

整個Web應用的共享數據

在一個Servlet中:

    ServletContext context=getServletContext();  //可缺省this
        context.setAttribute("name","chy");
        context.setAttribute("age",20);  

設置的數據是所有Servlet共享的,在其他Servlet中可以修改、獲取這些數據。

 

在另一個Servlet中使用:

 //獲取單個屬性值
        String name= (String) servletContext.getAttribute("name");  //獲取的是屬性值都是Object,需要強轉
        int age= (int) servletContext.getAttribute("age");
        
        //遍歷
        Enumeration<String> attributeNames = servletContext.getAttributeNames();
        while (attributeNames.hasMoreElements()){
            String attributeName=attributeNames.nextElement();  //屬性名是String
            Object attributeValue = servletContext.getAttribute(attributeName);  //屬性值是Object,需要強轉
            //...
        }

 

需要先訪問前一個Servlet。先設置了數據,才取得出來。

如果要移除某個共享數據,可以使用 removeAttribute(String name) 。

 

獲取ServletConfig對象、ServletContext對象,可以使用this,也可以缺省this,直接寫getServletConfig|Context()。

因為getServletConfig()獲取的只能是當前Servlet的初始化配置,是唯一的;

getServletContext()獲取的只能是當前WebApp中的共享數據,也是唯一的;

不需要this。

 

獲取當前Servlet的初始化參數時,可以不要ServletConfig對象,直接寫 getInitParameter()、getInitParameterNames()。

因為當前的Servlet是唯一的、確定的。

 

 

 

 使用ServletContext讀取資源文件

1 ServletContext servletContext = getServletContext();
2         InputStream is = servletContext.getResourceAsStream("/test.properties"); 
3         Properties properties = new Properties();
4         properties.load(is);

 

 

 

 

配置Tomcat數據源

1、在tomcat->conf->context.xml中配置數據源

<Context>

    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

 <Resource name="jdbc/mysql"
        type="javax.sql.DataSource"
        driverClassName="com.mysql.cj.jdbc.Driver"
        url="jdbc:mysql://localhost:3306/my_db?serverTimezone=GMT"
        username="chy"
        password="abcd"  />

</Context>

<WatchedResource>是自帶的,不用管。

一個<Resource>配置一個資源,可同時配置多個資源。<Resource>的name屬性唯一標識此資源,數據源的name常用jdbc/xxx來命名。Tomcat中配置的資源是全局的,所有webapp都可以通過name引用。

type指定資源類型是數據源。Tomcat的內置數據源是DBCP,所以參數要是DBCP的參數,可在<Resource>中配置DBCP中可配置的所有參數。

 

需要把數據庫驅動添加到tomat的lib中。

說明:tomcat自帶java web常用的jar包。使用tomcat運行webapp時,默認會自動使用tomcat\lib下的servlet-api.jar、jsp-api.jar這2個包,所以我們不必手動添加這2個包的依賴。當然把java ee的jar包添加進來也行。

 

 

 

 

2、在WebApp的web.xml中引用Tomcat數據源

<resource-ref>
        <res-ref-name>jdbc/mysql</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
    </resource-ref>

配置在<web-app>中,一個<resource-ref>配置一個資源引用,<res-ref-name>指定要引用的資源的name(對應tomcat中資源的name),res-type指定所引用資源的類型。

這2個子元素的位置可以互換,但在某些版本的IDEA中,如果type寫在前,name寫在后,type會報紅,這是IDEA本身的問題,代碼沒有錯。

 

 

3、在Servlet中使用數據源

   InitialContext initialContext = new InitialContext();
            Context context = (Context) initialContext.lookup("java:comp/env");  //返回值是Object,需要強轉。參數是固定的。
            DataSource dataSource = (DataSource)context.lookup("jdbc/mysql");  //獲取數據源,參數是資源的name。返回值是Object,需要強轉
            Connection connection = dataSource.getConnection();
            

 

 

 

 

 

使用注解配置Servlet

使用注解配置Servlet最常用,也最方便。

@WebServlet(
  name = "testServlet",
  urlPatterns = { "/servlet/testServlet" },
  loadOnStartup = 1,
  initParams = {@WebInitParam(name = "name", value = "張三"),@WebInitParam(name="age",value="12")}
)
public class TestServlet extends HttpServlet {
  //......
}

name指定此Servlet的name,缺省時默認為此Servlet的全限定類名。

urlPatterns、value指定映射,二者完全等價。多重映射寫成字符串數組的形式,如果只有一個映射關系,可以直接寫成字符串。

loadOnStartup,即<load-on-startup>。

initParams指定此Servlet的初始化參數,數組形式。一個@WebInitParam配置一個初始化參數,name、value均為String。

 

以上參數均可缺省,但一般都要配置value | urlPatterns。

參數只有value | urlPatterns時可以缺省value | urlPatterns,直接寫參數值。

@WebServlet("/servlet/testServlet")

 

 

 

 

配置項目首頁

<welcome-file-list>
    <welcome-file>/login.jsp</welcome-file>
</welcome-file-list>

缺省時默認是index.xxx。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM