Servlet简介

  • Servlet就是sun公司开发动态web的一门技术
  • Sun在这些APi中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:
    • 编写一个类,实现Serlet接口
    • 把开发好java类部署到web服务器中。

把实现了Servlet接口的Java程序叫做,Servlet

HelloServlet

Serlvet接口Sun公司有两个默认的实现类:HttpServlet,GenericServled

HelloServlet

  1. 构建一个普通的Maven项目,删掉里面的src目录,以后我们的学习就在这个项目里面建立Moudel;这个空的工程就题Maven主工程;

在pom.xml里面放依赖
https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api

  1. <dependencies>
  2. <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
  3. <dependency>
  4. <groupId>javax.servlet</groupId>
  5. <artifactId>javax.servlet-api</artifactId>
  6. <version>4.0.1</version>
  7. <scope>provided</scope> 可以删掉
  8. </dependency>
  9. </dependencies>

JavaServer Page jsp依赖
https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api/2.3.3

  1. <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
  2. <dependency>
  3. <groupId>javax.servlet.jsp</groupId>
  4. <artifactId>javax.servlet.jsp-api</artifactId>
  5. <version>2.3.3</version>
  6. <scope>provided</scope>
  7. </dependency>
  1. 关于Maven父子工程的理解;
    父项目中会有

    1. <modules>
    2. <module>
    3. servlet-01
    4. </module>
    5. </modules>

    子项目会有

    1. <parent>
    2. <artifactId>javaweb-02-servlet</artifactId>
    3. <groupId>com.kuang</groupId>
    4. <version>1.0-SNAPSHOT</version>
    5. </parent>

    父项目中的java子项目可以直接使用

    1. son extends father
  2. Maven环境优化

    1. 修改web.xml为最新的 ```

<?xml version=”1.0” encoding=”UTF-8”?>

  1. 1. maven的结构搭建完整
  2. .![image.png](https://cdn.nlark.com/yuque/0/2021/png/2211273/1611654510796-598e1542-8d90-4693-b533-e0095bd03926.png#align=left&display=inline&height=144&margin=%5Bobject%20Object%5D&name=image.png&originHeight=190&originWidth=346&size=7353&status=done&style=none&width=263)
  3. 4. 编写一个Servlet程序
  4. 1. 编写一个普通类
  5. 1. 实现Servlet接口,这里我们直接继承HttpServlet

public class HelloServlet extends HttpServlet {

  1. //由于get或者post只是请求实现的不同的方式,可以相互调用,业务逻辑都一样;
  2. @Override
  3. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  4. //ServletOutputStream outputStream = resp.getOutputStream();
  5. PrintWriter writer = resp.getWriter(); //响应流
  6. writer.print("Hello,Serlvet");
  7. }
  8. @Override
  9. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  10. doGet(req, resp);
  11. }
  12. }
  1. 5. 编写Servlet的映射<br />为什么需要映射:我们写的是JAVA程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需<br />要再web服务中注册我们写的Servlet,还需给他一个浏览器能够访问的路径;
  1. <servlet>
  2. <servlet-name>hello</servlet-name>
  3. <servlet-class>com.kuang.servlet.HelloServlet</servlet-class>
  4. </servlet>
  5. <!--Servlet的请求路径-->
  6. <servlet-mapping>
  7. <servlet-name>hello</servlet-name>
  8. <url-pattern>/hello</url-pattern>
  9. </servlet-mapping>
  1. 6. 配置Tomcat<br />注意:配置项目发布的路径就可以了<br />![](https://cdn.nlark.com/yuque/0/2021/png/2211273/1611652053932-480ee1be-11f6-4ed0-85af-2410aae69b96.png#align=left&display=inline&height=356&margin=%5Bobject%20Object%5D&originHeight=356&originWidth=512&size=0&status=done&style=none&width=512)<br />![](https://cdn.nlark.com/yuque/0/2021/png/2211273/1611652053971-0265de5d-741e-4614-a85a-c2eff81dae91.png#align=left&display=inline&height=120&margin=%5Bobject%20Object%5D&originHeight=120&originWidth=554&size=0&status=done&style=none&width=554)
  2. 6. 启动测试,OK!<br />![](https://cdn.nlark.com/yuque/0/2021/png/2211273/1611652054058-584d3e8e-0364-4b5e-a115-929d421ea296.png#align=left&display=inline&height=306&margin=%5Bobject%20Object%5D&originHeight=306&originWidth=642&size=0&status=done&style=none&width=642)
  3. <a name="pM5eE"></a>
  4. ## Servlet原理
  5. Servlet是由Web服务器调用,web服务器在收到浏览器请求之后,会:<br />![](https://cdn.nlark.com/yuque/0/2021/png/2211273/1611652054012-8f21fa69-f48c-48bf-aa05-9b10412a6955.png#align=left&display=inline&height=783&margin=%5Bobject%20Object%5D&originHeight=783&originWidth=1058&size=0&status=done&style=none&width=1058)
  6. <a name="hjTWj"></a>
  7. ## Mapping问题
  8. 1. 一个Servlet可以指定一个映射路径<br />.

hello /hello

  1. 2. 一个servlet可以指定多个映射路径

hello /hello hello /hello2 hello /hello3 hello /hello4 hello /hello5

  1. 3. 一个servlet可以指定通用映射路径

hello /hello/*

  1. 4. 默认请求路径
  1. <servlet-mapping>
  2. <servlet-name>hello</servlet-name>
  3. <url-pattern>/*</url-pattern>
  4. </servlet-mapping>
  1. 5. 指定一些后缀或者前缀等等…

hello *.qinjiang

  1. 6. 优先级问题<br />指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;

error com.kuang.servlet.ErrorServlet error /*

  1. <a name="3BVu2"></a>
  2. # ServletConfig
  3. <a name="DMlax"></a>
  4. ## ServletConfig对象有什么用?
  5. 通过此对象可以**读取web.xml中**配置的**初始化参数**。
  6. <a name="PXVXw"></a>
  7. ## 🙄why?
  8. **能够让你的程序更加灵活**【更换需求,更改配置文件web.xml即可,程序代码不用改】
  9. <a name="Flmvo"></a>
  10. ## 获取web.xml文件配置的参数信息
  11. - 为Demo1这个Servlet配置一个参数,参数名是name,值是zhongfucheng
  12. ```xml
  13. <servlet>
  14. <servlet-name>Demo1</servlet-name>
  15. <servlet-class>zhongfucheng.web.Demo1</servlet-class>
  16. <init-param>
  17. <param-name>name</param-name>
  18. <param-value>zhongfucheng</param-value>
  19. </init-param>
  20. </servlet>
  21. <servlet-mapping>
  22. <servlet-name>Demo1</servlet-name>
  23. <url-pattern>/Demo1</url-pattern>
  24. </servlet-mapping>
  • 在Servlet中获取ServletConfig对象,通过ServletConfig对象获取在web.xml文件配置的参数 ```java public class servletConfig extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    1. //获取ServletConfig对象
    2. ServletConfig servletConfig = this.getServletConfig();
    3. //根据配置的名字获取值
    4. String name = servletConfig.getInitParameter("name");
    5. System.out.println(name);

    } }

  1. <a name="ServletContext"></a>
  2. # ServletContext
  3. <a name="ciijZ"></a>
  4. ## 共享数据
  5. - 在一个Servlet中,可以在另一个Servlet中拿到,实现了Servlet之间的通信
  6. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1281683/1598019995087-0c7b4fb8-bbe1-4285-9c61-a0c243e330ef.png#align=left&display=inline&height=239&margin=%5Bobject%20Object%5D&name=image.png&originHeight=320&originWidth=714&size=24381&status=done&style=none&width=534)
  7. ```java
  8. public class HelloServlet extends HttpServlet {
  9. @Override
  10. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  11. System.out.println("Hello");
  12. //this.getInitParameter() 初始化参数
  13. //this.getServletConfig() Servlet配置
  14. //this.getServletContext() Servlet上下文
  15. ServletContext context1 = this.getServletContext();
  16. //将一个数据保存到 ServletContext中,名字为:username,值为username
  17. resp.setContentType("text/html");
  18. resp.setCharacterEncoding("UTF-8");
  19. String username = "shilin.z";
  20. context1.setAttribute("username",username);
  21. }
  22. @Override
  23. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  24. doGet(req, resp);
  25. }
  26. }
  1. public class GetServlet extends HttpServlet {
  2. @Override
  3. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  4. ServletContext context2 = this.getServletContext();
  5. String username = (String) context2.getAttribute("username");
  6. resp.setContentType("text/html");
  7. resp.setCharacterEncoding("UTF-8");
  8. resp.getWriter().print("s1传输的内容: " + username);
  9. }
  10. @Override
  11. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  12. doGet(req, resp);
  13. }
  14. }
  1. <servlet>
  2. <servlet-name>hello</servlet-name>
  3. <servlet-class>edu.cqupt.servlet.HelloServlet</servlet-class>
  4. </servlet>
  5. <servlet-mapping>
  6. <servlet-name>hello</servlet-name>
  7. <url-pattern>/hello</url-pattern>
  8. </servlet-mapping>
  9. <servlet>
  10. <servlet-name>getc</servlet-name>
  11. <servlet-class>edu.cqupt.servlet.GetServlet</servlet-class>
  12. </servlet>
  13. <servlet-mapping>
  14. <servlet-name>getc</servlet-name>
  15. <url-pattern>/getc</url-pattern>
  16. </servlet-mapping>

