飞道的博客

带你吃透Servlet核心编程下篇(完整图文教程)

271人阅读  评论(0)


本文被 系统学习JavaWeb 收录点击订阅专栏



1 Http协议

1.1 什么是 HTTP 协议

协议是双方或者多方约定好需要遵守的规则。所谓HTTP协议就是指,在客户端和服务端通信时,发送的数据,需要遵守的规则。HTTP协议中的数据称为报文。

客户端给服务器发送数据叫请求,而服务器给客户端回传数据叫响应。
请求分为GET请求和POST请求。

1.2 GET请求与POST请求

GET请求的组成如下:

  1. 请求行
    (1)请求的方式 GET
    (2)请求的资源路径 [+?+请求参数]
    (3)请求的协议版本号 HTTP/1.1
  2. 请求头
    key:value 组成,不同的键值对,表示不同的含义。

GET请求HTTP协议内容示例:

常用请求头的说明:

  • Accept: 告诉服务器,客户端可以接收的数据类型;
  • Accept-Language: 告诉服务器客户端而言接收的语言类型;
  • User-Agent: 浏览器的信息;
  • Accept-Encoding: 告诉服务器,客户端可以接收的数据编码(压缩)格式;
  • Host: 表示请求的服务器ip和端口号;
  • Connection: 告诉服务器请求连接如何处理
     Keep-Alive:服务器马上回传数据,不要马上关闭,保持一小会儿的连接
     Closed: 马上关闭

POST请求的组成如下:

  1. 请求行
    (1)请求的方式 GET
    (2)请求的资源路径 [+?+请求参数]
    (3)请求的协议版本号 HTTP/1.1
  2. 请求头
    key:value 组成,不同的请求头,表示不同的含义。
  3. 请求体:发送给服务器的数据

辨析哪些是GET请求,哪些是POST请求
常用的GET请求:

  1. form标签 method=get
  2. a 标签
  3. link标签引入css
  4. Script标签引入js文件
  5. img标签引入图片
  6. iframe引入html页面
  7. 在浏览器地址栏输入地址后敲回车

常用的POST请求:

  1. form标签 method=post

1.3 响应的HTTP协议格式

响应的HTTP协议格式组成如下:

  1. 响应行
    (1)响应的协议和版本号
    (2)响应状态码
    (3)响应状态码描述符
  2. 响应头
    key:value 组成,不同的响应头,表示不同的含义。
  3. 响应体:回传给客户端的数据、

示例图如下:

常用的响应码:

响应码 说明
200 表示请求成功
302 表示请求重定向
404 表示请求服务器已经收到,但是需要访问的数据不存在
500 表示服务器已经收到请求,但是服务器内部错误

1.4 MIME数据类型

MIME是HTTP协议中的数据类型。全称是"Multipurpose Internet Mail Extensions"多功能Internet邮件扩充服务,MIME类型的格式是"大类型/小类型",并与某一种文件的扩展名相对应。

常见的MIME类型:


2 HttpServletRequest类

2.1 HttpServletRequest说明及常用方法

每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中。然后传递到service方法(doGet、doPost)中供我们使用。我们可以通过HttpServletRequest对象获取到所有请求的信息。

HttpServletRequest类常用方法

方法 说明
getRequestURL() 获取请求的资源路径
getRequestURL() 获取请求的统一资源定位符(绝对路径)
getRemoteHost() 获取客户端的ip地址
getHeader() 获取请求头
getParameter() 获取请求的参数
getParamterValues() 获取请求的参数(多个值使用)
getMethod() 获取请求的方式POST或GET
setAttribute(key,value) 设置域数据
getAttribute(key) 获取域数据
getRequestDispatcher() 获取请求转发对象

2.2 HttpServletRequest类演示

xml配置文件如下:

<?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>RequestAPIServelet</servlet-name>
        <servlet-class>com.example.servlet_test.RequestAPIServelet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RequestAPIServelet</servlet-name>
        <url-pattern>/requestAPIServlet</url-pattern>
    </servlet-mapping>
</web-app>

RequestAPIServelet.java

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 兴趣使然黄小黄
 * @version 1.0
 */
public class RequestAPIServelet extends HttpServlet {
   
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   
        //1. 获取请求的资源路径
        System.out.println("URL = " + req.getRequestURI());
        //2. 获取绝对路径(返回值是StringBuffer)
        System.out.println("URL = " + req.getRequestURL());
        //3. 获取客户端的ip地址
        /*
         * 在IDEA中,使用LocalHost访问时,得到的客户端的ip地址时127.0.0.1
         * IPV6表现形式则为0:0:0:0:0:0:0:1
         */
        System.out.println("ip = " + req.getRemoteHost());
        //4. 获取请求头
        System.out.println("请求头User-Agent = " + req.getHeader("User-Agent"));
        //5. 获取请求方式
        System.out.println("请求方式 = " + req.getMethod());
    }
}


 

2.3 获取请求表单中的参数值(POST请求)

下面演示如何获取表单的信息,以Post请求方式为例
xml配置文件信息:

<?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>ServletRequest</servlet-name>
        <servlet-class>com.example.servlet_test.ServletRequest</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletRequest</servlet-name>
        <url-pattern>/servletRequest</url-pattern>
    </servlet-mapping>
</web-app>

html页面信息如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://localhost:8080/Servlet_Test/servletRequest" method="post">
    用户名:<input type="text" name="username"><br/>
    密码:<input type="password" name="password"><br/>
    兴趣爱好:<input type="checkbox" name="hobby" value="java">Java
    <input type="checkbox" name="hobby" value="python">Python
    <input type="checkbox" name="hobby" value="C++">C++
    <input type="submit">
