首页 > 其他分享 >day16-Servlet05

day16-Servlet05

时间:2022-11-12 22:46:18浏览次数:55  
标签:请求 writer request day16 Servlet05 servlet response String

Servlet05

14.HttpServletRequest

  1. HttpServletRequest对象代表客户端的请求
  2. 当 客户端/浏览器 通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中
  3. 通过这个对象的方法,可以获取客户端的信息
  • HttpServletRequest类图
image-20221112160803071

image-20221112161006386 image-20221112161332903

14.1HttpServletRequest常用方法

  1. getRequestURI():获取请求的资源路径

    http://localhost:8080/servlet/loginServlet

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

    http://localhost:8080/servlet/loginServlet

  3. getRemoteHost():获取客户端的主机

  4. getRemoteAddr():获取客户端的ip

  5. getHeader():获取请求头

  6. getParameter():获取请求的参数

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

  8. getMethod():获取请求的方式get或post

  9. setAttribute(key,value):设置域数据

  10. getAttribute(key):获取域数据

  11. getRequestDispatcher():获取请求转发对象(请求转发的核心对象)

14.2HttpServletRequest应用实例

需求:在一个表单提交数据给Servlet,在该Servlet中通过HttpServletRequest对象获取相关数据

package com.li.servlet.request;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "HttpServletRequestMethods", value = "/requestMethods")
public class HttpServletRequestMethods extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //这里我们使用request对象,获取表单提交的各种数据
        //System.out.println("HttpServletRequestMethods doPost()被调用...");

        //1.获取和http请求头相关的信息
        System.out.println("请求的资源URI= " + request.getRequestURI());
        System.out.println("请求的统一资源定位符(绝对路径)URL= " + request.getRequestURL());
        System.out.println("请求的客户端ip地址= " + request.getRemoteAddr());
        /*
        getRemoteAddr()应用:发现某个ip在10s内访问的次数超过100次,就封ip
        实现思路:1用一个集合concurrentHashMap[k=ip v=访问次数] 2启动线程定时扫描 3做出相应处理
        */
        //如果我们希望得到请求的头的相关信息,可以直接使用request.getHeader("请求头字段名")
        System.out.println("http请求头HOST= " + request.getHeader("Host"));
        System.out.println("该请求发起的地址是= " + request.getHeader("Referer"));
        //请获取访问网站的浏览器是什么?
        String userAgent = request.getHeader("User-Agent");
        //User-Agent= Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0
        String[] s = userAgent.split(" ");//使用空格分割
        //取最后一个字符,再用 /分割,取第一个字符
        System.out.println("浏览器的种类= " + s[s.length - 1].split("\\/")[0]);
        System.out.println("http请求方式= " + request.getMethod());

        //2.获取和请求参数相关的信息,要去在返回数据前获取参数
        //username=&pwd=&hobby=lb&hobby=cc
        //2.1获取表单的数据[单个数据]
        request.setCharacterEncoding("utf-8");
        String username = request.getParameter("username");
        String pwd = request.getParameter("pwd");
        //2.2获取表单一组数据[多个数据]
        String[] hobbies = request.getParameterValues("hobby");
        System.out.println("username= " + username);
        System.out.println("pwd= " + pwd);
        //增强for循环的快捷键 iter->回车即可
        for (String hobby : hobbies) {
            System.out.println("hobby= " + hobby);
        }
        //推而广之,如果是单选,下拉框等,获取数据的方法大同小异
    }
}

html页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册</title>
</head>
<body>
<h1>注册用户</h1>
<!--注意:这里的requestMethods不是你的类名,是你在web.xml里面(或者注解里面)配置的<url-pattern>-->
<form action="http://localhost:8080/servlet_demo/requestMethods" method="post">
    u:<input type="text" name="username"/><br/><br/>
    p:<input type="password" name="pwd"/><br/><br/>
    选择你最喜欢的三国人物:
    <input type="checkbox" name="hobby" value="lb">刘备
    <input type="checkbox" name="hobby" value="cc">曹操
    <input type="checkbox" name="hobby" value="sq">孙权<br/><br/>
    <input type="submit" value="注册用户">
</form>
</body>
</html>

浏览器中访问html页面,输入数据,点击注册:

image-20221112173741298

后台输出如下:

image-20221112174008561

14.3HttpServletRequest注意事项和细节

  1. 获取doPost参数中文乱码解决方法,设置编码类型request.setCharacterEncoding("UTF-8");

    注意要写在获取参数之前:

    image-20221112174621994
  2. 注意:如果通过PrintWriter writer,有返回数据给浏览器,建议将获取参数的代码写在writer.print()之前,否则可能获取不到参数值(post)

  3. 处理http响应数中文乱码问题

    image-20221112175013837
  4. 再次理解HTTP协议响应Content-Type的含义,比如text/html,text/plain,application/x-tar

    Content-Type表示返回的数据类型,浏览器会根据这个类型来解析数据,详见HTTP协议MIME类型

14.4请求转发

