----------------------------------------------------------------------------------------------
[版權申明:本文系做者原創,轉載請註明出處]
文章出處:http://blog.csdn.net/sdksdk0/article/details/51953305
做者:朱培 ID:sdksdk0 郵箱: zhupei@tianfang1314.cn html
--------------------------------------------------------------------------------------------java
本文主要介紹servlet的基本使用操做,是一些很是基礎的知識,主要掌握servlet做用域、servlet映射、請求轉發、ServletConfig配置、ServletContext等的使用,最後以一個簡易的文件下載的案例來講明Servlet的應用。git
Servlet運行於支持Java的應用服務器中。從原理上講,Servlet能夠響應任何類型的請求,但絕大多數狀況下Servlet只用來擴展基於HTTP協議的Web服務器。
最先支持Servlet標準的是JavaSoft的Java Web Server,此後,一些其它的基於Java的Web服務器開始支持標準的Servlet。servlet是運行在web服務器中的小型java程序,經過HTTP接收和響應web客戶端的請求。github
Servlet 看起來像是一般的 Java 程序。Servlet 導入特定的屬於 Java Servlet API 的包。由於是對象字節碼,可動態地從網絡加載,能夠說 Servlet 對 Server 就如同 Applet對 Client 同樣,可是,因爲 Servlet 運行於 Server 中,它們並不須要一個圖形用戶界面。從這個角度講,Servlet 也被稱爲 FacelessObject。web
一、編碼一個類,實現javax.servlet.Servlet接口或者繼承javax.servlet.GenericServlet瀏覽器
public class HelloServlet extends GenericServlet{ public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException{ res.getOutputStream().write("hello world".getBytes()); } }
二、配置一個servlet。web.xml中tomcat
<!--聲明一個servlet --> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>cn.tf.servlet.HelloServlet</servlet-class> </servlet> <!-- 給servlet映射一個url地址 --> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
三、把應用部署到Tomcat中,以後才能夠看到效果。安全
六、找到對應的類HelloServlet.class:先從應用的class目錄、應用的lib中的jar包、Tomcat\lib目錄中全部的jar包這個順序進行查找。 實例化servlet對象,接着調用init方法、第一次訪問時調用.服務器
七、有Tomcat調用該類的servlet方法網絡
實例化對象,第一次訪問時調用.
init() 一旦初始化完成,該實例就一直保持在Tomcat的內存中,第一次訪問時調用.。
getServletInfo() 返回做者、版權等信息。
service() 用戶每次請求都會執行。
destroy() 關閉tomcat的時候調用。
加載和實例化 Servlet。這項操做通常是動態執行的。然而,Server 一般會提供一個管理的選項,用於在 Server 啓動時強制裝載和初始化特定的 Servlet。
public class ServletDemo2 implements Servlet { public ServletDemo2(){ System.out.println("調用了servletDemo2的構造方法"); } //初始化 @Override public void init(ServletConfig arg0) throws ServletException { System.out.println("調用了init方法"); } //獲取servlet配置的方法 @Override public ServletConfig getServletConfig() { return null; } //返回做者,版權等信息 @Override public String getServletInfo() { return null; } //服務器方法 @Override public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException { System.out.println("執行了service方法"); } //銷燬方法 @Override public void destroy() { System.out.println("服務器被銷燬"); } }
經過web.xml讓servlet在Tomcat加載應用時,就完成實例化和初始化。
<load-on-startup>2</load-on-startup>
GenericServlet和HttpServlet的對比
從大到小:servlet、GenericServlet、HttpServlet myeclipse默認的是繼承HttpServlet。這個時候不須要覆蓋service方法。繼承了doGet、doPost方法。
映射地址:多個不一樣的地址能夠映射到同一個servlet.
通配符映射:*匹配全部字符串 url-pattern:
匹配原則: 絕對匹配: /開頭的批評 擴展名結尾的 (優先級高->低).
默認的servlet:一個servlet的url-pattern爲一個/,那麼這個servlet就是默認的servlet。
線程安全
對於單例對象:多線程就可能出現線程安全問題。 實現SingleThreadModel接口後,控制線程安全問題徹底由服務器來決定。
在servlet中儘可能不要使用實例變量,應該要使用局部變量。
將編碼配置放到web.xml中。
<init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param>
讀取配置參數的值: ServletConfig
String value=getServletConfig().getInitParameter("encoding");
一、 servletContext的實例就表明當前的javaweb應用。 一個javaweb只有一個servletContext的實例。當前應用中的其餘資源(servlet、jsp、html等)共享同一個ServletContext.
二、生命週期 應用被服務器加載時產生ServletContext實例。 生命週期是 從servletContext建立到服務器關閉
三、得到ServletContext的引用
ServletContext sc=getServletContext();
sc.setAttribute("a", "demo1"); Object value=sc.getAttribute("a");
四、得到web應用的全局參數 在web.xml中配置
<context-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </context-param>
調用:
ServletContext sc=config.getServletContext(); sc.getInitParameter("encoding");
五、servlet請求轉發 從demo4轉到demo3
ServletContext sc=getServletContext(); RequestDispatcher dispatcher=sc.getRequestDispatcher("/servlet/Demo3"); dispatcher.forward(request, response);
六、讀取配置文件
ResourceBundle只適合讀取properties文件,只能讀取類路徑中的配置文件,WEB-INF/class或者jar中的文件:
ResourceBundle rb=ResourceBundle.getBundle("cn.tf.servletContext.c");
ServletContext:String getRealPath(String path), 獲取到文件的真實路徑,只適合javaweb應用,可以讀取其任何位置的任意文件:
ServletContext sc=getServletContext(); String path=sc.getRealPath("/WEB-INF/a.properties"); System.out.println(path); Properties prop=new Properties(); prop.load(new FileInputStream(path)); System.out.println(prop.getProperty("key"));
用類加載器:文件位置要在在類路徑中,能夠讀取任意類型的文件,不適合讀取大文件。
ClassLoader cl=Demo5.class.getClassLoader(); InputStream is=cl.getResourceAsStream("cn/tf/servletContext/c.properties"); Properties prop=new Properties(); prop.load(is); System.out.println(prop.getProperty("key"));
ServletContext sc=getServletContext(); String path=sc.getRealPath("/WEB-INF/1.jpg");
OutputStream out=response.getOutputStream(); int len =-1; byte b[] =new byte[1024]; while((len=in.read(b))!=-1){ out.write(b,0,len); }四、告知瀏覽器去下載這個文件
response.setHeader("Content-Disposition", "attachment;filename=1.jpg"); response.setHeader("Content-Type", "application/octet-stream");
in.close(); out.close();
//文件下載 public class Demo6 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲得要下載的文件的真實路徑 ServletContext sc=getServletContext(); String path=sc.getRealPath("/WEB-INF/1.jpg"); InputStream in=new FileInputStream(path); //告知瀏覽器去下載 response.setHeader("Content-Disposition", "attachment;filename=1.jpg"); response.setHeader("Content-Type", "application/octet-stream"); OutputStream out=response.getOutputStream(); int len =-1; byte b[] =new byte[1024]; while((len=in.read(b))!=-1){ out.write(b,0,len); } in.close(); out.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }