Serlvet3.0 註解 淺析_servlet

來源:互聯網
上載者:User
(1)註解配置 一、Servlet3.0介紹

Servlet3.0是Java EE6規範的一部分,Servlet3.0提供了註解(annotation),使得不再需要在web.xml檔案中進行Servlet的部署描述,簡化開發流程。 二、開發Servlet3.0程式的所需要的環境

開發Servlet3.0的程式需要一定的環境支援。MyEclipse10和Tomcat7都提供了對Java EE6規範的支援。若用低版本時需要手動設定環境
所以開發Servlet3.0的程式需要以下的開發環境支援:
- IDE:MyEclipse 10+
- JDK:JDK 1.6+
- tomcat:tomcat 7+

import java.io.IOException;  import javax.servlet.ServletException;  import javax.servlet.annotation.WebServlet;  import javax.servlet.http.HttpServlet;  import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpServletResponse;  /**   * 註解WebServlet用來描述一個Servlet   * 屬性name描述Servlet的名字,可選   * 屬性urlPatterns定義訪問的URL,或者使用屬性value定義訪問的URL.(定義訪問的URL是必選屬性)   * //註解配置  @WebServlet(  displayName = "UserServlet" , //描述  name = "UserServlet", //servlet名稱  urlPatterns = { "/user" }, //url  loadOnStartup = 1, //啟動項  initParams = { @WebInitParam(name = "username", value = "張三") }  )//初始化參數   */  @WebServlet(name="Servlet3Demo",urlPatterns="/Servlet3Demo")  public class Servlet3Demo extends HttpServlet {      public void doGet(HttpServletRequest request, HttpServletResponse response)              throws ServletException, IOException {          response.getWriter().write("Hello Servlet3.0");      }      public void doPost(HttpServletRequest request, HttpServletResponse response)              throws ServletException, IOException {          this.doGet(request, response);      }  }  /*   * 完成了一個使用註解描述的Servlet程式開發。    使用@WebServlet將一個繼承於javax.servlet.http.HttpServlet的類定義為Servlet組件。    @WebServlet有很多的屬性:        1、asyncSupported:    聲明Servlet是否支援非同步作業模式。        2、description:      Servlet的描述。        3、displayName:       Servlet的顯示名稱。        4、initParams:        Servlet的init參數。        5、name:           Servlet的名稱。        6、urlPatterns:     Servlet的訪問URL。        7、value:           Servlet的訪問URL。    Servlet的訪問URL是Servlet的必選屬性,可以選擇使用urlPatterns或者value定義。    像上面的Servlet3Demo可以描述成@WebServlet(name="Servlet3Demo",value="/Servlet3Demo")。    也定義多個URL訪問:    如@WebServlet(name="Servlet3Demo",urlPatterns={"/Servlet3Demo","/Servlet3Demo2"})    或者@WebServlet(name="AnnotationServlet",value={"/Servlet3Demo","/Servlet3Demo2"})   *   */  
注意web.xml檔案中的version資訊,version=”3.0”和http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd 這就是表示當前使用的是Servlet3.0的版本。 (2)非同步呼叫

在Servlet3.0中,在Servlet內部支援非同步處理。它的邏輯是當我們請求一個Servlet時,我們的Servlet可以先返回一部分內容給用戶端。然後在Servlet內部非同步處理另外一段邏輯,等到非同步處理完成之後,再把非同步處理的結果返回給用戶端。
注: 非同步處理費時的業務

