当前位置: 首页 > news >正文

JavaWeb之HttpServletRequest与HttpServletResponse详解及快递管理系统实践

HttpServletRequest与HttpServletResponse详解及快递管理系统实践

第一章 HttpServletRequest请求对象

1. HttpServletRequest概述

  1. 概述HttpServletRequest extends ServletRequest -> 请求对象(request对象)
  2. 请求方式
    • GET请求:请求参数在浏览器地址栏上,没有请求体
    • POST请求:请求参数在请求体中
  3. 请求参数形式key=value形式,多个参数之间用&链接
  4. 请求路径localhost:8080/web应用名称/资源?key=value&key=value
    • key:页面上的name属性值
    • value:页面上的value属性值

1.1 HttpServletRequest的组成

请求包含请求报文,请求报文由以下部分组成:

  1. 请求行
    • GET请求:请求方式 请求路径?请求参数 协议版本
    • POST请求:请求方式 请求地址 协议版本
  2. 请求头:对服务器解析请求的指导性信息
  3. 请求空行(可忽略)
  4. 请求体
    • GET请求没有请求体
    • POST请求有请求体,包含请求参数

1.2 HttpServletRequest的作用

  1. 获取请求报文中的数据(主要是请求体内容)
  2. 实现请求转发(重定向)
  3. 作为域对象存储数据(请求域)

2. HttpServletRequest获取HTTP请求内容的方法

2.1 获取请求行方法
方法名说明
getMethod()获取请求方式(常用)
getContextPath()获取当前应用上下文路径(在application context中设置的名字)(常用,四个方法中的重点)
getRequestURI()获取请求地址,不带主机名
getRequestURL()获取请求地址,带主机名
@WebServlet("/request1")
public class Request1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 获取请求方式String method = request.getMethod();System.out.println(method);System.out.println("======================");// 获取web应用名称String contextPath = request.getContextPath();System.out.println(contextPath);System.out.println("=======================");// 获取请求地址,不带主机名String requestURI = request.getRequestURI();System.out.println(requestURI);System.out.println("=======================");// 获取请求地址,带主机名StringBuffer requestURL = request.getRequestURL();System.out.println(requestURL);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}

测试页面:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>首页1</title>
</head>
<body>
<form action="/day05_request_response/request1" method="post">用户名:<input type="text" name="username"/><br/>&nbsp;&nbsp;&nbsp;码:<input type="password" name="password"/><br/><input type="submit" value="登录">
</form>
</body>
</html>
2.2 获取请求头信息方法
方法名说明
getHeader(String name)根据请求的key获取对应的value
@WebServlet("/Servlet2")
public class Servlet2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String host = req.getHeader("Host");System.out.println(host);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp);}
}

常见请求头说明:

  • Accept:浏览器能够处理的内容类型
  • Accept-Charset:浏览器能够显示的字符集
  • Accept-Encoding:浏览器能够处理的压缩编码
  • Accept-Language:浏览器当前设置的语言
  • Connection:浏览器与服务器之间连接的类型
  • Cookie:当前页面设置的任何Cookie
  • Host:发出请求的页面所在的域
  • Referer:发出请求的页面的URL
  • User-Agent:浏览器的用户代理字符串
2.3 获取请求体中的请求参数(重点)
  1. 请求参数位置

    • GET:请求参数在地址栏上 -> localhost:8080/web应用名称/资源?key=value&key=value
    • POST:请求参数在请求体中,格式为key=value&key=value
  2. 参数说明

    • key:页面上的name属性值
    • value:页面上的value属性值
    • 实际需要获取的是value值,通过key获取
方法名返回值类型方法描述
request.getParameter(“请求参数的name属性名”)String根据提交参数的name获取对应的value
request.getParameterValues(“请求参数的name属性名”)String[]根据提交参数的name获取多个value
request.getParameterMap()Map<String,String[]>获取提交请求的所有参数,以键值对的方式存到map中

示例页面:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>获取提交参数</title>
</head>
<body><a href="/day05_request_response/request3?username=tom&password=111">访问request3</a><br/>
<hr color="red" size="2">
<form action="/day05_request_response/request3" method="get">用户名<input type="text" name="username"/><br/>密码<input type="text" name="password"/><br/>昵称<input type="text" name="nickname"/><br/>邮箱<input type="text" name="email"/><br/><!--复选框-->兴趣爱好<input type="checkbox" name="hobby" value="basketball"/>篮球<input type="checkbox" name="hobby" value="football"/>足球<input type="checkbox" name="hobby" value="yumaoball"/>羽毛球<input type="checkbox" name="hobby" value="pingpangball"/>乒乓球<br/><button type="submit">提交</button>
</form>
</body>
</html>

