JavaWeb04-Request,Response

目录

一、Request(请求)

1.作用

2.继承体系

3.获取请求数据

(1)请求行

(2)请求头

(3)请求体(POST)

(5)Request通用方式获取请求参数

4.Servlet模板

5.中文数据乱码解决

6.请求转发

二、Response(响应)

1.作用

2.继承体系

3.设置响应数据

(1)响应行

(2)响应头

(3)响应体

4.重定向

5.响应字符数据

6.响应字节数据

三、杂项问题

1.路径问题

2.插件推荐


一、Request(请求)

1.作用

获取请求数据

2.继承体系

  • Tomcat需要解析请求数据,封装为request对象并且创建request对象传递到service方法中

  • 要使用request对象,可查阅JavaEE API文档的HttpServletRequest接口

3.获取请求数据

(1)请求行
方法名 说明
String getMethod() 获取请求方式:GET/POST...
String getContextPath() 动态获取虚拟目录(项目访问路径):/request-demo
StringBuffer getRequestURL() 动态获取URL(统一资源定位符):http://localhost:8080/request-demo/req1
String getRequestURl() 动态获取URI(统一资源标识符): /request-demo/req1
String getQueryString() 获取请求参数(GET方式):username=zhangsan&password=123
java 复制代码
    //测试网址:http://localhost:8080/tomcat_demo_war/request?username=zhangsan&password=123
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //
        final String reqMethod = req.getMethod();
        final String contextPath = req.getContextPath();
        final StringBuffer requestURL = req.getRequestURL();
        final String requestURI = req.getRequestURI();
        //username=zhangsan&password=123
        final String queryString = req.getQueryString();
        System.out.println(reqMethod);
        System.out.println(contextPath);
        System.out.println(requestURL);
        System.out.println(requestURI);
        System.out.println(queryString);
    }

结果:

(2)请求头
方法名 说明
String getHeader(String name) 根据请求头名称获取值
(3)请求体(POST)
方法名 说明
ServletInputStream getInputStream() 获取字节输入流
BufferedReader getReader() 获取字符输入流
html 复制代码
  <form action="/request02" method="post">
      <!--确保表单内容有name属性!-->
    <label>
      <input type="text" placeholder="请输入用户名" name="username"><br>
    </label>
    <label>
      <input type="password" placeholder="请输入密码" name="password"><br>
    </label>
    <input type="submit">
  </form>
java 复制代码
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //
    System.out.println("req对象:" + req);
    //此流不需要自己手动关闭,在request对象被销毁的时候,该流会自动关闭
    final BufferedReader reader = req.getReader();
    final String s = reader.readLine();
    System.out.println(s);
​
}
(5)Request通用方式获取请求参数
方法名 说明
Map< String,String\[\]> getParameter() 获取所有参数Map集合
String\[\] getParameterValues(String name) 根据名称获取参数值/数组
String getParameter(String name) 根据名称获取参数值(单个值)

html

html 复制代码
  <form action="/request03" method="get">
<!--确保表单内容有name属性!-->
    <label>
      <input type="text" placeholder="请输入用户名" name="username"><br>
    </label>
    <label>
      <input type="password" placeholder="请输入密码" name="password"><br>
    </label>
      <label>
          <input type="checkbox" name="hobby" value="run">
      </label>跑
      <label>
          <input type="checkbox" name="hobby" value="jump">
      </label>跳
      <label>
          <input type="checkbox" name="hobby" value="eat">
      </label>吃
    <input type="submit">
  </form>

java:

java 复制代码
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        final Map<String, String[]> reqParameterMap = req.getParameterMap();
        reqParameterMap.forEach((k,v) -> {
            System.out.println(k+":"+ Arrays.toString(v));
        });
​
        final String[] hobby = req.getParameterValues("hobby");
        System.out.println(Arrays.toString(hobby));
        //只会获取数组中的第一个数据
        final String hobby1 = req.getParameter("hobby");
        System.out.println(hobby1);
    }
​
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        final Map<String, String[]> reqParameterMap = req.getParameterMap();
        reqParameterMap.forEach((k,v) -> {
            System.out.println(k+":"+ Arrays.toString(v));
        });
​
        final String[] hobby = req.getParameterValues("hobby");
        System.out.println(Arrays.toString(hobby));
        //只会获取数组中的第一个数据
        final String hobby1 = req.getParameter("hobby");
        System.out.println(hobby1);
    }

优化重复代码:

java 复制代码
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    final Map<String, String[]> reqParameterMap = req.getParameterMap();
    reqParameterMap.forEach((k,v) -> {
        System.out.println(k+":"+ Arrays.toString(v));
    });
​
    final String[] hobby = req.getParameterValues("hobby");
    System.out.println(Arrays.toString(hobby));
    //只会获取数组中的第一个数据
    final String hobby1 = req.getParameter("hobby");
    System.out.println(hobby1);
}
​
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    this.doGet(req,resp);
}

4.Servlet模板

如果还觉得不够省事,可以修改模板

5.中文数据乱码解决

如果是Tomcat8及以上的版本,恭喜这个问题可以跳过~

预防万一解决方式也写一下

POST:

方法名 说明
setCharacterEncoding("UTF-8"); 设置字符流编码格式

GET:

