一、新建 web 工程,編寫一個類,實現 javax.servlet.Servlet 接口:java
package com.zze.servlet; import javax.servlet.*; import java.io.IOException; public class HelloServlet1 implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException { } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { servletResponse.getWriter().write("Hello Servlet1!!!"); } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
二、在 WEB-INF/web.xml 的 web-app 節下加入以下配置:web
<servlet> <!--給Servlet起名--> <servlet-name>HelloServlet1</servlet-name> <!--Servlet地址--> <servlet-class>com.zze.servlet.HelloServlet1</servlet-class> </servlet> <servlet-mapping> <!--配置Servlet映射,該名稱對應上面已定義的Servlet名--> <servlet-name>HelloServlet1</servlet-name> <!--訪問時的路徑--> <url-pattern>/hello1</url-pattern> </servlet-mapping>
三、接下來就能夠啓動服務,訪問 localhost:8080/hello1 :數組
一、同方式一相似,由於 tomcat 自己就爲咱們提供了 javax.servlet.Servlet 的實現類: javax.servlet.http.HttpServlet ,因此咱們直接繼承它,重寫咱們要使用的方法便可:瀏覽器
package com.zze.servlet; import java.io.IOException; public class HelloServlet2 extends javax.servlet.http.HttpServlet { protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { doGet(request, response); } protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { response.getWriter().write("hello Servlet2!!!"); } }
二、同方式一,在 WEB-INF/web.xml 的 web-app 加入配置:tomcat
<servlet> <servlet-name>HelloServlet2</servlet-name> <servlet-class>com.zze.servlet.HelloServlet2</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet2</servlet-name> <url-pattern>/hello2</url-pattern> </servlet-mapping>
三、重啓 tomcat ,訪問 localhost:8080/hello2 :服務器
建立 Servlet 以下,並加入配置:cookie
package com.zze.servlet; import javax.servlet.*; import java.io.IOException; public class TestServlet implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException { System.out.println("from init"); } @Override public ServletConfig getServletConfig() { System.out.println("from getServletConfig"); return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("from service"); } @Override public String getServletInfo() { System.out.println("from getServletInfo"); return null; } @Override public void destroy() { System.out.println("from destroy"); } }
訪問,接着經過 shutdown.bat 關閉 tomcat, 查看輸出結果:session
from init
from service
from destroy
能夠經過在 servlet 節下加入 load-on-startup 節讓指定 Servlet 實例的 init 方法在程序啓動時執行,以下:app
package com.zze.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; public class TestServlet1 extends HttpServlet { @Override public void init() throws ServletException { System.out.println("form TestServlet1.init"); } }
package com.zze.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; public class TestServlet2 extends HttpServlet { @Override public void init() throws ServletException { System.out.println("form TestServlet2.init"); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>testServlet1</servlet-name> <servlet-class>com.zze.servlet.TestServlet1</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet> <servlet-name>testServlet2</servlet-name> <servlet-class>com.zze.servlet.TestServlet2</servlet-class> <load-on-startup>6</load-on-startup> </servlet> <servlet-mapping> <servlet-name>testServlet1</servlet-name> <url-pattern>/test1</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>testServlet2</servlet-name> <url-pattern>/test2</url-pattern> </servlet-mapping> </web-app>
啓動程序,查看控制檯輸出:ide
form TestServlet1.init
form TestServlet2.init
package com.zze.servlet; import javax.servlet.*; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Enumeration; public class TestServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 獲取 ServletConfig 實例 ServletConfig servletConfig = getServletConfig(); // 獲取 Servlet 名稱,這個名稱指的是在 web.xml 中 servlet 節中配置的 servlet-name 節的值 String servletName = servletConfig.getServletName(); System.out.println(servletName); // 獲取當前 Servlet 對應 web.xml 中 servlet 節下全部 init-param 節 下的 param-name 節中的值 Enumeration<String> initParameterNames = servletConfig.getInitParameterNames(); while (initParameterNames.hasMoreElements()) { String name = initParameterNames.nextElement(); System.out.println(name); // 經過 init-param 下 param-name 的值獲取對應 param-value 的值 String initParameterValue = servletConfig.getInitParameter(name); System.out.println(initParameterValue); } /* 輸出結果: testServlet name bob age 21 */ } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>testServlet</servlet-name> <servlet-class>com.zze.servlet.TestServlet</servlet-class> <init-param> <param-name>name</param-name> <param-value>bob</param-value> </init-param> <init-param> <param-name>age</param-name> <param-value>21</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>testServlet</servlet-name> <url-pattern>/test</url-pattern> </servlet-mapping> </web-app>
建立:服務器啓動的時候,會爲託管的每個web應用程序,建立一個ServletContext對象
銷燬:從服務器移除託管,或者是關閉服務器。
package com.zze.servlet; import javax.servlet.ServletContext; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Enumeration; public class TestServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) { ServletContext servletContext = getServletContext(); // 獲取 web.xml 中 web-app 節下全部 context-param 節 下的 param-name 節中的值 Enumeration<String> initParameterNames = servletContext.getInitParameterNames(); while (initParameterNames.hasMoreElements()) { String name = initParameterNames.nextElement(); // 經過 context-param 下 param-name 的值獲取對應 param-value 的值 String value = servletContext.getInitParameter(name); System.out.println(String.format("name:%s value:%s", name, value)); } /* name:name value:rick name:age value:13 */ } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <context-param> <param-name>name</param-name> <param-value>rick</param-value> </context-param> <context-param> <param-name>age</param-name> <param-value>13</param-value> </context-param> <servlet> <servlet-name>testServlet</servlet-name> <servlet-class>com.zze.servlet.TestServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>testServlet</servlet-name> <url-pattern>/test</url-pattern> </servlet-mapping> </web-app>
現有以下結構:
若是想要在 Servlet 中讀取 test.properties ,能夠經過以下三種方式:
package com.zze.servlet; import javax.servlet.ServletContext; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class TestServletBak extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { func1(); func2(); func3(); } private void func1() { try { ServletContext servletContext = getServletContext(); // 參數傳入相對路徑:相對工程部署在 tomcat 下的工程根目錄 InputStream inputStream = servletContext.getResourceAsStream("file/test.properties"); Properties properties = new Properties(); properties.load(inputStream); String name = properties.getProperty("name"); System.out.println(String.format("from func1:%s", name)); } catch (IOException e) { e.printStackTrace(); } } private void func2() { try { ServletContext servletContext = getServletContext(); // 參數傳入相對路徑:相對工程部署在 tomcat 下的工程根目錄 String realPath = servletContext.getRealPath("file/test.properties"); FileInputStream inputStream = new FileInputStream(realPath); Properties properties = new Properties(); properties.load(inputStream); String name = properties.getProperty("name"); System.out.println(String.format("from func2:%s", name)); } catch (IOException e) { e.printStackTrace(); } } private void func3() { try { InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("../../file/test.properties"); Properties properties = new Properties(); properties.load(inputStream); String name = properties.getProperty("name"); System.out.println(String.format("from func3:%s", name)); } catch (Exception e) { e.printStackTrace(); } } }
ServletContext 實例其實也是一個域對象,存儲在其中的數據能夠被全部 Servlet 共享。看以下示例:
package com.zze.servlet; import javax.servlet.ServletContext; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class SetServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) { ServletContext servletContext = getServletContext(); servletContext.setAttribute("data", "this data is from SetServlet"); System.out.println("set success"); } }
package com.zze.servlet; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class GetServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = getServletContext(); String data = (String) servletContext.getAttribute("data"); System.out.println(String.format("get success,data is '%s'",data)); } }
依次訪問 SetServlet、GetServlet ,獲得輸出結果:
set success
get success,data is 'this data is from SetServlet'
package com.zze.servlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Enumeration; import java.util.Iterator; import java.util.Map; public class TestSerlvet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp){ // 獲取請求頭 Enumeration<String> headerNames = req.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = headerNames.nextElement(); String headerValue = req.getHeader(headerName); System.out.println(String.format("%s:%s", headerName, headerValue)); } // cache-control:no-cache // postman-token:7b0b1d95-d1bd-4282-b516-40ea14910741 // user-agent:PostmanRuntime/7.3.0 // accept:*/* // host:localhost:8080 // cookie:JSESSIONID=BB60472100AF2B9054BC9F61515203A8 // accept-encoding:gzip, deflate // connection:keep-alive // 獲取請求參數 Map<String, String[]> parameterMap = req.getParameterMap(); Iterator<String> keys = parameterMap.keySet().iterator(); while (keys.hasNext()) { String key = keys.next(); String[] values = parameterMap.get(key); System.out.println(String.format("%s:%s", key, values[0])); } // name:zhangsan } }
方法一:手動編碼再解碼。
package com.zze.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Iterator; import java.util.Map; public class TestSerlvet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws UnsupportedEncodingException { String value = req.getParameter("name"); // 由於咱們提交參數時編碼是"UTF-8" 而req.getParameter 默認使用 "ISO-8859-1" 進行解碼, // 因此咱們能夠先用 "ISO-8859-1" 將其編碼回字節數組,而後使用"UTF-8"解碼就可正確顯示內容 String valueStr = new String(value.getBytes("ISO-8859-1"), "UTF-8"); System.out.println(String.format("%s:%s", "name", valueStr)); // name:張三 } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 設置以什麼編碼解析請求體,對 GET 方式無用 req.setCharacterEncoding("UTF-8"); String name = req.getParameter("name"); System.out.println(name); // 張三 } }
方法二:配置 tomcat 的解碼方式:
在 tomcat 目錄下的 conf/server.xml 中 Connector 節下加上 URIEncoding 屬性:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />
以後 req.getParameter 就會使用 UTF-8 進行解碼了。
package com.zze.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class TestServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { // 設置輸出 ContentType response.setContentType("text/plain;charset=utf-8"); // 設置響應狀態碼 response.setStatus(200); // 以字符流方式響應數據 response.getWriter().write("hello"); // 以字節流方式響應數據 response.getOutputStream().write("world".getBytes()); } }
package com.zze.servlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class TestServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { // 設置輸出 ContentType,讓瀏覽器以 utf-8 解析響應內容 response.setContentType("text/plain;charset=utf-8"); // 以 utf-8 編碼響應內容 response.setCharacterEncoding("utf-8"); // 以字符流方式響應數據 response.getWriter().write("哈哈哈哈哈"); // java.lang.String.getBytes() 默認使用 utf-8 編碼 response.getOutputStream().write("啦啦啦啦啦".getBytes("utf-8")); } }
package com.zze.servlet; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class TestServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { // 文件名 String fileName = "testdownload.cs"; // 文件路徑 String filePath = "files/" + fileName; // 設置響應頭通知瀏覽器下載文件而不是直接打開 response.setHeader("Content-Disposition", "attachment;filename=" + fileName); // 獲取該文件輸入流 // String realPath = getServletContext().getRealPath(filePath); // InputStream inputStream = new FileInputStream(realPath); InputStream inputStream = getServletContext().getResourceAsStream(filePath); // 轉化爲輸出流響應 ServletOutputStream outputStream = response.getOutputStream(); int len = 0; byte[] buffer = new byte[1024]; while ((len = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, len); } outputStream.close(); inputStream.close(); } }
public static String EncodeFileName(HttpServletRequest request, String fileName) { try { String downloadFileName = null; String agent = (String) request.getHeader("USER-AGENT"); if (agent != null && agent.toLowerCase().indexOf("firefox") > 0) { downloadFileName = "=?UTF-8?B?" + (new String(Base64.getEncoder().encode(fileName.getBytes("UTF-8")))) + "?="; } else { downloadFileName = java.net.URLEncoder.encode(fileName, "UTF-8"); } return downloadFileName; } catch (Exception e) { e.printStackTrace(); return null; } }
package com.zze.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class TestServlet1 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("from TestServlet1"); request.getRequestDispatcher("/test2").forward(request,response); } }
package com.zze.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class TestServlet2 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("from TestServlet2"); response.getWriter().write("from TestServlet2"); } }
訪問 localhost:8080/test1 ,輸出結果:
from TestServlet1
from TestServlet2
package com.zze.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class TestServlet1 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("from TestServlet1"); response.sendRedirect("/test2"); /* 至關於: response.setStatus(302); response.setHeader("Location","/test2"); */ } }
package com.zze.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class TestServlet2 extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("from TestServlet2"); response.getWriter().write("from TestServlet2"); } }
訪問 localhost:8080/test1 ,輸出結果:
from TestServlet1
from TestServlet2
package com.zze.servlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class SetCookieServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { Cookie cookie1 = new Cookie("name", "zhangsan"); cookie1.setDomain("localhost"); // 設置請求指定域時才攜帶 cookie cookie1.setPath("/cookie"); // 設置請求指定路徑時才攜帶 cookie cookie1.setMaxAge(60); // 設置有效時間,單位爲「秒」 Cookie cookie2 = new Cookie("age","20"); response.addCookie(cookie1); response.addCookie(cookie2); System.out.println("請求成功"); } }
package com.zze.servlet; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class GetCookieServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie[] cookies = request.getCookies(); for (Cookie cookie : cookies) { String name = cookie.getName(); String value = cookie.getValue(); System.out.println(String.format("name:%s,value:%s",name,value)); } } }
先訪問 localhost:8080/cookie/set :
再訪問 localhost:8080/cookie/get ,控制檯輸出:
name:age,value:20 name:name,value:zhangsan name:_gcl_au,value:1.1.931601231.1544668650 name:_ga,value:GA1.1.337106894.1544668656 name:_pk_id.5.1fff,value:2b0610186745f3b2.1545900897.3.1545987031.1545986337. name:_gid,value:GA1.1.1827212045.1546481630
package com.zze.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; public class SetSessionServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); session.setAttribute("name", "zhangsan"); session.setAttribute("age",21); System.out.println("設置 Session 成功"); } }
package com.zze.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.util.Enumeration; public class GetSessionServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); Enumeration<String> attributeNames = session.getAttributeNames(); while (attributeNames.hasMoreElements()){ String name = attributeNames.nextElement(); Object value = session.getAttribute(name); System.out.println(String.format("name:%s value:%s",name,value.toString())); } } }
先訪問 localhost:8080/session/set ,再訪問 localhost:8080/session/get ,控制檯輸出:
設置 Session 成功
SessionId:A2582CD80E2AFCE986D15C9C4C5FCF68
name:name value:zhangsan
name:age value:21
能夠看到,請求 localhost:8080/session/get 時攜帶的名爲 JSESSIONID 的 Cookie 值就是輸出的 SessionId。