测试结果:
http://localhost:8080/s2/hello, 不然输出为null
image.png

获取初始化参数

  1. <!-- 配置一些web应用的初始化参数-->
  2. <context-param>
  3. <param-name>url</param-name>
  4. <param-value>jdbc:mysql://local:3306/mybatis</param-value>
  5. </context-param>
  6. <servlet>
  7. <servlet-name>getp</servlet-name>
  8. <servlet-class>edu.cqupt.servlet.Servlet03</servlet-class>
  9. </servlet>
  10. <servlet-mapping>
  11. <servlet-name>getp</servlet-name>
  12. <url-pattern>/getp</url-pattern>
  13. </servlet-mapping>
  1. @Override
  2. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  3. ServletContext context = this.getServletContext();
  4. String url = context.getInitParameter("url");
  5. resp.getWriter().print(url);
  6. }

测试结果:
image.png

请求转发(不是重定向)

image.png

  1. @Override
  2. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  3. System.out.println("进入了Servlet04");
  4. ServletContext context = this.getServletContext();
  5. //RequestDispatcher requestDispatcher = context.getRequestDispatcher("/getp"); //转发的请求路径
  6. //requestDispatcher.forward(req,resp); //调用forward实现请求转发
  7. context.getRequestDispatcher("/getp").forward(req,resp);
  8. }
  1. <servlet>
  2. <servlet-name>sd4</servlet-name>
  3. <servlet-class>edu.cqupt.servlet.Servlet04</servlet-class>
  4. </servlet>
  5. <servlet-mapping>
  6. <servlet-name>sd4</servlet-name>
  7. <url-pattern>/sd4</url-pattern>
  8. </servlet-mapping>

