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:

相关推荐
功德+n2 分钟前
在 Maven 中使用 <scope> 元素:全面指南
java·maven
失业写写八股文21 分钟前
Java类加载阶段深度解析:三步走全流程详解
java
yyueshen29 分钟前
单例模式,有必要用volatile么?
java·单例模式·设计模式
一条闲鱼_mytube31 分钟前
[Kubernetes] 7控制平面组件
java·平面·kubernetes
Y雨何时停T1 小时前
Spring IoC 详解
java·spring·rpc
&白帝&1 小时前
Java @PathVariable获取路径参数
java·开发语言·python
Yuanymoon1 小时前
【由技及道】镜像星门开启:Harbor镜像推送的量子跃迁艺术【人工智障AI2077的开发日志010】
java·docker·jenkins·harbor·devops
木胭脂沾染了灰1 小时前
策略设计模式-下单
java·前端·设计模式
sevevty-seven2 小时前
Spring Boot 自动装配原理详解
java·spring boot·后端
Forget the Dream4 小时前
设计模式之迭代器模式
java·c++·设计模式·迭代器模式