Servlet知识进阶

HttpServletRequest 类

作用

HTTP 协议信息解析好封装到Request 对象中。然后传递到service 方法,我们可以通过HttpServletRequest 对象,获取到所有请求的信息。

常用方法

i. getRequestURI() 获取请求的资源路径,和输入的网址是一样的

   String requestURI = req.getRequestURI();
        System.out.println("requestURI = " + requestURI);

ii. getRequestURL() 获取请求的统一资源定位符(绝对路径)

    StringBuffer requestURL = req.getRequestURL();
        System.out.println("requestURL = " + requestURL);

iii. getRemoteHost(),获取客户端的ip 地址,访问者的ip,自己访问自己是0.0.0.0.0.0.1

  String remoteHost = req.getRemoteHost();
        System.out.println("remoteHost = " + remoteHost);

iv. getHeader() 获取请求头

说明:可以通过这个方式获取请求头的参数到我们的服务器端进行查看,没有的数据和没有的响应头我们可以通过postman自定义发送,经常用来做测试。

package com.sun.bean;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.invoke.VarHandle;
@WebServlet("/RequsetServlet")
public class RequsetServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //HTTP 请求发送时,会把保存在该请求域名下的所有 cookie 值一起发送给 web 服务器
        String cookie = req.getHeader("Cookie");
        System.out.println("cookie = " + cookie);
        //表示是否需要持久连接。(HTTP 1.1 默认进行持久连接)
        String connection = req.getHeader("Connection");
        System.out.println("connection = " + connection);
        //请求发送的日期和时间
        String date = req.getHeader("Date");
        System.out.println("date = " + date);
        //自定义请求头
        String qq = req.getHeader("qq");
        System.out.println("qq = " + qq);

    }
}

运行结果

v. getParameter() 获取请求的参数

能接受客户端提交上来的数据,不管是get还是post提交上来的数据,都使用此方法来接受数据,此方法也是我们使用最多的一个方法。

get提交中文数据时,并不会乱码,tomcat6.0的老版本会有get提交乱码的问题,需要在tomcat服务器中的server.xml文件中配置一下,但是现在的8.0以后的版本不会出现get提交乱码。虽然不会出现乱码,但是会存在数据暴露的问题

但是post提交中文时服务器端还是会出现乱码问题。可以通过以下方法进行解决。此方法是在解决接收时候的乱码,接受的时候是乱码,应该在接受之前就设置字符集,而不是接受之后进行设置。

  • 乱码如下
package com.sun.bean;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/RequsetServlet")
public class RequsetServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String pass = req.getParameter("pass");
        System.out.println("username = " + username);
        System.out.println("pass = " + pass);
    }
}

  • 解决方案如下
   req.setCharacterEncoding("utf-8");
        String myname = req.getParameter("myname");
        System.out.println("myname = " + myname);
        String mypass = req.getParameter("mypass");
        System.out.println("mypass = " + mypass);

  • getParameter()方法不足之处

checkbox这个多选表单元素,不能使用getParameter()方法,因为使用这个方法接受到的参数只能接收到第一个参数,后面的接受不到,应该使用getParameterValues()这个方法

vi. getParameterValues() 获取请求的参数(多个值的时候使用)

还是采用的post方法提交,所以需要有设置字符集的过程,此方法可以接收多个参数。

checkbox类型的表单提交元素提交的是value里面的值到服务器

  <label>爱好:</label>
  <input type="checkbox" name="hobby" value="足球">足球
 <input type="checkbox" name="hobby" value="蓝球">蓝球
 <input type="checkbox" name="hobby" value="排球">排球
<input type="checkbox" name="hobby" value="乒乓球">乒乓球
</form>
        req.setCharacterEncoding("utf-8");
        String[] hobbies = req.getParameterValues("hobby");
        Arrays.stream(hobbies).forEach(System.out::println);

  • 关于value的理解,以下拉菜单为例

当我们使用表单提交元素,下拉菜单选择的时候,我们的value如果要写的话,我们大概率是写区号或者ID号,因为我们不写value,服务器端默认获取我们的标签文本内容,当我们写了,它就会获取我们的value里的值。