测试结果:
image.png


读取资源文件

  • Properties类
    • 在java目录下新建properties
    • 在resources目录下新建properties
  • 发现:都被打包到了同一路径下:classes,我们俗称路径为classpath

image.png
需要在本项目的pom.xml中配置resources

  1. <!-- bulid中配置resources,来防止我们资源导出失败的问题-->
  2. <build>
  3. <resources>
  4. <resource>
  5. <directory>src/main/resources</directory>
  6. <includes>
  7. <include>**/*.properties</include>
  8. <include>**/*.xml</include>
  9. </includes>
  10. <filtering>true</filtering>
  11. </resource>
  12. <resource>
  13. <directory>src/main/java</directory>
  14. <includes>
  15. <include>**/*.properties</include>
  16. <include>**/*.xml</include>
  17. </includes>
  18. <filtering>true</filtering>
  19. </resource>
  20. </resources>
  21. </build>

需要一个文件流:
Servlet05.java

  1. public class Servlet05 extends HttpServlet {
  2. @Override
  3. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  4. //获得文件流
  5. InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
  6. Properties prop = new Properties();
  7. prop.load(is);
  8. String user = prop.getProperty("username");
  9. String pwd = prop.getProperty("password");
  10. resp.getWriter().print(user + ":" + pwd);
  11. }
  12. @Override
  13. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  14. doGet(req, resp);
  15. }
  16. }