处理代码:

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;@WebServlet("/request3")
public class request3 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username = req.getParameter("username");String password = req.getParameter("password");System.out.println("username:"+username+"password:"+password);System.out.println("=======================");String username1 = req.getParameter("username");String password1 = req.getParameter("password");String nickname = req.getParameter("nickname");String email = req.getParameter("email");System.out.println(username1+"..."+password1+"..."+nickname+"..."+email);System.out.println("==============");// 获取多个参数值String[] hobbies = req.getParameterValues("hobby");System.out.println("hobbies:"+ Arrays.toString(hobbies));System.out.println("===============");// 获取所有参数的Map集合Map<String, String[]> parameterMap = req.getParameterMap();Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();for (Map.Entry<String, String[]> entry : entries) {System.out.println(entry.getKey()+":"+Arrays.toString(entry.getValue()));}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp);}
}
2.4 解决获取请求参数乱码
2.4.1 乱码原因
  1. 编码和解码遵循的编码规则不一样
  2. 与tomcat的解码方式相关:
    • tomcat10采用UTF-8编码
    • tomcat获取请求参数主要是解析url中的参数
  3. tomcat8及以上版本优化:
    • GET请求:参数在url上,直接用UTF-8解析
    • POST请求:参数在请求体中,tomcat默认编码可能导致中文乱码
2.4.2 解决方法(主要针对post请求)
方法名说明
request.setCharacterEncoding(“UTF-8”)将获取到的请求参数设置为utf-8格式
@WebServlet("/request4")
public class Request4 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 处理请求中文乱码request.setCharacterEncoding("utf-8");String username = request.getParameter("username");String password = request.getParameter("password");System.out.println(username);System.out.println(password);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}

测试页面:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>首页request4</title>
</head>
<body>
<form action="/day05_request_response/request4" method="post">用户名:<input type="text" name="username"/><br/>&nbsp;&nbsp;&nbsp;码:<input type="password" name="password"/><br/><input type="submit" value="登录">
</form>
</body>
</html>

3. 请求转发

3.1 什么是请求转发
  1. 概述:通过项目下的一个资源将请求转发到另外一个该项目资源下的技术
  2. 特点
    • 整个过程只产生一个请求,浏览器地址栏不会变化
    • 是服务器内部行为,浏览器不知情
    • 在同一个请求中完成,只有一次请求
3.2 请求转发方法
方法名说明
RequestDispacher getRequestDispacher(String path)获取请求转发器对象
参数:path指目标资源路径
1. 转发到servlet:写servlet对应的url-pattern
2. 转发到页面:写页面路径
forward(request对象,response对象)实现请求转发,是RequestDispacher对象的方法
3.3 请求转发演示
// 浏览器访问request4,转发到request5或页面
@WebServlet("/request4")
public class request4 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 请求转发到request5// req.getRequestDispatcher("/request5").forward(req,resp);// 请求转发到WEB-INF下的index4.htmlreq.getRequestDispatcher("/WEB-INF/index.html").forward(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}

目标Servlet:

@WebServlet("/request5")
public class request5 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().write("I am LiuDaDan");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp);}
}
3.4 总结
  1. 请求转发是服务器内部行为,浏览器只发一次请求
  2. 只能转发到当前web应用下的资源
  3. 地址栏不会变化
  4. 转发涉及的资源属于同一个请求

4. HttpServletRequest域对象

  1. 域对象对比
    • ServletContext:代表整个web应用程序,作用范围最大,全应用共享
    • HttpServletRequest域(请求域):存储的数据只能在当前请求中共享,新请求无法获取
4.1 HttpServletRequest域对象方法
方法名说明
setAttribute(String key,Object o)存数据
getAttribute(String key)根据key获取value
removeAttribute(String key)根据key删除value
4.2 演示代码
@WebServlet("/request7")
public class request7 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setAttribute("username","liudadan");// 必须请求转发,因为HttpServletRequest域只在同一请求中有效req.getRequestDispatcher("/request8").forward(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp);}
}
// 在request8中获取request7存储的数据
@WebServlet("/request8")
public class request8 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Object username = req.getAttribute("username");System.out.println("username:"+username);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req,resp);}
}

第二章 HttpServletResponse响应对象

1. HttpServletResponse响应对象介绍

1.1 概念

HttpServletResponse extends ServletResponse

1.2 作用

给浏览器设置响应信息,包括:

  • 响应行
  • 响应头
  • 响应体

2. HttpServletResponse使用

2.1 设置响应状态码(了解)

