Java Web(5)-Servlet详解(下)

一、HttpServletRequest 类

1. HttpServletRequest 类作用?

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

2. HttpServletRequest 类的常用方法

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

具体如下:

首先把环境建好,配置好web.xml ,然后在类中

package com.md.servlet;

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

/**
 * @author MD
 * @create 2020-07-25 8:18
 */
public class RequestAPIServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println(req.getRequestURI());// /04_Servlet/requestAPIServlet

        System.out.println(req.getRequestURL());
        //http://localhost:8080/04_Servlet/requestAPIServlet

        System.out.println(req.getRemoteHost());//127.0.0.1

        System.out.println(req.getHeader("User-Agent"));//Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36

        System.out.println(req.getMethod());//GET
    }

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

对应的web.xml

 <servlet>
        <servlet-name>RequestAPIServlet</servlet-name>
        <servlet-class>com.md.servlet.RequestAPIServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>RequestAPIServlet</servlet-name>
        <url-pattern>/requestAPIServlet</url-pattern>
    </servlet-mapping>

3. 获取请求参数

首先在web下面建立html文件,如下

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

然后是对应的java代码,以及配置的web.xml(和上面的类似)

/**
 * @author MD
 * @create 2020-07-25 8:31
 */
public class ParameterServlet extends HttpServlet {


    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("------------doGet--------------");
        // 获取请求的参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
//        String hobby = req.getParameter("hobby");
        // 当有多个值的时候
        String [] hobby = req.getParameterValues("hobby");

        System.out.println("用户名:"+username);
        System.out.println("密码:"+password);
        System.out.println("爱好:"+ Arrays.asList(hobby));


    }
}

4. 中文乱码

使用post请求的时候,如果用户名输入的是中文,则会出现中文乱码的情况,所以需要这样设置

public class ParameterServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 在post的时候注意设置字符集,要不中文乱码
        // 只有在获取请求参数调用之前使用才有效
        req.setCharacterEncoding("UTF-8");

        System.out.println("------------doPost--------------");

        // 获取请求的参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
//        String hobby = req.getParameter("hobby");
        // 当有多个值的时候
        String [] hobby = req.getParameterValues("hobby");

        System.out.println("用户名:"+username);
        System.out.println("密码:"+password);
        System.out.println("爱好:"+ Arrays.asList(hobby));

    }
}

5. 请求转发

什么是请求的转发?

请求转发是指服务器收到请求后,从一次资源跳转到另一个资源的操作叫请求转发

请求转发的特点:

  • 浏览器地址栏没有改变
  • 一次请求
  • 共享Request域中的数据
  • 可以转发到WEB-INF目录下
  • 不可以访问工程以外的资源

例子如下:通过访问Servlet1然后转发到Servlet2去

public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       // http://localhost:8080/04_Servlet/servlet1?username=abc

        // 1. 获取请求的参数
        String username = req.getParameter("username");
        System.out.println("在Servlet1中获取到的请求参数:"+username);
        // 在Servlet1中获取到的请求参数:abc


        // 2. 把获取到的数据传递,也可以自定义参数传递
//        req.setAttribute("username" , username);
        req.setAttribute("key","我来自Servlet1");


        // 3. 转发
        // 地址必须以 /开头 ,这个地址也是在web.xml中配置对应的你要去的
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
        requestDispatcher.forward(req,resp);
        
        // 或者可以直接这样
        req.getRequestDispatcher("/servlet2").forward(req,resp);

    }
}

对应的web.xml就不展示了,都类似

/**
 * @author MD
 * @create 2020-07-25 8:57
 */
public class Servlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 获取请求的参数
        String username = req.getParameter("username");
        System.out.println("在Servlet2中获取到的请求参数:"+username);//在Servlet2中获取到的请求参数:abc

        // 2. 查看从Servlet1中传递的参数
        Object key = req.getAttribute("key");
        System.out.println("Servlet1中传来的参数:"+key);//Servlet1中传来的参数:我来自Servlet1

        // 3. 处理自己的业务
        System.out.println("正在处理Servlet2的业务");//正在处理Servlet2的业务

    }
}