@WebServlet(value="/s3", asyncSupported=true)public class servlet3 extends HttpServlet{    @Override    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        //請求        request.setCharacterEncoding("utf-8");        //響應        response.setContentType("text/html;charset=utf-8");        final PrintWriter out=response.getWriter();        out.println("<p>非同步之前輸出的內容。</p>");          out.flush();          //開始非同步呼叫,擷取對應的AsyncContext。            final AsyncContext asyncContext = request.startAsync();            //設定逾時時間,當逾時之後程式會嘗試重新執行非同步任務,即我們新起的線程。            asyncContext.setTimeout(10*1000L);            //新起線程開始非同步呼叫,start方法不是阻塞式的,它會新起一個線程來啟動Runnable介面,之後主程式會繼續執行            asyncContext.start(new Runnable() {               public void run() {                  try {                      Thread.sleep(5*1000L);                      out.println("<p style='border:1px solid blue;'>非同步呼叫之後輸出的內容。</p>");                      out.flush();                      //非同步呼叫完成,如果非同步呼叫完成後不調用complete()方法的話,非同步呼叫的結果需要等到設定的逾時                      //時間過了之後才能返回到用戶端。                      asyncContext.complete();                  } catch (Exception e) {                      e.printStackTrace();                  }               }            });            out.println("<p style='border:1px solid red;'>可能在非同步呼叫前輸出,也可能在非同步呼叫之後輸出,因為非同步呼叫會新起一個線程。</p>");            out.flush();      }}

非同步呼叫監聽器

   當我們需要對非同步呼叫做一個詳細的監聽的時候,比如監聽它是否逾時,我們可以通過給AsyncContext設定對應的監聽器AsyncListener來實現這一功能。AsyncListener是一個介面,裡面定義了四個方法,分別是針對於非同步呼叫開始、結束、出錯和逾時的。
(3)檔案上傳

在Servlet3.0中上傳檔案變得非常簡單。我們只需通過request的getPart(String partName)擷取到上傳的對應檔案對應的Part或者通過getParts()方法擷取到所有上傳檔案對應的Part。之後我們就可以通過part的write(String fileName)方法把對應檔案寫入到磁碟。或者通過part的getInputStream()方法擷取檔案對應的輸入資料流,然後再對該輸入資料流進行操作。要使用request的getPart()或getParts()方法對上傳的檔案進行操作的話,有兩個要注意的地方。首先,用於上傳檔案的form表單的enctype必須為multipart/form-data;其次,對於使用註解聲明的Servlet,我們必須在其對應類上使用@MultipartConfig進行標註,而對於在web.xml檔案進行配置的Servlet我們也需要指定其multipart-config屬性,如:

xml代碼:

<servlet>     <servlet-name>xxx</servlet-name>     <servlet-class>xxx.xxx</servlet-class>     <multipart-config></multipart-config>  </servlet>  <servlet-mapping>     <servlet-name>xxx</servlet-name>     <url-pattern>/servlet/xxx</url-pattern>  </servlet-mapping>   file-size-threshold:數字類型,當檔案大小超過指定的大小後將寫入到硬碟上。預設是0,表示所有大小的檔案上傳後都會作為一個臨時檔案寫入到硬碟上。  location:指定上傳檔案存放的目錄。當我們指定了location後,我們在調用Part的write(String fileName)方法把檔案寫入到硬碟的時候可以,檔案名稱可以不用帶路徑,但是如果fileName帶了絕對路徑,那將以fileName所帶路徑為準把檔案寫入磁碟。  max-file-size:數實值型別,表示單個檔案的最大大小。預設為-1,表示不限制。當有單個檔案的大小超過了max-file-size指定的值時將拋出IllegalStateException異常。  max-request-size:數實值型別,表示一次上傳檔案的最大大小。預設為-1,表示不限制。當上傳時所有檔案的大小超過了max-request-size時也將拋出IllegalStateException異常。上面的屬性是針對於web.xml中配置Servlet而言的,其中的每一個屬性都對應了multipart-config元素下的一個子項目。對於基於註解配置的Servlet而言,@MultipartConfig的屬性是類型的,我們只需把上述對應屬性中間的杠去掉,然後把對應字母大寫即可,如maxFileSize。 
@WebServlet("/servlet/upload")  @MultipartConfig  public class FileUploadServlet extends HttpServlet {     /**     *     */     private static final long serialVersionUID = 1L;     @Override     protected void doPost(HttpServletRequest req, HttpServletResponse resp)           throws ServletException, IOException {        req.setCharacterEncoding("UTF-8");        Part part = req.getPart("upload");        //格式如:form-data; name="upload"; filename="YNote.exe"        String disposition = part.getHeader("content-disposition");        System.out.println(disposition);        String fileName = disposition.substring(disposition.lastIndexOf("=")+2, disposition.length()-1);        String fileType = part.getContentType();        long fileSize = part.getSize();        System.out.println("fileName: " + fileName);        System.out.println("fileType: " + fileType);        System.out.println("fileSize: " + fileSize);        String uploadPath = req.getServletContext().getRealPath("/upload");        System.out.println("uploadPath" + uploadPath);        part.write(uploadPath + File.separator +fileName);     }  }         對於Servlet3.0中的檔案上傳還有一個需要注意的地方,當我們把Part寫入到硬碟以後,我們原先的Part(也就是之前的臨時檔案)可能已經刪了,這個時候如果我們再次去訪問Part的內容的話,那它就是空的,系統會拋出異常說找不到對應的檔案。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.