JavaWeb-Servlet服务连接器(二)

news2024/11/23 16:47:28

目录

Request(获取请求信息)

1.获取请求行内容

2.解决乱码问题

 3.获取请求头部分

4.获取请求体

 5.其他功能


Request(获取请求信息)

工作流程:

1.通过请求的url的资源路径,tomcat会生成相应的Servlet实现对象。

2.tomcat服务器会创建request对象和response对象,request对象接收请求消息数据。

3.tomcat将request和response方法传递给service方法并且调用service方法

4.程序员可以通过request对象获取请求的消息数据,并且设置response的响应数据

5.服务器在给浏览器响应之前获取response

1.获取请求行内容

请求行部分获取请求行内容的方法示例代码返回值
请求方法(Method)getMethod()String method = request.getMethod();"GET"
(重点)请求       URI(URL)getRequestURI()String uri = request.getRequestURI();"/index.html"
协议版本(Protocol)getProtocol()String protocol = request.getProtocol();"HTTP/1.1"
查询字符串(Query String)getQueryString()String queryString = request.getQueryString();null (如果没有查询字符串)
(重点)上下文路径(Context Path)getContextPath()String contextPath = request.getContextPath();"" (如果没有上下文路径,则为空字符串)

 案例代码:

package com.company;


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

@WebServlet("/requestHang")
public class RequestHang extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        获取方法
        String method =req.getMethod();
        System.out.println("使用的方法是"+method);
//       * 获取上下文路径
        String contextPath = req.getContextPath();
        System.out.println("请求的上下文路径是"+contextPath);
//       * 获取URI
        String Uri = req.getRequestURI();
        System.out.println("请求的URI是"+Uri);
//        获取协议版本
        String version = req.getProtocol();
        System.out.println("请求的协议版本是"+version);
//        获取查询字符串
        String string = req.getQueryString();
        System.out.println("请求附带的查询字符串是"+string);
    }

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

        //        获取方法
        String method =req.getMethod();
        System.out.println("使用的方法是"+method);
//       * 获取上下文路径
        String contextPath = req.getContextPath();
        System.out.println("请求的上下文路径是"+contextPath);
//       * 获取URI
        String Uri = req.getRequestURI();
        System.out.println("请求的URI是"+Uri);
//        获取协议版本
        String version = req.getProtocol();
        System.out.println("请求的协议版本是"+version);
//        获取参数
        String username = req.getParameter("username");
        System.out.println("Username is "+username);
    }
}

index.jsp代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>测试发送消息</title>
  </head>
  <body>
    <form action="/com_alphamilk_war_exploded/requestHang" method="get">
      <input name="username">
      <input type="submit" value="提交">
    </form>
  </body>
</html>

通过url访问结果如下:

 可以看到请求出现了乱码,下一步就是解决请求乱码问题.


2.解决乱码问题

1.控制台输出乱码

如果tomcat的版本是在10以下的,用中文可能会出现乱码问题,这里用的是9版本,解决方法:

打开tomcat文件夹找到conf配置文件

配置文件在conf下面,将配置中的字符集改成GBK,修改后的配置如下图:

修改后重新启动结果如下:

 2.post请求方式中参数中文乱码

通过将表单提交方式改为post,再在内容输入中文,通过request方法的getParameter获取参数username

可以看到输出的结果是一串乱码。所以需要进行修补

解决方法:设置流的编码即可

//        设置流的编码
        req.setCharacterEncoding("utf-8");

重启服务器并再次运行:


 3.获取请求头部分

示例:请求头(Request Header):Accept-Language: en-US,en;q=0.9

请求头名称获取请求头值的方法示例代码返回值
Accept-LanguagegetHeader("Accept-Language")String acceptLanguage = request.getHeader("Accept-Language");"en-US,en;q=0.9"
所有请求头名称getHeaderNames()Enumeration<String> headerNames = request.getHeaderNames();包含所有请求头名称的枚举

案例代码:获取所有请求头信息与对应的值

package com.company;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet("/rsHead")
public class RequestHead extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        通过迭代器Enumration遍历请求头
        Enumeration<String> enumeration = req.getHeaderNames();
//        开始遍历
        while (enumeration.hasMoreElements()){
            String name = enumeration.nextElement();
//            找到获取头名称的值
            String value = req.getHeader(name);
            System.out.println(name+" == " +value);
        }
    }
}

案例代码2:设置外部跳转无法访问,只能通过项目内的页面访问资源

通过请求头referer获取访问到当前页面的来源(如果是直接输入地址则referer为空)