URL编码

  • 将字符串按照编码方式转为二进制

  • 每个字节转为2个16进制数并在前边加上%

Tomcat默认编码:ISO-8859-1

解决方式:该方法通用

  • 将接收数据先转成字节数据
  • 之后再解码变成汉字
java 复制代码
public class UrlDemo {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //URL编码
        //浏览器
        String s = "张三";
        final String encode = URLEncoder.encode(s,"utf-8");
        System.out.println(encode);
​
        //URL解码
        //Tomcat
        //Tomcat8以下默认使用的是ISO-8859-1
        final String decode = URLDecoder.decode(encode, "ISO-8859-1");
        System.out.println(decode);
​
        //转为字节数据,编码
        final byte[] bytes = decode.getBytes(StandardCharsets.ISO_8859_1);
        for (byte aByte : bytes) {
            System.out.print(aByte+" ");
        }
        System.out.println();
​
        //字节数组转字符串,解码
        final String s1 = new String(bytes, StandardCharsets.UTF_8);
        System.out.println(s1);
    }
}

6.请求转发

请求转发(forward):一种在服务器内部的资源跳转方式

实现方式:

java 复制代码
//写在资源A
req.getRequestDispatcher("资源B路径").forward(req,resp);

请求转发资源间共享数据:使用Request对象

方法名 说明
void setAttribute(String name, Object o) 存储数据到 request域中
Object getAttribute(String name) 根据 key,获取值
void removeAttribute(String name) 根据 key,删除该键值对

特点:

  • 浏览器地址栏路径不发生变化

  • 只能转发到当前服务器的内部资源

  • 一次请求,可以在转发的资源间使用request共享数据

二、Response(响应)

1.作用

设置响应数据

2.继承体系

3.设置响应数据

(1)响应行
方法名 说明
void setStatus(int sc) 设置响应状态码
(2)响应头
方法名 说明
void setHeader(String name,String value) 设置响应头键值对
(3)响应体
方法名 说明
PrintWriter getWriter() 获取字符输出流
ServletOutputStream getOutputStream() 获取字节输出流

4.重定向

重定向(Redirect):一种资源跳转方式

java 复制代码
System.out.println("resp01");
response.setStatus(302);
//不区分大小写
response.setHeader("Location","/response02");
​
//简化
response.sendRedirect("/response02");

特点:

  • 浏览器地址栏路径发生变化

  • 可以重定向到任意位置的资源(服务器内部、外部均可)

  • 两次请求,不能在多个资源使用request共享数据

5.响应字符数据

java 复制代码
//中文乱码解决
//原因:通过Response获取的字符输出流默认编码:ISO-8859-1
response.setContentType("text/html;charset=utf-8");
//解析html标签
response.setHeader("content-type","text/html");
//流不需要手动关闭,随着响应结束,response对象销毁,由服务器关闭
final PrintWriter writer = response.getWriter();
writer.write("测试");
writer.write("ceshi");
writer.write("<h1>测试</h1>");

6.响应字节数据

java 复制代码
//读取文件
FileInputStream fis = new FileInputStream("D:/新建文件夹 (2)/图片素材/13516761_0_final.png");
//获取response字节输出流
final ServletOutputStream os = response.getOutputStream();
//完成流的copy
final byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) != -1){
    os.write(buffer,0,length);
}
fis.close();

IO工具类:

XML 复制代码
<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.11.0</version>
</dependency>
java 复制代码
//读取文件
FileInputStream fis = new FileInputStream("D:/新建文件夹 (2)/图片素材/13516761_0_final.png");
//获取response字节输出流
final ServletOutputStream os = response.getOutputStream();
IOUtils.copy(fis,os);

三、杂项问题

1.路径问题

浏览器使用:需要加虚拟目录(项目访问路径) 服务端使用:不需要加虚拟目录

动态获取虚拟目录:

java 复制代码
final String contextPath = request.getContextPath();
System.out.println(contextPath);
//简化
response.sendRedirect(contextPath + "/response02");

2.插件推荐

File Path Autocomplete:

相关推荐
周杰伦fans7 小时前
C# 异常继承深度解析:从设计原则到 sealed 关键字的奥秘
java·jvm·c#
搬石头的马农7 小时前
从零配置Claude自动修Bug:6步打造全自动开发流程
java·人工智能·python·bug·ai编程
小马爱打代码7 小时前
Redis Key 过期后会立刻删除吗?过期删除与内存淘汰策略详解
java·redis·缓存
鱼鳞_8 小时前
苍穹外卖-Day10(Spring task)
java·后端·spring
雨落在了我的手上8 小时前
初始java(十七):常⽤⼯具类介绍
java·开发语言
凤凰院凶涛QAQ8 小时前
《Java版数据结构 & 集合类剖析》集合框架的封装设计与顺序表:“从 Iterable 到 ArrayList:集合框架的‘职业树“
java·开发语言·数据结构
孟华苏8 小时前
怎么快速排查内存泄漏问题
java·开发语言·python
noipp8 小时前
推荐题目:洛谷 P16510 [GKS 2015 #C] gRanks
java·c语言·开发语言·c++·python·算法
flyinmind8 小时前
Java环境与Android环境中使用QuickJS
java·开发语言·javascript·quickjs
不吃鱼的羊8 小时前
DaVinci Developer自动连接
java·开发语言