javaweb(2)之Servlet入门
Hello Servlet
方式一
1、新建 web 工程,编写一个类,实现 javax.servlet.Servlet 接口:
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() { } }
Code
2、在 WEB-INF/web.xml 的 web-app 节下加入如下配置:
<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>
3、接下来就可以启动服务,访问 localhost:8080/hello1 :
方式二
1、同方式一类似,因为 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!!!"); } }
Code
2、同方式一,在 WEB-INF/web.xml 的 web-app 加入配置:
<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>
3、重启 tomcat ,访问 localhost:8080/hello2 :
Servlet执行流程
创建 Servlet 如下,并加入配置:
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"); } }
Code
访问,接着通过 shutdown.bat 关闭 tomcat, 查看输出结果:
from init from service from destroy
- 结论:
- 1、当 Servlet 被访问时,会先执行它的 init 方法,接着才是执行 service 方法,最后执行 destroy 方法。
- 2、init 方法只有在程序启动后第一次访问时才会执行,service 方法会在每次访问时执行。
- 3、destroy 执行有两种情况:第一种是通过 tomcat 的 shutdown.bat 脚本关闭 tomcat 时会执行,第二种情况是将程序从 tomcat 中移除时会执行。
提前init方法的执行时机
可以通过在 servlet 节下加入 load-on-startup 节让指定 Servlet 实例的 init 方法在程序启动时执行,如下:
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"); } }
com.zze.servlet.TestServlet1
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"); } }
com.zze.servlet.TestServlet2
<?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>
WEB-INF/web.xml
启动程序,查看控制台输出:
form TestServlet1.init form TestServlet2.init
- 结论:
- 1、只要 servlet 节下指定了 load-on-startup,那么在程序启动时这个节对应的 Servlet 就会被加载。
- 2、它的值必须是一个整数,表示 Servlet 的加载顺序。
- 3、如果该元素的值为负数或者没有设置,则容器会当 Servlet 被请求时再加载。
- 4、如果值为正整数或者 0 时,表示容器在应用启动时就会加载并初始化该 Servlet,值越小,优先级越高,就越被先加载。值相同时,容器就会自己选择顺序来加载。
Servlet的初始化参数
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-INF/web.xml
ServletContext使用
生命周期
创建:服务器启动的时候,会为托管的每一个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>
WEB-INF/web.xml
获取web应用中的资源
现有如下结构:
如果想要在 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"); } }
com.zze.servlet.SetServlet
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)); } }
com.zze.servlet.GetServlet
依次访问 SetServlet、GetServlet ,得到输出结果:
set success get success,data is 'this data is from SetServlet'
请求对象-HttpServletRequest
获取请求相关数据
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 进行解码了。
响应对象-HttpServletResponse
响应内容
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); } }
path:/test1
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"); } }
path:/test2
访问 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"); */ } }
path:/test1
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"); } }
path:/test2
访问 localhost:8080/test1 ,输出结果:
from TestServlet1 from TestServlet2
- 总结:
- 1、地址栏:重定向显示的是最后显示的资源地址;而请求转发显示的是最初请求的那个地址。
- 2、请求次数:重定向最少有两次请求,服务器在接收到请求后,会通过返回状态码 302 告知浏览器需要重定向,通过响应头中的 Location 告知浏览器重定向位置;而请求转发只有一次,因为服务器内部帮客户端执行了后续的工作。
- 3、跳转路径:重定向可以跳转到任意路径,不是自己的工程路径也可以跳转;请求转发只能在当前项目路径中跳转。
- 4、request对象:因为重定向就是发起一个新的请求,所以 request 就是一个新的 request 对象,无法使用上一次的 request 对象;而请求转发本质上还是同一次请求,所以可以正常使用初始请求对象。
Cookie和Session
Cookie
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("请求成功"); } }
path:/cookie/set
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)); } } }
path:/cookie/get
先访问 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
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; 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 成功"); } }
path:/session/set
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())); } } }
path:/session/get
先访问 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。
javaweb(2)之Servlet入门的更多相关文章
- 浅谈JavaWEB入门必备知识之Servlet入门案例详解
工欲善其事.必先利其器,想要成为JavaWEB高手那么你不知道servlet是一个什么玩意的话,那就肯定没法玩下去,那么servlet究竟是个什么玩意?下面,仅此个人观点并通过一个小小的案例来为大家详 ...
- JavaWeb之Servlet入门(二)
1. 准备 在JavaWeb之Servlet入门(一)中,我们完成了第一个Servlet程序,完成了从URL到后台控制器的中转过程,接下来我们延续JavaWeb之Servlet入门(一)学习下如何传参 ...
- Servlet视频学习笔记 57-58 (servlet入门和调用过程)
网易云课堂<30天轻松掌握JavaWeb视频>servlet部分 课时57 servlet开发入门 servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术.S ...
- JavaWeb学习之Servlet(二)----Servlet的生命周期、继承结构、修改Servlet模板
[声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140466.html 一.http协议回顾: 在上一篇文章中:JavaW ...
- HTTP协议 Servlet入门 Servlet工作原理和生命周期 Servlet细节 ServletConfig对象
1 HTTP协议特点 1)客户端->服务端(请求request)有三部份 a)请求行--请求行用于描述客户端的请求方式.请求的资源名称,以及使用的HTTP协议版本号 请求行中的GET ...
- JavaWeb三大组件(Servlet,Filter,Listener 自己整理,初学者可以借鉴一下)
JavaWeb三大组件(Servlet,Filter,Listener 自己整理,初学者可以借鉴一下) Reference
- java之servlet入门操作教程一续
本节主要是在java之servlet入门操作教程一 的基础上使用myeclipse实现自动部署的功能 准备: java之servlet入门操作教程一 中完成myFirstServlet项目的创建: ...
- (转)JavaWeb学习之Servlet(二)----Servlet的生命周期、继承结构、修改Servlet模板
[声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140466.html 一.http协议回顾: 在上一篇文章中:JavaW ...
- servlet入门与进阶
servlet入门与进阶 1.servlet基础认知 Servlet(Server Applet):全称Java Servlet,是用Java编写的服务器端程序,其主要功能在于交互式地浏览和修改数据, ...
随机推荐
- mac 上安装 openJDK11
紧接上篇,mac现在基本上作为开发者的主力机,当然也要安装jdk的 首先需要卸载原来的jdk8,如下: ls /Library/Java/JavaVirtualMachines/ sudo rm -r ...
- Python中的string模块的学习
代码为主,相信有python基础的都能看懂: ? [python] view plain copy >>> import string >>> string.a ...
- 理解、学习与使用 JAVA 中的 OPTIONAL<转>
从 Java 8 引入的一个很有趣的特性是 Optional 类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都 ...
- Smart Link
Smart Link通过两个接口相互配合工作来实现功能.这样的一对接口组成了一个Smart Link组.为了区别一个Smart Link组中的两个接口,我们将其中的一个叫做主接口,另一个叫做从接口.同 ...
- SpringBoot 全配置(推荐收藏)
# =================================================================== # COMMON SPRING BOOT PROPERTIE ...
- C_C++变量命名规则
变量命名规则是为了增强代码的可读性和容易维护性.以下为C++必须遵守的变量命名规则: 变量名只能是字母(A-Z,a-z)和数字(0-9)或者下划线(_)组成. 第一个字母必须是字母或者下划线开头. 不 ...
- 【Linux常用工具】
tmux - 终端分屏工具 man - Help cat/more/less - 文件阅读 less还具有字符串搜索功能
- nginx的日志配置
本文转自:https://www.cnblogs.com/biglittleant/p/8979856.html 版权归属原作者!!!!!! nginx access日志配置 access_log日志 ...
- linux Ubuntu系统安装百度aip
1.下载百度api pip install baidu-aip 2.配置视频转码工具ffmpeg Ubuntu16.04下安装FFmpeg(超简单版) 第一步:添加源. sudo add-apt-re ...
- [Manthan, Codefest 18][Codeforces 1037F. Maximum Reduction]
题目链接:1037F - Maximum Reduction 题目大意:给出一段代码,给你一个长度为n的数组和数字k,求程序运行结果,mod 1e9+7输出 简单翻译下代码的意思,初始定义一个空数组b ...