首先桌面随便创建一个html文件,然后通过文件的超链接实行跳转到刚才页面

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>冒牌登陆系统</title>
	</head>
	<body>
		<a href="http://localhost:9998/com_alphamilk_war_exploded/rsHead">访问尝试</a>
	</body>
</html>

既然能获取到外部访问源地址,那么现在通过限制请求头的访问,外部地址的访问就会输出非法访问。

服务器Servlet类代码:

package com.company;

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

@WebServlet("/refererTest")
public class rsRefer extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        设置Referer
        String referer = req.getHeader("referer");
//        防盗链机制
        if (referer != null){
            if (referer.contains("/com_alphamilk_war_exploded")){
                System.out.println("正常访问");
            }else {
                System.out.println("非法访问,请从官网处进行访问");
            }
        }
    }
}

重启服务器后,此时再通过随便创建的html文件修改路径后访问得到:


4.获取请求体

只有post请求方式才有请求体

步骤:

1.获取流对象 BufferReader

2.从流对象中获取值 nextline();

常用方法:

方法名作用
getReader()获取请求的输入流,并返回一个BufferedReader对象,用于读取来自客户端的请求数据。
getInputStream()获取请求的输入流,并返回一个ServletInputStream对象,用于直接从客户端请求中读取字节数据。

案例代码:

html代码:

<html>
  <head>
    <title>测试发送消息</title>
  </head>
  <body>
  <form action="http://localhost:9998/com_alphamilk_war_exploded/body" method="post">
    <input type="text" name="username" placeholder="用户名"><br>
    <input type="text" name="password" placeholder="密码"><br>
    <input type="submit">
  </form>
  </body>
</html>

Servlet类代码:

package com.company;

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

@WebServlet("/body")
public class RequestBody extends HttpServlet{
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        BufferedReader reader = req.getReader();
        String line;

        while (reader.readLine()!=null){
            line = reader.readLine();
            System.out.println(line);
        }
    }
}

 通过输入用户名与密码再提交表单

 


 5.其他功能

1.获取参数通用方式(不管post请求还是get请求都可以用、重点):     

方法名作用
getParameter(String name)获取指定名称的请求参数的值。如果有多个同名参数,只返回第一个参数的值。
getParameterValues(String name)获取指定名称的请求参数的所有值。如果参数存在多个值,返回一个包含所有值的字符串数组。
Enumeration<String> getParameterNames()返回一个枚举对象,包含所有请求参数的名称。可以使用该枚举对象遍历所有请求参数的名称。
getParameterMap()返回一个Map对象,其中包含所有的请求参数和它们的值。键是参数名称,值是参数的值(以字符串数组形式)。

案例代码:

 服务器代码

package com.company;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet("/Demo3")
public class ReqOther extends HttpServlet{
    HttpServletRequest req;
    HttpServletResponse resp;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Enumeration<String> enumeration = req.getParameterNames();
        String names;
//        通过迭代器遍历输出所有的参数名与对应的值
        while (enumeration.hasMoreElements()){
            names = enumeration.nextElement();
            System.out.println(names+":"+req.getParameter(names));
        }
    }
//    由于是通用方法,所以如果有post请求则更改为Get请求流程
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        注意post方法会出现中文乱码问题,需要转为utf-8格式编码
        req.setCharacterEncoding("utf-8");
        this.req = req;
        this.resp = resp;
        this.doGet(req, resp);
    }
}

web代码更改路径地址后输入,并提交

 

 当一个表单中出现多个相同的名字时候就需要用getParameterValues或者getParameterMap存放。

2.请求转发(服务器内部资源的跳转方式)

方法名作用
getRequestDispatcher(String path)获取与给定相对路径(path)相关联的 RequestDispatcher 对象,用于在同一个 Web 应用程序内部的不同资源之间进行请求转发。
forward(ServletRequest request, ServletResponse response)将请求和响应对象转发给另一个资源(如 Servlet、JSP 页面),停止当前资源的执行,并将控制权交给目标资源,由目标资源负责生成响应。

案例代码:

创建一个资源类,一个访问类,通过访问类访问资源类

访问类:

package com.company;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

//资源跳转
@WebServlet("/Demo4")
public class rsPatcher extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            System.out.println("3s后进行跳转");
//            3秒后进行跳转
            TimeUnit.SECONDS.sleep(3);
        }catch (Exception e){
            e.printStackTrace();
        }

//        定义要跳转的资源类路径
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/Demo5");
//        进行跳转
        requestDispatcher.forward(req,resp);
    }
}

资源类:

package com.company;

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

@WebServlet("/Demo5")
public class pro extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("我是资源类,我被访问了");
    }
}