<form action="RequestAPIServlet" method="post">
  <label>城市:</label><select name="city" multiple>
  <option value="10">黄石</option>
  <option value="20">上海</option>
  <option value="30">北京</option>
</select>
  <input type="submit" value="提交">
</form>
package com.sun.test1;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.stream.Stream;

@WebServlet("/RequestAPIServlet")
public class RequestAPIServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String[] city = req.getParameterValues("city");
        Arrays.stream(city).forEach(System.out::println);
    }
}

vii. getMethod() 获取请求的方式GET 或POST(非重点)

HttpServletResponse 类

解决乱码

@WebServlet("/ResponseIOServlet")
public class ResponseIOServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 它会同时设置服务器和客户端都使用UTF-8 字符集,还设置了响应头
   // 此方法一定要在获取流对象之前调用才有效
		resp.setContentType("text/html; charset=UTF-8");
        PrintWriter writer = resp.getWriter();
        writer.println("我是一个大可爱");
    }
}

请求转发

viii. setAttribute(key, value); 设置域数据

ix. getAttribute(key); 获取域数据

x. getRequestDispatcher() 获取请求转发对象

请求转发

请求转发概念

请求转发(Request Forwarding)是指将一个HTTP请求从一个Servlet转发到另一个Servlet或JSP页面进行处理的操作。请求转发可以实现不同Servlet之间的数据共享和协作,以及将请求的处理过程划分为多个模块。

请求转发的作用

1. 模块化和代码复用:可以将请求处理过程划分为多个模块,每个模块负责不同的功能,提高代码的可维护性和复用性。

2. 数据共享:转发请求时,可以将数据通过请求对象(HttpServletRequest)的属性、请求参数等方式传递给目标Servlet或JSP页面,实现数据的共享。

3. 隐藏URL和保持请求状态:请求转发是在服务器内部进行的,对客户端是透明的,因此可以隐藏目标资源的URL,同时保持请求状态,比如保持用户的登录状态。

在请求转发过程中,设置域数据(Attribute)的作用是将数据存储在请求对象中,以便在转发的目标Servlet或JSP页面中获取和使用这些数据。通过设置域数据,可以实现不同Servlet之间的数据传递和共享。

获取域数据的作用是在目标Servlet或JSP页面中使用转发前的请求对象中存储的数据。通过获取域数据,可以在目标资源中访问和处理之前设置的数据,实现数据的共享和使用。

将请求对象和响应对象传递给`requestDispatcher.forward(req, resp)`方法是为了在请求转发过程中,目标Servlet或JSP页面能够访问和使用请求对象和响应对象,以便处理请求和生成响应。通过传递这两个对象,目标资源可以获取和操作请求参数、请求属性、响应头等信息,以及向客户端发送响应数据。

1. 使用HttpServletRequest对象进行跳转

注意:请求转发必须要以斜杠打头,/ 斜杠表示地址为:http://ip:port/工程名/ , 映射到IDEA 代码的web 目录

请求转发不能站外跳转,只能当前的项目下的资源内进行跳转【请求转发】,可以转发域数据和属性值,也就是说所有数据都可以在转发后的地址获取到,转发时地址栏网站不发生改变。

   package com.sun.bean;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/servlet1")
public class Servlet1 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        System.out.println("在servlet1中查看参数" + username);
        req.setAttribute("key1","柜台1的章");
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
        requestDispatcher.forward(req,resp);
    }
}
package com.sun.bean;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/servlet2")
public class Servlet2 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        Object username = req.getParameter("username");
        System.out.println("servlet2里面查看参数" + username);
        Object key1 = req.getAttribute("key1");
        System.out.println("查看是否有servlet1的章" + key1);
        System.out.println("处理自己的业务");
    }
}

2. 使用 HttpServletResponse对象进行重定向跳转

重定向跳转,也具备跳转能力,但是属性值和域数据获取不到,但它可以跳转到站外地址,转发时地址栏网站发生变化。无须使用 /,因为/会被解析成http://localhost:8088:

跳转到站外资源