</form>
</body>
</html>

 

获取请求参数的方法都写在了ServletRequest类中

ServletRequest.java:

package com.example.servlet_test;

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.util.Arrays;

/**
 * @author 兴趣使然黄小黄
 * @version 1.0
 * 读取表单数据
 */
public class ServletRequest extends HttpServlet {
   
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   
        //获取请求参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobby = req.getParameterValues("hobby");
        //打印
        System.out.println("用户名:" + username);
        System.out.println("密码:" + password);
        System.out.println("爱好:" + Arrays.asList(hobby));
    }
}


 


2.4 解决post请求中的中文乱码问题

还是刚刚的例子,表单中的内容如下图(用户名用中文):

提交后,控制台获取的参数信息如下;

用户名中文出现了乱码!如何解决?

只需要在获取参数前设置编码格式为utf-8即可


req.setCharacterEncoding(“UTF-8”):设置请求体的字符集为UTF-8,从而解决post请求的中文乱码问题。


3 请求转发

何为请求转发?
请求转发是指当服务器接收到请求后,从一个资源跳转到另一个资源的操作。

请求转发的特点如下:

  • 浏览器地址不会变化
  • 仅仅是一次请求
  • 可以共享Request域的数据
  • 可以转发到 WEB-INF 目录(一般情况无法访问,可以通过请求转发访问)
  • 不可以访问到工程以外的资源

示例代码如下:(xml配置文件略,可以自己参考类名去配置)

public class Servlet1 extends HttpServlet {
   
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   
        //获取请求的参数
        String username = req.getParameter("username");
        System.out.println("servlet1中 username = " + username);
        //给材料盖章,传递到servlet2查看
        req.setAttribute("key1", "柜台1的章");
        //问路:servlet2怎么走
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
        //走向Servlet2
        requestDispatcher.forward(req, resp);
    }
}


public class Servlet2 extends HttpServlet {
   
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   
        //获取请求参数
        String username = req.getParameter("username");
        System.out.println("servlet2中 username = " + username);
        //查看柜台1是否有章
        Object key1 = req.getAttribute("key1");
        System.out.println("柜台1是否有章 " + key1);
        //处理自己的业务
        System.out.println("柜台二处理中");
    }
}

 

4 HttpServletResponse类

HttpServletResponse类与HttpServletRequest类一样。每次请求进来,Tomcat服务器都会创建一个Response对象传递给Servlet程序使用。HttpServletRequest表示所有请求过来的信息,而HttpServletResponse表示所有相应的信息。

如果我们希望设置返回给客户端的信息,则可以通过HttpServletResponse对象来进行设置。

4.1 两个输出流

使用场景
字节流 getOutputStream() 常用于下载(传递二进制数据)
字符流 getWriter() 常用于回传字符串

两个流只能同时使用一个

4.2 如何回传客户端数据

往客户端回传字符串数据

案例代码如下:

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.PrintWriter;

/**
 * @author 兴趣使然黄小黄
 * @version 1.0
 */
public class ResponseIO extends HttpServlet {
   
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   
        PrintWriter writer = resp.getWriter();
        writer.write("response's content!!!");
    }
}

 

同样,该案例中也存在响应的中文乱码问题
与post请求的中文乱码问题不同的是,不能仅仅设置服务端的编码格式,还需要将浏览器默认解析的编码格式统一!

代码如下:

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.PrintWriter;

/**
 * @author 兴趣使然黄小黄
 * @version 1.0
 */
public class ResponseIO extends HttpServlet {
   
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   
        //设置服务器的字符集
        resp.setCharacterEncoding("UTF-8");
        //通过响应头,设置浏览器的字符集
        resp.setHeader("Content-Type", "text/html;charset=UTF-8");

        PrintWriter writer = resp.getWriter();
        writer.write("这是一段中文!");
    }
}

 

也可以在获取流对象前,通过一个方法同时设置服务端和客户端的编码集:

resp.setContentType("text/html;charset=UTF-8");

5 请求重定向

5.1 什么是请求重定向

请求重定向是指客户端给服务端发请求,然后服务器给客户端提供了一个新的地址去访问。可以简单理解为:呼叫转移~

需要注意请求重定向与请求转发的区别!
请求重定向的特点如下:

  • 不共享Request域的数据
  • 两次请求
  • 浏览器地址栏会发生变化
  • 不能访问到WEB-INF目录下的资源
  • 可以访问到工程外的资源

5.2 请求重定向演示

Response1.java

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 兴趣使然黄小黄
 * @version 1.0
 * 演示请求重定向
 */
public class Response1 extends HttpServlet {
   
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   
        System.out.println("----------Response1---------");
        //设置状态码302 表示重定向
        resp.setStatus(302);
        resp.setHeader("Location", "http://localhost:8080/Servlet_Test/response2");
    }
}

 

Response2.java

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 兴趣使然黄小黄
 * @version 1.0
 * 演示请求重定向
 */
public class Response2 extends HttpServlet {
   
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   
        System.out.println("----------Response2---------");
        resp.getWriter().write("response2");
    }
}

 


补充
请求重定向也有一种简便的实现方式:

resp.sendRedirect("http://xxxx/xxx/xxx...");

写在最后

 本文部分内容参考:尚硅谷JavaWeb课程。好了,本文内容到这里就告一段落了,欢迎大家订阅专栏,加入JavaWeb学习!点击订阅

 如果你有任何问题,欢迎私信,感谢您的支持!


转载:https://blog.csdn.net/m0_60353039/article/details/127304742
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场