常见状态码:

  • 200:响应成功
  • 304:缓存
  • 302:重定向
  • 404:找不到资源
  • 500:服务器内部错误
方法名说明
response.setStatus(状态码)设置响应行中的响应状态码
@WebServlet("/response1")
public class Response1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// response.setStatus(404);System.out.println(1/0); // tomcat会默认给出报错信息}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}

响应状态码通常由tomcat自动设置,无需手动干预

2.2 设置响应头(了解)

响应头数据格式:k:v

方法名说明
setHeader(String key,String value)设置响应头的key和value
@WebServlet("/response2")
public class Response2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setHeader("myHeader","taoge"); // 设置响应头}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
2.3 设置响应体(重要)
2.3.1 使用字符输出流响应
方法名说明
PrintWriter getWriter()使用字符流作出响应,需注意中文乱码
@WebServlet("/response3")
public class Response3 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.getWriter().write("<!DOCTYPE html>\n" +"<html lang=\"en\">\n" +"<head>\n" +"    <meta charset=\"UTF-8\">\n" +"    <title>Title</title>\n" +"</head>\n" +"<body>\n" +"   hello,i am taoge,i am 16 years old\n" +"</body>\n" +"</html>");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
2.3.2 解决响应中文乱码
方法名说明
response.setContentType(“text/html;charset=utf-8”)设置响应头,解决中文乱码
@WebServlet("/response4")
public class Response4 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");response.getWriter().write("你好,我是一个大帅哥!");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
2.4 设置浏览器重定向

概述:从web项目资源跳转到另一个资源,浏览器会发起两次请求,是一个新的请求。

方法名说明
response.sendRedirect(“重定向的资源路径”)请求重定向到另外一个资源中去

示例代码:

// 访问response5,重定向到response6
@WebServlet("/response5")
public class Response5 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 重定向到response6,需添加上下文地址response.sendRedirect(request.getContextPath()+"/response6");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}@WebServlet("/response6")
public class Response6 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");response.getWriter().write("你好,我是一个大帅哥!");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
2.5 重定向和请求转发区别
  1. 重定向会由浏览器发起新的请求,请求转发不会
  2. 重定向可以访问任意互联网资源,请求转发只能访问本项目资源
  3. 重定向不能访问本项目WEB-INF内的资源,请求转发可以
  4. 重定向涉及的资源不在同一次请求中,不能使用请求域;请求转发涉及的资源在同一次请求中,可以使用请求域

第三章 MVC模式

1. 为什么需要MVC

直接在Servlet中通过write方法编写页面代码维护性差,需要将视图(页面)单独抽取为View层。但HTML无法展示动态数据,需要引入服务器端动态视图模板技术(如jsp或Thymeleaf)。

2. MVC概念

  1. 定义:web应用程序的开发模式

    • M:Model模型 -> 处理数据
    • V:View视图 -> 页面展示
    • C:Controller控制器 -> 协调调度
  2. 理念:在表现层开发中,将封装数据的模型、显示界面的视图、协调调度的控制器分开。

  3. 好处

    • 实现组件解耦
    • 便于单独维护
    • 方便前后端工程师协作

3. MVC和三层架构之间关系

MVC属于表现层的设计模式,与三层架构(表现层、业务逻辑层、数据访问层)相辅相成,共同构成完整的应用程序架构。

第四章 快递管理系统第二期

1. 准备工作

1.1 数据库准备

导入资料中的deliver.sql到数据库

1.2 项目搭建(delivery-system)
1.2.1 创建Javaweb工程(delivery-system)
1.2.2 导入页面

将资料中的页面导入到项目中

1.2.3 修改项目登录页面
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"version="6.0"><!-- 设置登录为欢迎页面 --><welcome-file-list><welcome-file>login.html</welcome-file></welcome-file-list>
</web-app>

改完web.xml后若仍跳转index.html,需清除浏览器缓存(ctrl+shift+delete)

1.2.4 导入数据库相关环境及创建类

导入数据库连接相关的工具类和配置文件