db.properties

  1. username=root
  2. password=123456

web.xml

  1. <servlet>
  2. <servlet-name>sd5</servlet-name>
  3. <servlet-class>edu.cqupt.servlet.Servlet05</servlet-class>
  4. </servlet>
  5. <servlet-mapping>
  6. <servlet-name>sd5</servlet-name>
  7. <url-pattern>/sd5</url-pattern>
  8. </servlet-mapping>

测试结果:
image.png

HttpServletResponse

web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,一个代表响应的HttpServletResponse对象;

  • 如果要获取客户端请求过来的参数:找HttpServletRequset对象
  • 如果要给客户端响应一些信息: 找HttpServletResponse对象

    简单分类

    负责向浏览器发送数据的方法

    1. ServletOutputStream getOutputStream() throws IOException;
    2. PrintWriter getWriter() throws IOException;

    **

    负责向浏览器发送响应头的方法

    1. void setCharacterEncoding(String var1);
    2. void setContentLength(int var1);
    3. void setContentLengthLong(long var1);
    4. void setContentType(String var1);
    5. void setDateHeader(String var1, long var2);
    6. void addDateHeader(String var1, long var2);
    7. void setHeader(String var1, String var2);
    8. void addHeader(String var1, String var2);
    9. void setIntHeader(String var1, int var2);
    10. void addIntHeader(String var1, int var2);

    响应的状态码

    HttpServletResponse定义了很多状态码的常量(具体可以查看Servlet的API),当需要向客户端发送响应状态码时,可以使用这些常量,避免了直接写数字,常见的状态码对应的常量:

    1. int SC_CONTINUE = 100;
    2. int SC_OK = 200;
    3. int SC_MULTIPLE_CHOICES = 300;
    4. int SC_NOT_FOUND = 404;
    5. int SC_INTERNAL_SERVER_ERROR = 500;
    6. .....

    常见应用

    向浏览器输出消息

    使用PrintWriter流输出中文注意问题:

  • 在获取PrintWriter输出流之前首先使用 response.setCharacterEncoding(charset) 设置字符以什么样的编码输出到浏览器

  • 如: response.setCharacterEncoding("UTF-8"); 设置将字符以”UTF-8”编码输出到客户端浏览器,然后再使用 response.getWriter(); 获取PrintWriter输出流,这两个步骤不能颠倒 ```java response.setCharacterEncoding(“UTF-8”);//设置将字符以”UTF-8”编码输出到客户端浏览器 /**
  • PrintWriter out = response.getWriter();这句代码必须放在response.setCharacterEncoding(“UTF-8”);之后
  • 否则response.setCharacterEncoding(“UTF-8”)这行代码的设置将无效,浏览器显示的时候还是乱码 */ PrintWriter out = response.getWriter();//获取PrintWriter输出流 ```
  • 然后再使用 response.setHeader("content-type", "text/html;charset=字符编码"); 设置响应头,控制浏览器以指定的字符编码编码进行显示,例如:
    1. //通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
    2. response.setHeader("content-type", "text/html;charset=UTF-8");
    ```java /**
  • 多学一招:使用HTML语言里面的标签来控制浏览器行为,模拟通过设置响应头控制浏览器行为 *response.getWriter().write(““);
  • 等同于response.setHeader(“content-type”, “text/html;charset=UTF-8”); */ response.getWriter().write(““); ```

    下载文件

    • 获取下载文件的路径
    • 下载的文件名
    • 设置想办法让浏览器能够支持下载我们需要的东西
    • 获取下载文件的输入流
    • 创建缓冲区
    • 获取OutputStream对象
    • 将FileOutputStream流写入到buffer缓冲区
    • 使用OutputStream将缓冲区中的数据输出到客户端 ```java package com.dyq.servlet;

import javax.servlet.ServletException; 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.net.URLEncoder;

public class FileServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.要获取下载文件的路径 // target/classes/段.jpg String realPath = “C:\Users\DYQ\IdeaProjects\javaweb-02-servlet\response\target\classes\段.jpg”; System.out.println(“下载文件的路径”+realPath); //2.下载文件名是啥? String fileName = realPath.substring(realPath.lastIndexOf(“\“) + 1); //“\“是转义 //3.设置想办法让浏览器能够支持下在我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码 resp.setHeader(“Content-Disposition”,”attachment;filename=”+ URLEncoder.encode(fileName,”utf-8”)); //4.获取下载文件的输入流 FileInputStream in = new FileInputStream(realPath); //5.创建缓冲区 int len = 0; byte[] buffer = new byte[1024]; //6.获取OutputStream对象 ServletOutputStream out = resp.getOutputStream(); //7.将FileOutputStream流写入到buffer缓冲区 使用OutputStream将缓冲区中的数据输出到客户端 while (in.read(buffer)>0){ out.write(buffer,0,len); } in.close(); out.close(); }

  1. @Override
  2. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  3. super.doGet(req, resp);
  4. }

}

  1. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1281683/1598064943480-8bf05768-d1c9-41b9-a0f3-54641c1902f8.png#align=left&display=inline&height=498&margin=%5Bobject%20Object%5D&name=image.png&originHeight=995&originWidth=934&size=60658&status=done&style=none&width=467)
  2. <a name="DKCF2"></a>
  3. ### 验证码功能
  4. **验证怎么来的?**
  5. - 前端实现
  6. - 后端实现,需要用到 java 的图片类,生成一个图片
  7. ```java
  8. public class ImageServlet extends HttpServlet {
  9. @Override
  10. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  11. //1. 如何让浏览器3秒自动刷新一次;
  12. resp.setHeader("refresh","3");
  13. //在内存中创建一个图片
  14. BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_3BYTE_BGR);
  15. //得到图片
  16. Graphics2D g = (Graphics2D)image.getGraphics();
  17. // 设置图片的背景颜色
  18. g.setColor(Color.white);
  19. g.fillRect(0,0,80,20);
  20. //给图片写数据
  21. g.setColor(Color.blue);
  22. g.setFont(new Font("宋体",Font.BOLD,20));
  23. g.drawString(makeNum(),0,20);
  24. // 告诉浏览器,这个请求用图片的方式打开
  25. resp.setContentType("image/jpeg");
  26. //网站存在缓存,不让浏览器缓存
  27. resp.setDateHeader("expires", -1);
  28. resp.setHeader("Cache-Control","no-cache");
  29. resp.setHeader("Pragma","no-cache");
  30. // 把图片写给浏览器
  31. boolean write = ImageIO.write(image, "jpg",resp.getOutputStream());
  32. }
  33. //生产随机数
  34. private String makeNum(){
  35. Random random = new Random();
  36. String num = random.nextInt(9999999) + "";
  37. StringBuffer sb = new StringBuffer();
  38. for (int i = 0; i < 7 - num.length() ; i++) { //保证生成的随机数只有7位
  39. sb.append("0"); //不足7位用0填充
  40. }
  41. num = sb.toString() + num;
  42. return num;
  43. }
  44. @Override
  45. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  46. doGet(req, resp);
  47. }
  48. }
  1. <servlet>
  2. <servlet-name>img</servlet-name>
  3. <servlet-class>edu.cqupt.servlet.ImageServlet</servlet-class>
  4. </servlet>
  5. <servlet-mapping>
  6. <servlet-name>img</servlet-name>
  7. <url-pattern>/img</url-pattern>
  8. </servlet-mapping>
  1. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1281683/1598104251154-19554502-a91d-4590-8178-5447323d9028.png#align=left&display=inline&height=242&margin=%5Bobject%20Object%5D&name=image.png&originHeight=630&originWidth=1162&size=35334&status=done&style=none&width=446)

