一、新建 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。