14.4.1为什么需要请求转发

  1. 目前我们学习的都是一次请求,对应一个Servlet

    image-20221112181819875
  2. 在实际的开发中,往往业务比较复杂,需要在一次请求中,使用到多个Servlet完成一个任务(Servlet链,流水作业)

    image-20221112182014390

14.4.2请求转发说明

  1. 实现请求转发:请求转发指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理

  2. HttpServletRequest对象(也叫request对象)提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发

  3. request对象同时也是一个域对象,开发人员通过request对象在实现转发时,把数据通过request对象带给其他web资源处理

    • setAttribute方法
    • getAttribute方法
    • removeAttribute方法
    • getAttributeNames方法

14.4.3请求转发应用实例

例子

需求:浏览器在某html页面输入数据,checkServlet根据该数据对进行操作,如果输入的数据为“tom”,就将其设置为“管理员”,如果不是,就设置为“普通用户”,由managerServlet向服务器返回数据

image-20221112192943227

CheckServlet:

package com.li.servlet.request;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(urlPatterns = {"/checkServlet"})
public class CheckServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("CheckServlet doPost()被调用...");

        //根据用户名来确定该用户是什么身份
        String username = request.getParameter("username");
        //注意:如果是同一个request对象(请求转发),那么可以在不同的Servlet中使用getParameter取出该参数
        if ("tom".equals(username)) {
            //分配权限
            //request对象是一个域对象,通过request对象,在实现转发时,
            // 把数据通过request对象带给其他web资源处理
            request.setAttribute("role", "管理员");//k-v
        } else {
            request.setAttribute("role", "普通用户");//k-v
        }

        //获取分发器
        /**
         * 1. /managerServlet写的是想转发的Servlet的url-pattern
         * 2. / 会被解析成 /servlet_demo
         *      因此请求转发是不可能转发到外网去的
         * 3.forward(request,response)表示把当前的request和response对象传递给下一个Servlet使用,
         *      保证了下一个Servlet和当前的Servlet使用的是同一个request和response对象
         */
        RequestDispatcher requestDispatcher =
                request.getRequestDispatcher("/managerServlet");
        requestDispatcher.forward(request, response);

    }
}

ManagerServlet:

package com.li.servlet.request;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(urlPatterns = {"/managerServlet"})
public class ManagerServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("ManagerServlet doPost()被调用...");

        //因为是同一个request对象,因此可以用request.getParameter("username")获取username
        String username = request.getParameter("username");
        String role = (String) request.getAttribute("role");//k-v
        //输出信息
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.print("用户名:" + username + "<br/>");
        writer.print("role:" + role);
        writer.flush();
        writer.close();
    }
}

login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<form action="http://localhost:8080/servlet_demo/checkServlet" method="post">
    u:<input type="text" name="username"><br/>
    <input type="submit" value="登录">
</form>
</body>
</html>

redeployTomcat,在浏览器中访问http://localhost:8080/servlet_demo/login.html,输入数据,点击登录,可以看到地址栏变为http://localhost:8080/servlet_demo/checkServlet,但没有变为managerServlet(地址会保留在第一个Servlet的URL)

image-20221112202633137 image-20221112202743178

image-20221112202907968 image-20221112202925282

14.4.4请求转发注意细节

  1. 浏览器地址不会变化(地址会保留在第一个Servlet的URL)

  2. 在同一次HTTP请求中,进行多次转发,仍然是一次HTTP请求

  3. 在同一次HTTP请求中,进行多次转发,多个Servlet可以共享request域/对象的数据,即request域/对象的数据(参数,属性)的作用域,是在一次HTTP请求有效

    因为是同一个request对象(数据上来讲)

  4. 可以转发到WEB-INF目录下

  5. 不能访问当前WEB工程外的资源

  6. 因为浏览器地址栏会停留在第一个Servlet,如果你刷新页面,会再次发出请求(并且会带数据)。

    所以在支付页面情况下,不要使用请求转发,否则会造成重复支付 [解决方案可以使用重定向]

image-20221112205005615

14.5习题

14.5.1习题一

通过HttpServletRequest对象获取到访问服务的的浏览器名称

通过字符串分割,14.2已完成

14.5.2习题二

请想办法获取到 JSESSIONID的值

image-20221112180402215

//获取 JSESSIONID的值
String cookie = request.getHeader("Cookie");
String[] s1 = cookie.split(";");
String[] strings = s1[0].split("=");
System.out.println("JSESSIONID的值= "+strings[1]);
image-20221112181501739

14.5.3习题三

下面是一个表单,完成如下功能

(1)编写一个RegisterServlet,能够接收到提交的各种数据,并获取浏览器所在电脑的操作系统和位数

(2)并把接收到的数据返回给浏览器显示

(3)注意处理中文乱码问题

(4)暂不处理文件提交

image-20221112205321403

RegisterServlet:

