写点什么

Java Web(七)Request&Response

作者:浅辄
  • 2022-11-12
    吉林
  • 本文字数:2810 字

    阅读完需:约 9 分钟

Request&Response


  • Request:获取请求数据

  • Response:设置响应数据

一.Request 对象

1.Request 继承体系


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

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

2.Request 获取请求数据

2.1 获取请求数据
  • 请求数据分为 3 部分:

  • 1.请求行:

    GET /request-demo/req1?username=zhangsan HTTP/1.1

    • String getMethod():获取请求方式:GET

    • String getContextPath():获取虚拟目录(项目访问路径):/request-demo

    • StringBuffer getRequestURL0:获取 URL(统一资源定位符):http:/localhost:8080/request-demo/req1

    • String getRequestURI():获取 URI(统一资源标识符):/request-demo/req1

    • String getQueryString() :获取请求参数(GET 方式):username=zhangsan&password=123

    2.请求头

    User-Agent:Mozilla/5.0 Chrome/91.0.4472.106

    • String getHeader(String name):根据请求头名称,获取值

    3.请求体

    username=superbaby&password=123

    • ServletInputStream getlnputStream():获取字节输入流

    • BufferedReader getReader(():获取字符输入流

2.2 通用方式获取请求参数
  • 请求参数获取方式

  • get 方式:

    String getQueryString()

    post 方式:

    BufferedReader getReader()

思考:

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

3.Request 通用方式获取请求参数


  • Map<String,String[]>getParameterMap():获取所有参数 Map 集合

  • String[]getParameterValues(String name):根据名称获取参教值(数组)

  • String getParameter(String name):根据名称获取参数值(单个值)

  • 使用通用方式获取请求参数后,屏蔽了 GET 和 POST 的请求方式代码的不同,则代码可以定义为如下格式:

  • @WebServlet("/reqDemo3")
    public class RequestDemo3 extends HttpServlet{
    @override
    protected void doGet(HttpServletRequest req,HttpServletResponse resp){
    
    }
    @override
    protected void doPost(HttpServletRequest req,HttpServletResponse resp){
    this.doGet(req,resp);
    }
    }
    
  • 可以使用 Servlet 模板创建 Servlet 更高效


若是没有 new Servlet 选项
  1. 在 pom.xml 文里导入 servlet 得依赖

  2. 在 File 里的 Project Structure 找到 Modules

  3. 点击 Dependencies 勾选 servlet-api 的选项


  • 若想改变模板的格式


4.Request 请求参数中文乱码

  • 请求参数如果存在中文数据,则会乱码


//POST的乱码//1.解决乱码:PoST的底层实现是getReaderrequest.setCharacterEncoding("UTF-8");//设置字符输入流的编码
//要先设置编码格式,否则后续仍然会中文乱码
//2.获取usernameString username = request.getParameter("username");System.out.println(username);
//GET的乱码//1.GET,获取参数的方式:getQuerystring//乱码原因:tomcat进行URL解码,默认的字符集IS0-8859-1//1.1先对乱码数据进行编码:转为字节数组username.getByte(StandardCharsets.IS0_8859_1);//1.2字节数组解码username = new String(bytes,StandardCharsets.ISO_8859_1)//1.1和1.2可合为一行username = new String(username.getBytes((StandardCharsets.ISO_8859_1),StandardCharsets.ISO_8859_1);
复制代码


  • get 的乱码原因



  • URL 编码

  • 1.将字符串按照编码方式转为二进制 2.每个字节转为 2 个 16 进制数并在前边加上 %

  • 解决方案:

  • POST:设置输入流的编码

    req.setCharacterEncoding("UTF-8");
    

    通用方式(GET/POST):先编码,再解码

    new String(username.getBytes("ISO-8859-1"),"UTF-8");


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

5.Request 请求转发

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



  • 实现方式


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.Response 设置响应数据功能介绍

  • 响应数据分为 3 部分

  • 1.响应行:

    HTTP/1.1 200 OK

    • void setStatus(int sc):设置响应状态码

    2.响应头:

    Content-Type:text/html

    • void setHeader((String name,String value):设置响应头键值对

    3.响应体:

    <html><head>head><body></body></html>

    • PrintWriter getWriter():获取字符输出流

    • ServletOutputStream getQutputStream():获取字节输出流

2.Response 完成重定向

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



  • 实现方式:


resp.setStatus(302);resp.setHeader("location",“资源B的路径");
复制代码


resp.sendRedirect("资源B的路径");
复制代码


  • 重定向的特点

  • 浏览器地址栏路径发生变化可以重定向到任意位置的资源(服务器内部、外部均可)两次请求,不能在多个资源使用 request 共享数据

  • 路径问题


是否要加虚拟目录


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


//简化方式完成重定向//动态获取虚拟目录String contextPath = request.getContextPath();response.sendRedirect(contextPath+"/resp2");
复制代码

3.Response 响应字符数据

  • 使用 1.通过 Response 对象获取字符输出流


  PrintWriter writer = resp.getWriter()
复制代码


2.写数据


  writer.write("aaa");
复制代码


正常写入数据就调用 write 方法即可,如想要写入 html 文本语言,则要设置 ContentType


response.setContentType("text/html;charset=utf-8");//1.获取字符输出流PrintWriter writer response.getWriter();//content-type//response.setHeader("content-type","text/html");writer.write(s:"你好");writer.write(s:"<h1>aaa</h1>");//细节:流不需要关闭
复制代码


  • 注意该流不需要关闭,随着响应结束,response 对象销毁,由服务器关闭中文数据乱码:原因通过 Response 获取的字符输出流默认编码:ISO-8859-1


  resp.setContentType("text/html;charset=utf-8");
复制代码

4.Response 响应字节数据

  • 使用 1.通过 Responsel 对象获取字符输出流


  ServletOutputStream outputStream = resp.getOutputStream();
复制代码


2.写数据


  outputStream,write(字节数据):
复制代码


  • IOUtils 工具类使用 1.导入坐标


  <dependency>      <groupld>commons-io</groupld>      <artifactld>commons-io</artifactld>      <version>2.6</version>  </dependency>
复制代码


2.使用


  IOUtils.copy(输入流,输出流);
复制代码

5.SqlSession 工具类抽取

  • 创建 SqlSessionFactory 代码优化


  //2.1获取SqlSessionFactory对象  String resource "mybatis-config.xml";  Inputstream inputstream = Resources.getResourceAsstream(resource);  SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputstream);
复制代码


  • 问题 1.代码重复:工具类 2.SqlSessionFactory 工厂只创建一次,不要重复创建:静态代码块

发布于: 刚刚阅读数: 3
用户头像

浅辄

关注

大丈夫生于天地之间,岂能郁郁久居人之下 2022-11-08 加入

阿里云技术博主认证

评论

发布
暂无评论
Java Web(七)Request&Response_浅辄_InfoQ写作社区