1.2.5 导入MD5加密工具类
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public final class MD5Utils {public static String encrypt(String strSrc) {try {char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8','9', 'a', 'b', 'c', 'd', 'e', 'f' };byte[] bytes = strSrc.getBytes();MessageDigest md = MessageDigest.getInstance("MD5");md.update(bytes);bytes = md.digest();int j = bytes.length;char[] chars = new char[j * 2];int k = 0;for (int i = 0; i < bytes.length; i++) {byte b = bytes[i];chars[k++] = hexChars[b >>> 4 & 0xf];chars[k++] = hexChars[b & 0xf];}return new String(chars);} catch (NoSuchAlgorithmException e) {e.printStackTrace();throw new RuntimeException("MD5加密出错!!!");}}
}
1.2.6 导入pojo类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;@AllArgsConstructor
@NoArgsConstructor
@Data
public class SysUser  implements Serializable {private Integer id;private String username;private String password;private String nickname;
}

2. 登录业务代码

2.1 MVC架构模式实现
2.1.1 部署项目

按照标准流程部署web项目

2.1.2 修改login页面表单参数

调整表单的action和参数名,确保与后端接收一致

2.1.3 Controller层
import java.io.*;import com.atguigu.pojo.SysUser;
import com.atguigu.service.UserService;
import com.atguigu.service.impl.UserServiceImpl;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.WebServlet;import java.io.IOException;
import java.sql.SQLException;@WebServlet("/user/login")
public class UserLoginController extends HttpServlet {private UserService userService = new UserServiceImpl();@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {try {// 设置请求参数编码格式request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");// 获取请求参数String username = request.getParameter("username");String password = request.getParameter("password");// 调用service层方法SysUser sysUser = userService.login(username,password);if (sysUser!=null){request.getRequestDispatcher("/index.html").forward(request,response);}else{request.getRequestDispatcher("/login.html").forward(request,response);}} catch (SQLException e) {throw new RuntimeException(e);}}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
2.1.4 Service层

接口:

public interface UserService {SysUser login(String username, String password) throws SQLException;
}    

实现类:

public class UserServiceImpl implements UserService {private UserDao userDao = new UserDaoImpl();@Overridepublic SysUser login(String username, String password) throws SQLException {// 密码加密password = MD5Utils.encrypt(password);// 调用dao层SysUser sysUser = userDao.login(username,password);return sysUser;}
}    
2.1.5 Dao层

接口:

public interface UserDao {SysUser login(String username, String password) throws SQLException;
}    

实现类:

public class UserDaoImpl implements UserDao {private QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());@Overridepublic SysUser login(String username, String password) throws SQLException {String sql = "select id,username,password,nickname from sys_user where username = ? and password = ?";SysUser sysUser = qr.query(sql, new BeanHandler<SysUser>(SysUser.class), username, password);return sysUser;}
}    
2.2 解决转发页面样式丢失问题

修改login.htmlindex.html中的资源路径,添加web应用名称:

<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>快递管理系统</title><meta name="Copyright" content="Douco Design." /><link href="/delivery/css/public.css" rel="stylesheet" type="text/css"><script type="text/javascript" src="/delivery/js/jquery.min.js"></script><script type="text/javascript" src="/delivery/js/global.js"></script>
</head>
http://www.dtcms.com/a/393066.html

相关文章:

  • Git详细介绍
  • 大话计算机网络(上)
  • JVM方法调用机制深度解析:从aload_1到invokevirtual的完整旅程
  • STM32CubeIDE学习——安装
  • 追觅宣布进军手机市场,已经白热化的手机赛道追觅优势何在?
  • AI智能体开发工作流的成功案例分享及思路
  • 【算法基础】String、Hash 与 Stack
  • 使用springboot开发一个宿舍管理系统练习项目
  • 像素版推箱子游戏
  • 2025年CSP-J认证 普及组初赛真题解析 CCF信息学奥赛C++ 中小学初级组 第一轮真题-选择题解析
  • 【精品资料鉴赏】121页可编辑PPT详解医药集团合规管控规划方案
  • Linux用户权限与进程管理深度解析
  • [数据结构] 反射,枚举与lambda表达式
  • 奇异值:数据科学的数学基石与应用核心
  • Python 2025:安全编程与漏洞防范实战指南
  • ​​[硬件电路-286]:高速轨到轨比较器TLV3603DCKR 功能概述与管脚定义
  • CAR 细胞疗法:破解自身免疫性疾病的 “免疫纠错” 新路径
  • FreeRTOS实战指南 — 5 多任务系统实现流程
  • `css`使单词保持连贯的两种方法
  • 【Vue3 ✨】Vue3 入门之旅 · 第三篇:模板语法与数据绑定
  • 分类预测 | Matlab实现PCA-BP主成分分析结合BP神经网络多特征分类预测
  • 【Linux】进程优先级切换调度
  • Ubuntu24上安装Scrapy框架实战
  • 正向shell,反弹shell学习
  • 一维数组原地更新——力扣119.杨辉三角形II
  • Python语法学习-1
  • Linux基础命令大全
  • 9.21 快速选择
  • 【常见集合】HashMap
  • Docker安装小白教程(阿里yum)