package com.li.servlet.request.homework;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(urlPatterns = {"/registerServlet"})
public class RegisterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取表单提交的数据

        //先设置编码类型
        request.setCharacterEncoding("utf-8");
        //单个数据使用 getParameter
        String username = request.getParameter("username");
        String pwd = request.getParameter("pwd");
        String pwd2 = request.getParameter("pwd2");
        //多个数据使用getParameterValues
        String[] sports = request.getParameterValues("sport");
        String gender = request.getParameter("gender");
        String city = request.getParameter("city");
        String introduce = request.getParameter("introduce");

        //2.获取用户浏览器所在电脑的操作系统和位数
        //Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0
        String User_Agent = request.getHeader("User-Agent");
        String[] s = User_Agent.split(" ");//使用空格分割
        //s[1]="(Windows" 取出索引为1及之后的字符串
        String OS = s[1].substring(1);
        //s[5]=x64;
        String OSNum = s[5].substring(1, 3);

        //3.返回输出
        //设置编码类型
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.print("你的用户名称:" + username + "<br/>");
        writer.print("你的用户密码:" + pwd + "<br/>");
        writer.print("你的确认密码:" + pwd2 + "<br/>");
        writer.print("喜欢的运动:");
        for (String sport : sports) {
            writer.print(sport + " ");
        }
        writer.print("<br/>你的性别:" + gender + "<br/>");
        writer.print("喜欢的城市:" + city + "<br/>");
        writer.print("自我介绍:" + introduce + "<br/>");
        writer.print("电脑操作系统:" + OS + "<br/>");
        writer.print("位数:" + OSNum + "<br/>");
        writer.flush();
        writer.close();
    }
}

register_form.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户注册</title>
</head>
<body>
<form action="http://localhost:8080/servlet_demo/registerServlet" method="post">
    用户注册信息<br/>
    用户名称:<input type="text" name="username"/><br/>
    用户密码:<input type="password" name="pwd"/><br/>
    确认密码:<input type="password" name="pwd2"/><br/>
    请选中你喜欢的运动项目<br/>
    <input type="checkbox" name="sport" value="lq">篮球<br/>
    <input type="checkbox" name="sport" value="zq">足球<br/>
    <input type="checkbox" name="sport" value="sq">手球<br/>
    请选中你的性别<br/>
    <input type="radio" name="gender" value="men">男<br/>
    <input type="radio" name="gender" value="women">女<br/>
    请选中你喜欢的城市
    <select name="city">
        <option>--请选中--</option>
        <option value="gz">广州</option>
        <option value="bj">北京</option>
        <option value="sh">上海</option>
    </select><br/>
    自我介绍<textarea name="introduce"></textarea><br/>
    <input type="submit" value="提交">
    <input type="reset" value="重置">
</form>
</body>
</html>

image-20221112224256688 image-20221112224304878

标签:请求,writer,request,day16,Servlet05,servlet,response,String
From: https://www.cnblogs.com/liyuelian/p/16884910.html

相关文章

  • day16 --> (会话技术(Cookie、Session)、JSP入门)
    今日内容:1、会话技术:1.Cookie2.Sessio2、JSP入门学习 会话技术1、会话:一次会话中包含多次请求和响应。一次会话:浏览器第一次给服务器资源发送请求,会话建立,知道有一......
  • day16
    [0344.反转字符串]classSolution{public:voidreverseString(vector<char>&s){intleft=0;intright=s.size()-1;while(le......
  • 牛客java选择题每日打卡Day16
    牛客java选择题每日打卡Day16......
  • 代码随想录Day16
    二叉树的层序遍历:LeetCode102 给你一个二叉树,请你返回其按层序遍历得到的节点值。(即逐层地,从左到右访问所有节点)。  思路:如果我们用树形结构去实现层序遍历,3......
  • day16 运动(上)
    概述:运动(动画),就是操作对应的dom元素发生变化,(这个变化要持续多次(修改样式)),每次间隔的时间是你肉眼察觉不到的(时间比较短).当到达目标位......
  • day16 正则表达式 & 反射 & Java内存模型(JMM)
    day16class1)获取一个类的所有信息(变量、方法、构造方法)2)创建类对象newInstance()Field1)访问变量或给变量赋值Method1)执行具体类对象的指定方法3.Method(获取方法对......
  • 《剑指offer》day16
    把数组排成最小的数题目描述思路本题是遇到的第一道自定义排序的题这类题目关键是要理清排序规则,比如本题中"30"+"3"<"3"+"30",所以"30"<"3"字符串化+插入排序将......
  • java_day16
    Java基础Java集合框架Map接口用于存储任意键值对key-value键:无序、无下标、不允许重复值:无序、无下标、运行重复方法put(key,value)将对象存入到集合中,关联键......
  • day16异常以及生成器
    目录今日内容详细异常常见类型异常处理语法结构异常处理补充异常处理实战应用生成器对象课堂练习yield冷门用法生成器表达式今日内容详细异常常见类型AttributeError......
  • Python学习路程——Day16
    Python学习路程——Day16异常常见类型'''SyntaxErrorNameErrorIndexErrorKeyErrorIndentationError......'''1、SyntaxError三种SyntaxError:invalidsy......