输出:

 注意:跳转只能跳转到当前项目中的资源,如果把资源改为外部路径,比如www.baidu.com这样就无法进行跳转。并且转发知识一次的请求

3.共享数据

由于一个类中的数据往往只能该类使用,但是有些资源需要进行多个对象能共享使用,所以引入了共享数据

方法名作用
setAttribute(String name, Object value)将一个数据对象(value)与给定的名称(name)关联起来,将其存储在 ServletContext、HttpSession 或 HttpServletRequest 中,以便多个对象之间共享使用。
getAttribute(String name)根据给定的名称(name),从 ServletContext、HttpSession 或 HttpServletRequest 中获取与之关联的数据对象。
removeAttribute(String name)根据给定的名称(name),从 ServletContext、HttpSession 或 HttpServletRequest 中删除关联的数据对象。

案例代码:

设置一个运输物资类,一个资源类

运输物资类:

package com.company;

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

@WebServlet("/Demo6")
public class Demo6 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        设置共享资源,格式为   键值->对象
        req.setAttribute("msg","物资");

        System.out.println("当前为跳转类进行运输:"+req.getAttribute("msg"));
        RequestDispatcher requestDispatcher  = req.getRequestDispatcher("/Demo7");
//        进行跳转
        requestDispatcher.forward(req,resp);
    }
}

资源类

package com.company;

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

@WebServlet("/Demo7")
public class Demo7 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("资源类获取到"+req.getAttribute("msg"));
    }
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/868784.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iOS 使用build setting中的配置项配置info.plist

如图所示&#xff0c;选中build setting&#xff0c;由于我们这里是想要获取版本号&#xff0c; 所以这里获取current project version 选中info&#xff0c;将bundle version 设置为$&#xff08;CURRENT_PROJECT_VERSION&#xff09;,注意&#xff0c;要使用下划线链接&…

【C++】常用容器-string容器

1.string基本概念 2.string构造函数 #include <iostream> using namespace std;//string容器 void test01() {string s1;//创建空字符串&#xff0c;调用无参构造函数cout << "str1 " << s1 << endl;//什么都不输出const char* str "…

阿里云服务器安装部署Docker使用教程

本文阿里云百科分享如何在云服务ECS实例上&#xff0c;部署并使用Docker。Docker是一款开源的应用容器引擎&#xff0c;具有可移植性、可扩展性、高安全性和可管理性等优势。开发者可将应用程序和依赖项打包到一个可移植的容器中&#xff0c;快速发布到Linux机器上并实现虚拟化…

react学习笔记——4. 虚拟dom中处理动态数据

如下需求 方式1&#xff1a; 直接在ul中使用{data}&#xff0c;是可以遍历数据的&#xff0c;然后如果将data改成下面形式&#xff0c;也是可以实现的。但是如果data是一个对象&#xff0c;则不能便利。 const data [<li>Angular</li>, <li>React</li&g…

c语言——统计分类

我们将一个班的成绩进行分类&#xff0c; 成绩60分以下的为c、成绩61-89分的为b&#xff0c;90分以上的为A //统计分类 /*我们将一个班的成绩进行分类&#xff0c; 成绩60分以下的为c、成绩61-89分的为b&#xff0c;90分以上的为A */ #include<stdio.h> int main() …

MyBatis的XML映射文件

Mybatis的开发有两种方式&#xff1a; 注解 XML配置文件 通过XML配置文件的形式来配置SQL语句&#xff0c;这份儿XML配置文件在MyBatis当中也称为XML映射文件。 导学&#xff1a;在MyBatis当中如何来定义一份儿XML映射文件&#xff1f; 在MyBatis当中&#xff0c;定义XML…

HCIP的BGP基础实验

一、实验需求 除R5的5.5.5.0环回外&#xff0c;其他所有的环回均可互相一访问。 二、实验步骤 1.配置ip 2.建立邻居关系 2.1 R1和R2建立直连的EBGP邻居关系 [r1]bgp 1 [r1-bgp]router-id 1.1.1.1 [r1-bgp]peer 12.1.1.2 as-number 2 要建的话双方都要建下面配置R2 [r2]bgp…

“冰箭卫士·IP发布会”首次亮相第14届海峡两岸(厦门)文博会

2023年8月6日,“冰箭卫士IP发布会”首次亮相海峡两岸文博会思明馆。此次发布会由厦门市文化创意产业协会、厦门理工&#xff08;集美区&#xff09;政产学研基地主办&#xff0c;厦门市文化创意产业协会IP设计研究院、厦门一笔之上文化发展有限公司、冰箭应急安全科技研究院承办…

springboot 设置自定义启动banner背景图 教程