实现重定向

image.png
B一个web资源收到客户端请求后,他会通知客户端去访问另外一个web资源,这个过程叫重定向。
常见场景:

  • 用户登录:登录成功,跳转到另外的页面。 ```java public class RedirectServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

// resp.setHeader(“Location”, “/s3/img”); // resp.setStatus(302); resp.sendRedirect(“/s3/img”); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }

  1. <a name="J83bq"></a>
  2. ## 🧐面试题:请求和重定向的区别?
  3. - 相同点
  4. - 页面都会跳转
  5. - 不同点
  6. - 请求转发,url地址不会发生变化 307
  7. - 重定向,url地址会发生变化 302
  8. ```java
  9. public class RequestTestServlet extends HttpServlet {
  10. @Override
  11. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  12. System.out.println("进入这个请求了----");
  13. // 处理请求
  14. String username = req.getParameter("username");
  15. String pwd = req.getParameter("password");
  16. System.out.println(username + ":" + pwd);
  17. // 重定向一定要注意,路径问题,否则就会404
  18. resp.sendRedirect("/s3/home.jsp");
  19. }
  20. @Override
  21. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  22. doGet(req, resp);
  23. }
  24. }
  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <h1> Success ! </h1>
  8. </body>
  9. </html>

image.png

image.png


