JavaWeb《二》Servlet、Request请求
创始人
2025-05-30 16:41:52
0
🍎道阻且长,行则将至。🍓

本文是javaweb的第二篇,介绍了Servlet,Servlet是JavaWeb最为核心的内容,它是Java提供的一门动态web资源开发技术。概述了Request请求与响应,并且主要分析了Request请求。
上一篇:JavaWeb《一》概念、服务器部署及servlet
下一篇:敬请期待


目录

  • 一、Servlet🍏
    • 1.Servlet的体系结构
    • 2.HttpServlet
    • 3.urlPattern配置
    • 4.XML配置
  • 二、Request🍉
    • 1.request和response
    • 2.request和response对象的使用
    • 3.Request对象
    • 4.POST参数获取
    • 5.GET参数
    • 6.POST&GET参数
  • 三、中文乱码🍍



一、Servlet🍏

Servlet是JavaWeb最为核心的内容,它是Java提供的一门动态web资源开发技术。使用Servlet就可以实现,根据不同的登录用户在页面上动态显示不同内容。上一篇通过seevlet的入门案例,实现了浏览器发出访问请求,我们的idea中可以有所表示。

我们编写一个Servlet就必须要实现Servlet接口,重写接口中的5个方法,但是这样是比较麻烦的,这个过程中我们关注的其实只有service方法。

1.Servlet的体系结构

在这里插入图片描述

开发B/S架构的web项目,都是针对HTTP协议,所以我们自定义Servlet可以通过继承HttpServlet来完成。


2.HttpServlet

在上一个基础案例后,继续写一个Servletdemo类继承HttpServlet,重新启动服务器后会自动打包,在浏览器中访问http://localhost:8080/Webapp2_war/demo2

@WebServlet("/demo2")
public class ServletDemo extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//TODO GET 请求方式处理逻辑System.out.println("get...");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//TODO Post 请求方式处理逻辑System.out.println("post...");}
}

浏览器页面因为本来没内容就是空白,刷新一次在控制台就会get。
在这里插入图片描述
而想发送一个post请求servlet,需要使用form表单了。可以直接在webapp下创建一个index.html页面,在里面加入表单使用post方法,设置action/Webapp2_war/demo2和servlet对应),在浏览器页面访问这个页面提交内容就可以看到post了。

发送GET和POST请求的时候,参数的位置不一致,GET请求参数在请求行中,POST请求参数在请求体中,所以HttpServlet会根据请求方式的不同,调用不同的方法。
我们可以打开HttpServlet看到他实现上层的GenericServletservice方法,然后调用自己的service

    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {HttpServletRequest request = (HttpServletRequest)req;HttpServletResponse response = (HttpServletResponse)res;this.service(request, response);} else {throw new ServletException("non-HTTP request or response");}}

继续看到service,首先获取到了请求的方法,然后判断类型:
在这里插入图片描述


3.urlPattern配置

Servlet类编写好后,要想被访问到,就需要配置其访问路径:urlPattern
urlPattern可以配置多个,配置规则也有多种

  • 在此前我们一个Servlet只写了一个访问路径,其实它是可以配置多个urlPattern的。
    只需要参数:urlPatterns = {“/demo1”,“/demo2”},就可以输入不同链接来访问servlet了。
    注意这个路径是不能和别人重复了,会报错:
    Caused by: java.lang.IllegalArgumentException: 名为 [ServletDemo1]和 [ServletDemo2] 的servlet不能映射为一个url模式(url-pattern) [/demo1]

  • 精确匹配
    我们此前使用的就是精确匹配,服务路径和配置一致。

  • 目录匹配
    配置为:/user/*
    访问:***/user/aaa***/user/aab或者***/user/abc都可以,就是说配置中的*可以任意替代。
    该方法的优先级低于精确匹配

  • 扩展名匹配
    配置为:*.do
    访问:***/aaa.do或者***/abc.do都可以,配置中的*可以任意替代。

  • 任意匹配
    配置为://*
    访问:任意都可以。但是会导致你的静态资源html都不能访问了。


4.XML配置

在Servlet的配置中我们都使用的是@WebServlet注解方法,这个是Servlet 3.0版本后开始支持注解配置,3.0版本前只支持XML配置文件的配置方法。所以可以了解一下xml配置。
xml配置方法完成Servlet类就不需要加注解了,然后打开WEB_INF里面的web.xml,

    demo3Webapp2_war.ServletDemo3demo3/demo3


二、Request🍉