springboot banner Spring Boot中的banner是在应用程序启动时显示的一个ASCII艺术字符或文本。它被用来给用户展示一些关于应用程序的信息&#xff0c;例如名称、版本号或者公司标志等。 使用Spring Boot的默认设置&#xff0c;如果项目中有一个名为“banner.txt”的文件放置…

交换排序——选择排序和冒泡排序的区别是什么?

今天重温一下算法&#xff0c;其实刚开始我觉得冒泡排序和选择排序是一样的&#xff0c;因为他们排序过程中都是通过相邻的数据比较找到最小/最大的数据&#xff0c;通过不断思考和学习才明白&#xff0c;两者还是有区别的。 冒泡排序 概念 冒泡排序(Bubble Sort)&#xff0…

【面试专题】Java核心基础篇①

&#x1f4c3;个人主页&#xff1a;个人主页 &#x1f525;系列专栏&#xff1a;Java面试专题 目录 1.面向对象的三大特性&#xff1f;分别解释下&#xff1f; 2.介绍一下Java的数据类型 3.说一说重写与重载的区别 4.说一说你对static关键字的理解 5.static修饰的类能不能…

ESP-01S Wi-Fi 模块:配置接线

ESP-01S Wi-Fi 模块&#xff1a;配置接线 参考&#xff1a;使用esp-01s与继电器配合实现远程开关灯 (zhihu.com) ESP-01S WiFi 模块 – 配置布线 - 技术探索 (techexplorations.com) 本文提供了将 ESP8266 Wi-Fi 模块与 Arduino Uno 配合使用的分步指南&#xff0c;重点介绍了…

湘大 XTU OJ 1291 Buying Gifts 题解(非常详细):枚举 维护最小值 排序

一、链接 1291 Buying Gifts 二、题目 题目描述 快到年末了&#xff0c;Boss Liu准备在年会上发些礼物&#xff0c;由于不想礼物的价格区别太大&#xff0c;Boss Liu希望最好的礼物与最差的礼物价格相差越小越好。 当然&#xff0c;如果存在相同的选择&#xff0c;Boss Liu…

python num循环怎么从1开始

如何实现python for循环从1开始&#xff1f; range()函数的作用和用法&#xff1a; 编写一个从数值1开始的循环&#xff1a; 执行后得到的结果 其他注意事项

类的派生

目录 1.1 派生方法一(类调用) 1.2 派生方法二(super) python从小白到总裁完整教程目录:https://blog.csdn.net/weixin_67859959/article/details/129328397?spm1001.2014.3001.5502 1.1 派生方法一(类调用) 指名道姓访问某一个类的函数&#xff1a;该方式与继承无关 class …

QGIS3.28的二次开发七:创建地图工具

地图工具是输入设备&#xff08;一般指鼠标与键盘&#xff09;与画布&#xff08;QgsMapCanvas&#xff09;的交互接口。它负责处理所有用户通过输入设备&#xff08;鼠标和键盘&#xff09;和画布互动的操作&#xff0c;例如镜头控制、要素绘制、标识工具等。 QgsMapTool 是地…

知识付费小程序制作

知识付费小程序是一种通过在线平台提供知识付费服务的应用程序。它为知识提供者和知识需求者之间搭建了一个便捷的交流平台&#xff0c;让用户可以通过支付一定费用来获取专业的知识、技能或经验。 这类小程序通常具有以下核心功能&#xff1a; 1. 课程发布与管理&#xff1a…

内网渗透——入门篇(5%)

内网渗透——入门篇&#xff08;5%&#xff09; 参考文章&#xff1a;​​内网渗透学习&#xff08;一&#xff09;内网入门基础 - leviathan123 - 博客园 (cnblogs.com)​​​ 第一部分 内网常用名词及工具介绍 内网也指局域网&#xff0c;是指在某一区域由多台计算机互连而…

SQLServer 实现数据库表复制到另一个数据库_kaic

SQLServer 实现数据库表复制到另一个数据库 一、如果两个数据库在同一台服务器上 1、复制表结构和数据(A->B)&#xff1a; SELECT * INTO DatabaseB.dbo.TableB FROM DatabaseA.dbo.TableA 2、仅仅复制表结构(A->B)&#xff1a; SELECT * INTO DatabaseB.dbo.TableB …

shell和反弹shell

文章目录 是什么&#xff1f;bash是什么&#xff1f;反弹shell 是什么&#xff1f; Shell 是一个用 C 语言编写的程序&#xff0c;它是用户使用 Linux 的桥梁。Shell 既是一种命令语言&#xff0c;又是一种程序设计语言。 Shell 是指一种应用程序&#xff0c;这个应用程序提供了…