HttpServletRequest

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。

常用方法

getRequestURL方法返回客户端发出请求时的完整URL。
  getRequestURI方法返回请求行中的资源名部分。
  getQueryString 方法返回请求行中的参数部分。
  getPathInfo方法返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。
  getRemoteAddr方法返回发出请求的客户机的IP地址
  getRemoteHost方法返回发出请求的客户机的完整主机名。
  getRemotePort方法返回客户机所使用的网络端口号。
  getLocalAddr方法返回WEB服务器的IP地址。
  getLocalName方法返回WEB服务器的主机名。

🙄获得客户机请求参数(客户端提交的数据)

  • getParameter(String)方法(常用)
  • getParameterValues(String name)方法(常用)

    1. public class LoginServlet extends HttpServlet {
    2. @Override
    3. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    4. resp.setCharacterEncoding("utf-8");
    5. req.setCharacterEncoding("utf-8");
    6. //获取前端传递参数
    7. String username = req.getParameter("username");
    8. String password = req.getParameter("password");
    9. String[] hobbies = req.getParameterValues("hobbies");
    10. System.out.println("---------------");
    11. System.out.println(username);
    12. System.out.println(password);
    13. System.out.println(Arrays.toString(hobbies));
    14. System.out.println("---------------");
    15. //重定向
    16. // resp.sendRedirect("/s4/success.jsp");
    17. //通过请求转发
    18. System.out.println(req.getContextPath());
    19. //这里的/代表当前的web应用
    20. req.getRequestDispatcher("/success.jsp").forward(req,resp);
    21. }
    22. @Override
    23. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    24. doGet(req, resp);
    25. }
    26. }

    更多

    https://www.cnblogs.com/xdp-gacl/p/3798347.html


Cookie、Session

会话

会话:用户打开一个浏览器,点击了很多web资源,访问多个web资源,关闭浏览器,这个过程就叫做会话。
有状态会话:客户端访问服务器,下次在访问服务器,服务器知晓客户端曾今访问过。
一个网站怎么证明用户访问过?
客户端 服务器

  • 服务端给客户端一个cookie,客户端下次访问带上cookie就可以了
  • 服务器通过session登记客户端访问过,下次客户端再次访问,服务器匹配客户端

保存会话的两种技术

cookie(发票)

  • 客户端技术(响应、请求)