在前面的Servlet或者HttpServlet中,我们都可以看到:ServletRequest req, ServletResponse res参数,这两个参数的作用是什么?

1.request和response

Request是请求对象,Response是响应对象。

  • request:获取请求数据
    • 浏览器会发送HTTP请求到后台服务器;
    • HTTP的请求中会包含很多请求数据:请求行、请求头、请求体;
    • 后台服务器会对HTTP请求中的数据进行解析并把解析结果存入到一个对象中,即request对象,我们可以从request对象中获取请求的相关参数;
    • 获取到数据后就可以继续后续的业务,比如获取用户名和密码就可以实现登录操作的相关业务。
  • response:设置响应数据
    • 业务处理完后,后台就需要给前端返回业务处理的结果即响应数据;
    • 把响应数据封装到response对象中;
    • 后台服务器会解析response对象,按照[响应行+响应头+响应体]格式拼接结果;
    • 浏览器最终解析结果,把内容展示在浏览器给用户浏览。

2.request和response对象的使用

我们再写一个Servlet类,在get里面获取请求数据和设置响应数据。

@WebServlet("/demo8")
public class ServletDemo3 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//使用request对象 获取请求数据String name = request.getParameter("name");//使用response对象 设置响应数据response.setHeader("content-type","text/html;charset=utf-8");response.getWriter().write("

"+name+",欢迎您!

");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("Post...");} }

访问的时候在链接后面加上?name=zhangsan,因为这就是直接的get方法。
在这里插入图片描述

当然你也可以重写Post方法,然后在静态页面用post表单传入数据。


3.Request对象

HTTP请求数据总共分为三部分内容,分别是请求行请求头请求体,这三部分内容的数据该如何获取。

  • 获取请求行数据
    请求行包含三块内容,分别是请求方式请求资源路径HTTP协议及版本
    这三部分内容,request对象都提供了对应的API方法来获取:
获取的内容方法
请求方式String getMethod()
虚拟目录(项目访问路径)String getContextPath()
URL(统一资源定位符)StringBuffer getRequestURL()
URI(统一资源标识符)String getRequestURI()
请求参数String getQueryString()

get一下:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// String getMethod():获取请求方式: GETString method = req.getMethod();System.out.println(method);//GET// String getContextPath():获取虚拟目录(项目访问路径):/request-demoString contextPath = req.getContextPath();System.out.println(contextPath);// StringBuffer getRequestURL(): 获取URL(统一资源定位符):http://localhost:8080/request-demo/req1StringBuffer url = req.getRequestURL();System.out.println(url.toString());// String getRequestURI():获取URI(统一资源标识符): /request-demo/req1String uri = req.getRequestURI();System.out.println(uri);// String getQueryString():获取请求参数(GET方式): username=zhangsanString queryString = req.getQueryString();System.out.println(queryString);
}
  • 获取请求头数据
    请求头的数据,格式为key: value,根据请求头名称获取对应值的方法为:
String getHeader(String name)
  • 获取请求体数据
    GET请求没有请求体,所以使用请求体需要把请求方式变更为POST。对于请求体中的数据,Request对象提供了如下两种方式来获取其中的数据,分别是:
    • 1、ServletInputStream getInputStream()
      获取字节输入流,如果前端发送的是字节数据,比如传递的是文件数据,则使用该方法;

    • 2、BufferedReader getReader()
      获取字符输入流,如果前端发送的是纯文本数据,则使用该方法。


4.POST参数获取

参数在请求体中,请求参数获取BufferedReader getReader()

1.准备一个静态页面,添加form表单发送post请求

在这里插入图片描述

2.doPost方法获取数据

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取post 请求体:请求参数//1. 获取字符输入流BufferedReader br = req.getReader();//2. 读取数据String line = br.readLine();System.out.println(line);
}

点击页面的提交按钮后,就可以在控制台看到前端所发送的请求数据。

3.post具有多个值的参数
如下的hobby就具有两个参数:



swimrun

request对象为我们提供了如下方法,后面还会提到这里:

  • 获取所有参数Map集合
    Map getParameterMap()
  • 根据名称获取参数值(数组)
    String[] getParameterValues(String name)
  • 根据名称获取参数值(单个值)
    String getParameter(String name)

例如:

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("post~");Map map = req.getParameterMap();for (String key : map.keySet()) {System.out.print(key + ":");String[] values = map.get(key);for (String value : values) {System.out.print(value + " ");}System.out.println();}
}

在这里插入图片描述

5.GET参数