采取的是绝对路径的重定向方式

//跳转到站外资源
        resp.sendRedirect("http://www.baidu.com");

跳转到站内资源

采用的是相对定位的方式,在当前工程路径下寻找

package com.sun.bean;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/servlet1")
public class Servlet1 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        System.out.println("在servlet1中查看参数" + username);
        req.setAttribute("key1","柜台1的章");
        resp.sendRedirect("servlet2");
    }
}

3. 请求转发和重定向的区别

请求重定向(resp)是客户端行为,web资源收到客户端请求后,通知浏览器去访问另外一个web资源(让客户端请求另外一个url)。不可以携带参数。地址栏会发生变化。

转发请求(req)是服务器行为,web资源收到客户端请求好,通知浏览器去调用另外一个web资源(服务器自己转发到另一个url)。可以携带参数(通过forward方法将req,resp转发至另一个url)。地址栏不会发生变化。

<Base>标签的使用

重定向转发

package com.sun.bean;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/BaseServlet")
public class BaseServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.sendRedirect("pages/myuser.html");
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
我是pages目录下的myuser.html网页
<a href="../pages2/myrole.html">转到myrole.html</a>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
我是pages2目录下的myrole.html网页
</body>
</html>

上述结果是用重定向转发的,地址栏发生改变,通过重定向跳转到myuser.html页面

通过点击a链接跳转到myrole.html页面

请求转发

package com.sun.bean;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/BaseServlet")
public class BaseServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       req.getRequestDispatcher("/pages/myuser.html").forward(req,resp);
    }
}

上述html代码不变的情况下,可以访问到myuser.html网页,但是访问不到myrole网页,因为a链接的地址是返回到上一层目录,在8080端口下找这个文件,所以会出现404错误找不到资源的情况。

通过上述两种方式,我们再一次对重定向转发和请求转发有了认识,但是我们需要了解的是<base>标签,因此,我们可以看到,如果我们想要使用请求转发,又想要使用重定向转发,我们就可以使用<base>标签

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <base href="http://localhost:8080/javaWeb01_war_exploded/">
</head>
<body>
我是pages目录下的myuser.html网页
<a href="pages2/myrole.html">转到myrole.html</a>
</body>
</html>

web 中 /斜杠的不同意义

客户端(浏览器)使用/它会解析成http://ip:port

服务器端 使用/它会解析成http://ip:port/工程路径

注:服务器端也例外resp.sendRedirect("/Servlet2");加/一样会解析成http://ip:port

给客户端回传数据

有两种输出流,但是两种流只能使用一个,否则会报异常

解决响应中文乱码问题,常用的方法如下:

package com.sun.bean;

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

@WebServlet("/ResponseAPIServlet")
public class ResponseAPIServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        writer.print("我打印到控制台");
        System.out.println();
    }
}

Servlet进阶知识总结

HttpServletRequest和HttpServletResponse对象

在上一次的基础上,我们对HttpServletRequest和HttpServletResponse对象进行了更精确的讲解,前者是接受来自客户端的请求,然后进行逻辑处理,后者是对结果进行响应。

请求转发是Servlet中的一个重要功能,可以通过HttpServletRequest对象进行请求转发或者HttpServletResponse进行重定向转发,两者有非常大的区别。

路径问题

由于我们前面说到了,我们对加不加工程名或者加不加/有一些困惑,我们提供一个非常简单的方法,在客户端/浏览器直接加上<base>标签,绑定项目工程路径,就可以解决这个问题了,在服务器端,url路径是需要加/的,但是在使用HttpServletResponse对象进行重定向的时候是无须加的,其他情况基本都加上。

乱码问题

当我们使用post提交表单的时候,会出现服务器乱码问题,这个时候我们需要使用HttpServletRequest对象中的方法设置字符集。

 req.setCharacterEncoding("utf-8");

当我们给客户端进行回传数据的时候,会出现客户端乱码问题,这个时候我们需要使用HttpServletResponse对象中的方法设置字符集,我只介绍常用的方法

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

注:上述两种方法我们需要在获取数据或者写数据之前就设置

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

媪姝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值