session(登记)

  • 服务器技术:利用这个技术,可以保存用户的会话信息,我们可以把信息或者数据放在Session中

常见场景:

  • 网站登录过后,下次不用登录,第二次访问直接就进去。

cookie

  • 从请求中拿到cookie
  • 服务器响应给客户端cookie

    1. // 保存用户上一次访问的时间
    2. public class CookieDemo extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. // 服务器告诉你 ,你访问的时间,把这个时间封装成一个信件,下次访问的时候,需要带上信件
    6. req.setCharacterEncoding("gbk");
    7. resp.setCharacterEncoding("gbk");
    8. PrintWriter out = resp.getWriter();
    9. // 服务器端从客户端获取
    10. Cookie[] cookies = req.getCookies(); // cookie可能存在多个
    11. // 判断cookie是否存在
    12. if(cookies!=null){
    13. //如果存在
    14. out.write("你上次访问的时间是:");
    15. for (int i = 0; i <cookies.length ; i++) {
    16. Cookie cookie = cookies[i];
    17. // 获取cookie的名字
    18. if(cookie.getName().equals("lastLoginTime")){
    19. long lastLoginTime = Long.parseLong(cookie.getValue());
    20. Date date = new Date(lastLoginTime);
    21. out.write(date.toLocaleString());
    22. }
    23. System.out.println(cookie.getName());
    24. }
    25. }else{
    26. out.write("这是您第一次访问本网站。");
    27. }
    28. //服务器给客户端响应一个Cookie
    29. Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");
    30. cookie.setMaxAge(24*60*60);
    31. resp.addCookie(cookie);
    32. }
    33. @Override
    34. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    35. doGet(req, resp);
    36. }
    37. }

    image.png
    image.png

    🍋Session(重点)

    image.png

    什么是Session:

  • 服务器给每一个用户(浏览器)创建一个Session对象

  • 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在
  • 用户登录之后,整个网站都可以访问!
  • 场景:保存用户的信息,保存购物车信息,在整个网站中经常会使用的数据,我们将它保存在session中


Session和Cookie的区别:**

  • Cookie是把用户的数据写给用户得浏览器,浏览器保存(可以保存多个)
  • Session把用户的数据写到用户独占的Session中,服务器端保存(保存重要的信息,减少服务器资源的浪费)
  • Session对象由服务器创建

使用Session

  1. public class SessionDemo extends HttpServlet {
  2. @Override
  3. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  4. // 解决乱码问题
  5. resp.setHeader("content-type","text/html; charset=utf-8");
  6. req.setCharacterEncoding("utf-8");
  7. resp.setCharacterEncoding("utf-8");
  8. //得到session
  9. HttpSession session = req.getSession();
  10. //获取Session的ID
  11. String sessionId = session.getId();
  12. //判断session是否为新创建的
  13. if(session.isNew()){
  14. resp.getWriter().write("session 创建成功。session ID:" + sessionId );
  15. }else{
  16. resp.getWriter().write("已经在服务器中存在了。session ID:" + sessionId );
  17. }
  18. // Session创建的时候做了什么事情
  19. //Cookie cookie = new Cookie("JSESSIONID",sessionId);
  20. //resp.addCookie(cookie);
  21. //给Session中存字符串
  22. session.setAttribute("name","shilin.z");
  23. String name = (String) session.getAttribute("name");
  24. System.out.println(name);
  25. //给Session中存用户信息
  26. session.setAttribute("name",new Person("shilin.z",20));
  27. Person person = (Person) session.getAttribute("name");
  28. System.out.println(person.toString());
  29. //手动注销Session: 刷新,会重新生成sessionID
  30. //session.removeAttribute("name");
  31. //session.invalidate();
  32. //自动注销:在xml中配置
  33. }
  34. @Override
  35. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  36. doGet(req, resp);
  37. }
  38. }
  1. <!-- 设置Session 默认的失效时间,以分钟为单位-->
  2. <session-config>
  3. <!-- 1分钟后失效 -->
  4. <session-timeout>1</session-timeout>
  5. </session-config>