前面我们进行了POSTt的请求参数获取(BufferedReader getReader()),GET请求和POST请求获取请求参数的方式不一样,GET请求的请求参数在请求行中,在获取请求参数这块该如何实现呢》》》String getQueryString();

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String result = req.getQueryString();System.out.println(result);
}

6.POST&GET参数

GET请求方式和POST请求方式区别主要在于获取请求参数的方式不一样,可以采取一种统一获取请求参数的方式,从而统一doGet和doPost方法内的代码。

  • 1、根据请求方式的不同分别获取请求参数值
    写到一起,然后使用request的getMethod()来获取请求方式。
public class RequestDemo1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取请求方式String method = req.getMethod();//获取请求参数String params = "";if("GET".equals(method)){params = req.getQueryString();}else if("POST".equals(method)){BufferedReader reader = req.getReader();params = reader.readLine();}System.out.println(params);      }@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req,resp);}
}

  • 2、request对象为我们提供了一些方法:前面提到☝
方法M
获取所有参数Map集合Map getParameterMap()
根据名称获取参数值(数组)String[] getParameterValues(String name)
根据名称获取参数值(单个值)String getParameter(String name)

request对象已经将上述获取请求参数的方法进行了封装,并且request提供的方法实现的功能更强大,以后只需要调用request提供的方法即可:

public class RequestDemo1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//采用request提供的获取请求参数的通用方式来获取请求参数//编写其他的业务代码...}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req,resp);}
}

三、中文乱码🍍

提交中文内容可能在控制台出现乱码

浏览器把中文参数按照UTF-8进行URL编码,Tomcat对获取到的内容进行了ISO-8859-1的URL解码,编解码不一致因此出现乱码。
在这里插入图片描述

在这里插入图片描述

  • POST请求
    设置输入流的编码 : request.setCharacterEncoding("UTF-8");
  • GET/POST通用
    需要先解码,再编码 :new String(username.getBytes("ISO-8859-1"),"UTF-8");
    POST请求参数一般都会比较多,采用这种方式解决乱码起来比较麻烦,所以POST请求建议使用设置编码的方式进行。

Tomcat8.0之后,已将GET请求乱码问题解决,设置默认的解码方式为UTF-8。

/*** 中文乱码问题解决方案*/
@WebServlet("/req4")
public class RequestDemo4 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1. 解决乱码:POST,getReader()//request.setCharacterEncoding("UTF-8");//设置字符输入流的编码//2. 获取usernameString username = request.getParameter("username");System.out.println("解决乱码前:"+username);//3. GET,获取参数的方式:getQueryString// 乱码原因:tomcat进行URL解码,默认的字符集ISO-8859-1/* //3.1 先对乱码数据进行编码:转为字节数组byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);//3.2 字节数组解码username = new String(bytes, StandardCharsets.UTF_8);*/username  = new String(username.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);System.out.println("解决乱码后:"+username);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}
}

解决:
在这里插入图片描述
在这里插入图片描述

跳到第一页☝


☕物有本末,事有终始,知所先后。🍭

🍎☝☝☝☝☝我的CSDN☝☝☝☝☝☝🍓

相关内容

热门资讯

软件导播台多画面切换支持多人连... 阿酷TONY / 原创 / 2023-3-21 / 轻导播台软件实测导播台文章,我以前...
【Java学习笔记】38.Ja... Java 发送邮件 使用Java应用程序发送 E-mail 十分简单,但是首先你应该在...
从一个Spring动态代理Bu... 文章目录Bug复现结论@PostConstruct的在Bean的生命周期的哪一步一般代理类的...
Java函数式编程 概念:面向对象思想关注用什么对象完成什么事情。而函数式编程思想就类似数学中的函数。它关...
Redis KV如何存储 一、KV如何存储? 为了实现从键到值的快速访问,Redis 使用了一个哈...
Java if else分支结... Java 支持两种选择语句:if 语句和 switch 语句。其中 if 语句使用布尔...
与会人士高度评价国际调解院 点... 与会人士高度评价国际调解院 点赞国际法治领域创新之举 新华社香港5月30日电 题:与会人士高度评价...
还在stream中使用peek... 文章目录简介peek的定义和基本使用peek的流式处理Stream的懒执行策略peek为什么只被推荐...
C++析构函数详解 创建对象时系统会自动调用构造函数进行初始化工作,同样,销毁对象时系统也会...
Apache Paimon 二、典型实践应用 2.1)离线数仓加速 离线数仓加速可以说是一个非常典型的应用场景了 ...