6. base标签

所以在html文件中,跳转的时候若使用相对路径,指定相对的那个路径

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--
        base标签设置页面相对路径工作时参照的地址
        href 属性就是参数的地址值
    -->
    <!--<base href="http://localhost:8080/04_Servlet/a/b/c.html">-->
    <!--
        也可以这样,但最后的斜杠不能省略
    -->
    <base href="http://localhost:8080/04_Servlet/a/b/">

</head>
<body>
    这是a目录下的b目录下的c.html页面
    <a href="../../index.html">跳到首页</a>
<!--通过定义了base,这个就相当于那个地址的上上层
    http://localhost:8080/04_Servlet/index.html
-->
</body>
</html>

开发中尽量使用绝对路径,实在不行就使用base+相对路径

7. web中 / 斜杠的不同意义

在web中 / 是一种绝对路径

  1. / 斜杠被浏览器解析,得到的地址就是 http://ip:port

    <a href="/">斜杠</a>

  2. / 斜杠 如果被服务器解析,得到的地址是:http://ip:port/工程路径

    • <url-pattern>/servlet1</url-pattern>
    • servletContext.getRealPath(“/”);
    • request.getRequestDispatcher(“/”);
  3. 特殊情况: response.sendRediect(“/”); 把斜杠发送给浏览器解析。得到 http://ip:port/

二、HttpServletResponse 类

1. HttpServletResponse 类的作用

HttpServletResponse 类和 HttpServletRequest 类一样。

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

我们如果需要设置返回给客户端的信息,都可以通过 HttpServletResponse 对象来进行设置

2. 两个输出流

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

3. 如何往客户端回传数据

首先还是先建立一个servlet,配置对应的web.xml

注意中文的乱码情况

package com.md.servlet;
/**
 * @author MD
 * @create 2020-07-25 9:57
 */
public class ResponseIOServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//        System.out.println(resp.getCharacterEncoding());//ISO-8859-1
//
//        // 设置服务器字符集为
//        resp.setCharacterEncoding("UTF-8");
//        // 此时若浏览器没有使用UTF-8中文还是乱码,这个时候需要
//        // 通过设置响应头,使得浏览器也使用UTF-8字符集
//        resp.setHeader("Content-Type","text/html; charset=UTF-8");


        // 或者直接可以这样写,自动设置服务器字符集和浏览器响应头
        // 方法一定要流获取之前先调用,通常放在最上面就行
        resp.setContentType("text/html; charset=UTF-8");


        // 需求:往客户端回传字符串数据

        PrintWriter writer = resp.getWriter();
        writer.write("response");
        writer.write("越过山丘,");
    }
}

4. 请求重定向

请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问。叫请求 重定向(因为之前的地址可能已经被废弃)

请求重定向的特点:

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

例子如下:访问Response1重定向到Response2

/**
 * @author MD
 * @create 2020-07-25 10:15
 */
public class Response1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("Response 1 ");

//        // 设置响应状态码,表示重定向
//        resp.setStatus(302);
//
//        // 设置响应头,说明新的地址,和web.xml里的要对应
//        resp.setHeader("Location","http://localhost:8080/04_Servlet/response2");


        // 推荐使用
        resp.sendRedirect("http://localhost:8080/04_Servlet/response2");
    }
}

//-----------------------------------

public class Response2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Response  2 ");

        resp.getWriter().write("Response2 result !");

    }
}

对应的web.xml

<servlet>
        <servlet-name>Response1</servlet-name>
        <servlet-class>com.md.servlet.Response1</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>Response1</servlet-name>
        <url-pattern>/response1</url-pattern>
    </servlet-mapping>

    <!---->
    <servlet>
        <servlet-name>Response2</servlet-name>
        <servlet-class>com.md.servlet.Response2</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>Response2</servlet-name>
        <url-pattern>/response2</url-pattern>
    </servlet-mapping>
posted @ 2020-07-28 22:05  山丘i  阅读(364)  评论(1编辑  收藏  举报