07_Response

news2024/9/30 17:29:55

文章目录

    • 案例(请求分发案例)
  • Response
    • 响应行
    • 响应头
    • 响应体
    • 特殊响应头
      • refresh
      • Content-type
      • Content-disposition
      • location
    • 案例(登录案例)

案例(请求分发案例)

  • 场景:有多个请求
    • Http://localhost:8080/user/login → 登录
    • Http://localhost:8080/user/register → 注册
    • Http://localhost:8080/user/info → 查看用户信息

eg:

/**
 * localhost:8080/demo1/user/login
 * localhost:8080/demo1/user/register
 * localhost:8080/demo1/user/info
 */

//@WebServlet(value = {"/user/login", "/user/register", "/user/info"})
@WebServlet("/user1/*")
public class UserServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        process(req, resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        process(req, resp);
    }

    private void process(HttpServletRequest request, HttpServletResponse resp) {
        String operation = null;
        // /demo1/user/login
        String requestURI = request.getRequestURI();
        operation = requestURI.substring(requestURI.lastIndexOf("/") + 1);
//        if("login".equals(operation)) {
//            login(request,resp);
//        } else if("info".equals(operation)) {
//            info(request,resp);
//        }
        switch (operation) {
            case "login":
                login(request, resp);
                break;
            case "info":
                info(request, resp);
                break;
            case "register":
                register(request, resp);
                break;
            case "remove":
                remove(request, resp);
                break;
        }
    }

    private void remove(HttpServletRequest request, HttpServletResponse resp) {
    }

    private void register(HttpServletRequest request, HttpServletResponse resp) {
    }

    private void info(HttpServletRequest request, HttpServletResponse resp) {
    }

    private void login(HttpServletRequest request, HttpServletResponse resp) {
    }
}

优化版本

eg:

  • DispatchUtil.java
    • 通过反射的方式,实现其通用性
public class DispatchUtil {
    @SneakyThrows
    public static void dispatch(String operation, HttpServletRequest request
            , HttpServletResponse response, HttpServlet instance) {

// java.lang.Class.getDeclaredMethod()方法返回一个Method对象,
// 它反映此Class对象所表示的类或接口的指定已声明方法。
// name 参数是一个字符串,指定所需的方法的简单名称,
// parameterTypes 参数是一个数组的Class对象识别方法的形参类型,在声明的顺序
                        
        Method method = instance.getClass().getDeclaredMethod(operation
                , HttpServletRequest.class, HttpServletResponse.class);

        method.setAccessible(true);

        method.invoke(instance, new Object[]{request, response});
    }
}
//@WebServlet(value = {"/user/login", "/user/register", "/user/info"})
@WebServlet("/user2/*")
public class UserServlet2 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        process(req, resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        process(req, resp);
    }

    private void process(HttpServletRequest request, HttpServletResponse resp) {
        String operation = null;
        // /demo1/user/login
        String requestURI = request.getRequestURI();
        operation = requestURI.substring(requestURI.lastIndexOf("/") + 1);
//        if("login".equals(operation)) {
//            login(request,resp);
//        } else if("info".equals(operation)) {
//            info(request,resp);
//        }
        // 不需要再switch判断,直接写方法名函数就可以
        DispatchUtil.dispatch(operation, request, resp, this);
    }

    private void remove(HttpServletRequest request, HttpServletResponse resp) {
    }

    private void register(HttpServletRequest request, HttpServletResponse resp) {
    }

    private void info(HttpServletRequest request, HttpServletResponse resp) {
    }

    private void login(HttpServletRequest request, HttpServletResponse resp) {
    }

    private void logout(HttpServletRequest request, HttpServletResponse resp) {
        System.out.println("logout");
    }
}

Response

响应报文的封装,设置响应报文

eg:

HTTP/1.1 200
Vary: accept-encoding,origin,access-control-request-headers,access-control-request-method,accept-encoding
Set-Cookie: rememberMe=deleteMe; Path=/; Max-Age=0; Expires=Sun, 12-Feb-2023 06:51:56 GMT
Set-Cookie: JSESSIONID=24287278-5ebb-407d-a3f7-56b74782c4c7; Path=/; HttpOnly
Access-Control-Allow-Origin: *
Content-Type: application/json;charset=UTF-8
Date: Mon, 13 Feb 2023 06:51:56 GMT
Content-Length: 200

{"errno":0,"data":{"adminInfo":
{"nickName":"admin123","avatar":"https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"},
"token":"24287278-5ebb-407d-a3f7-56b74782c4c7"},"errmsg":"成功"}

响应行

设置一下响应状态码

方法名参数说明
setStatus(int)参数就是状态码设置响应状态码

eg:

/**
 * 常用的响应状态码:200、404、302、400、500
 * 响应行中的响应状态码
 */
@WebServlet("/line")
public class LineServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse response)
            throws ServletException, IOException {
        response.setStatus(302);
    }
}

在这里插入图片描述


响应头

  • 响应头是key:value的格式,提供了通用的方法,可以设置响应头的key和value
  • 提供了一些特定的方法,特定的方法做的事情,就是设置特定响应头的值
方法参数说明
setHeader(String,String)参数1提供key,参数2提供value通用的方法

eg:

@WebServlet("/header")
public class HeaderServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse response)
            throws ServletException, IOException {
        // 第一个参数是key,第二个参数是value
        response.setHeader("custom-header","aaaaaa");
    }
}

在这里插入图片描述


响应体

  • 可以使用字符流,也可以使用字节流
  • 场景:
    • 字符流:响应文本数据,最主要的场景就是前后端分离之后,通过字符流响应Json数据
    • 字节流:响应图片、文件,也通常在文件下载的场景下使用
方法返回值描述
getWriter()PrintWriter字符流
getOutputStream()ServletOutputStream字节流

eg:

  • 字符流举例
@WebServlet("/body1")
public class BodyServlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse response)
            throws ServletException, IOException {
        // response.getWriter().write("hello world");
        // 如果把响应体里的字符以utf-8的方式编码,不一定能解决中文乱码的问题
        // 因为浏览器不一定以utf-8的方式来解码
        // 从根本上解决这个问题通知浏览器以utf-8的方式解码
        // content-type:指响应体里的正文类型
        response.setHeader("content-type","text/html;charset=utf-8");
        // response.getWriter().write("hello world");
        // 默认的编码:iso-8859-1
        response.getWriter().println("hello world");
    }
}

在这里插入图片描述

  • 字节流举例
@WebServlet("/body2")
public class BodyServlet2 extends HttpServlet {

    // http://localhost:8080/demo1/body2?pic=1.jpg
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String pic = request.getParameter("pic");
        String path = "D:\\test_photo";
        File file = new File(path, pic);
        // 要显示图片,需要在响应体中提供其字节数据 -> 浏览器就会显示图片
        ServletOutputStream outputStream = response.getOutputStream();
        FileInputStream inputStream = new FileInputStream(file);

        int length = 0;
        byte[] bytes = new byte[1024];

        while((length = inputStream.read(bytes)) != -1) {
            outputStream.write(bytes, 0 ,length);
        }
        inputStream.close();
        outputStream.close();
    }
}

特殊响应头

  • 特殊的几个响应头:
    1. refresh → 定时刷新、跳转
    2. content-type → 限定响应的正文(也可以解决中文乱码问题)
    3. content-disposition → 文件下载
    4. location → 重定向

refresh

eg:

/**
 * 自动显示当前的时间
 */
@WebServlet("/refresh")
public class RefreshServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse response)
            throws ServletException, IOException {
        response.setHeader("refresh", "1");

        String pattern = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        String dateStr = simpleDateFormat.format(new Date());


        response.getWriter().println(dateStr);
    }
}

@WebServlet("/refresh2")
public class RefreshServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse response)
            throws ServletException, IOException {
        // 指3s之后去访问demo2/hello.jsp
        response.setHeader("refresh", "3;url=/demo1/hello.jsp");
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().println("请稍后马上跳转到欢迎页面");
    }
}

Content-type

  • 通常不需要设置
  • 比如我们响应Json数据给前端,我们可以设置Content-Type:application/json
  • 我们要在这里做字符集的设置,如果没有做有可能出现中文乱码

Content-disposition

  • 下载的场景会使用
    • eg:content-disposition: attachment;filename=1.jpg
    • 1.jpg来下载正文

eg:

@WebServlet("/download")
public class ContentDispositionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String pic = request.getParameter("pic");
        String path = "D:\\test_photo";

        // 如果代码没有这行内容,那么就是显示该图片
        // 如果做下载,需要设置header content-disposition
        response.setHeader("content-disposition", "attachment;" + pic);

        FileInputStream inputStream = new FileInputStream(new File(path, pic));

        ServletOutputStream outputStream = response.getOutputStream();

        int length = 0;
        byte[] bytes = new byte[1024];

        while ((length = inputStream.read(bytes)) != -1) {
            outputStream.write(bytes, 0, length);
        }
        inputStream.close();
    }
}

location

  • 重定向
  • 状态码:302

eg:

@WebServlet("/location")
public class LocationServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        System.out.println("访问到LocationServlet");
        resp.setStatus(302);
        resp.setHeader("location","http://localhost:8080/demo1/refresh");
    }
}

案例(登录案例)

  • 这个请求由登录页面提供,我们可以通过html提供一个登录表单,该表单会发出请求
  • http://localhost:8080/user/login→ Servlet → 检查用户名和密码是否正确(使用一下MyBatis) →
    • 如果正确,那么就提示登录成功
    • 如果错误,那么刷新登录页面

任务拆解:

  1. 包含登录表单的 login.html文件,放在webapp目录下
  2. 开发UserServlet
    1. /user/login对应的处理方法,使用MyBatis做查询
    2. /user/info对应的处理方法
  3. 整合MyBatis,在应用程序中维护SqlSessionFactory实例
  • Mybatis的配置:
public interface UserMapper {
    List<User> selectByUserNameAndPassword
            (@Param("username") String username, @Param("password") String password);

    User selectByPrimaryKey(Integer id);
}
<mapper namespace="com.coo1heisenberg.demo2.mapper.UserMapper">

    <select id="selectByUserNameAndPassword" resultType="com.coo1heisenberg.demo2.bean.User">
        select id, username, password, age, birthday, createDate, mobile from test_user
        <where>
            username = #{username} and password = #{password}
        </where>
    </select>

    <select id="selectByPrimaryKey" resultType="com.coo1heisenberg.demo2.bean.User">
        select id, username, password, age, birthday, createDate, mobile from test_user
        <where>
            id = #{id}
        </where>
    </select>
</mapper>
  • Servlet的配置
@WebServlet("/user/*")
public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        process(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        process(req, resp);
    }

    private void process(HttpServletRequest request, HttpServletResponse response) {
        String requestURI = request.getRequestURI();
        String operation = null;
        operation = requestURI.substring(requestURI.lastIndexOf("/") + 1);

        switch (operation) {
            case "login":
                login(request, response);
                break;
            case "info":
                info(request, response);
                break;
        }
    }

    @SneakyThrows
    private void info(HttpServletRequest request, HttpServletResponse response) {
        Object user = request.getAttribute("user");
        response.getWriter().println(user);
    }

    @SneakyThrows
    private void login(HttpServletRequest request, HttpServletResponse response) {
        // 1. 首先获得username和password
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        // 2. 查询user记录
        UserMapper userMapper = MybatisUtil.getSqlSession().getMapper(UserMapper.class);
        List<User> users = userMapper.selectByUserNameAndPassword(username, password);

        // 3. 根据user记录判断登录状态
        response.setContentType("text/html;charset=utf-8");
        // 4. 判断登录状态 user的list是否为空
        if (users == null || users.size() == 0) {
            // 如果登陆失败(list == null || list.size() == 0)
            // 刷新到refresh --> 2;url=/demo2/login.html
            // 响应登录失败信息
            response.getWriter().println("登录失败,即将跳转登录页面");
            response.setHeader("refresh", "2;url=/demo2/login.html");
        } else {
            // 如果登录成功(list.size > 0)
            // 响应登录成功信息
            response.getWriter().println("登录成功");
            request.setAttribute("user", users.get(0));
            request.getRequestDispatcher("/user/info").forward(request, response);
            // 跳转到info -> 分享user的id信息(直接分享user信息)
        }
    }
}

  • HTML的配置
<body>
<h1>登录页面</h1>
<!--action:表示当前表单中的内容提交给哪个页面进行处理-->
<!--method:表示当前表单提交的方式,常见的有get和post方式,默认是get提交-->
<form action="/demo2/user/login" method="post">
  用户名:<input type="text" name="username"><br>
  密码:<input type="password" name="password"><br>
  <input type="submit">
</form>

</body>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1550137.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【检索稳定|火爆征稿中】2024年企业管理与数字化经济国际学术会议(ICBMDE 2024)

【检索稳定|火爆征稿中】2024年企业管理与数字化经济国际学术会议&#xff08;ICBMDE 2024&#xff09; 2024 International Conference on Business Management and Digital Economy&#xff08;ICBMDE 2024&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~…

6_相机坐标系_相机4个坐标系详述

相机系列文章是用来记录使用opencv3来完成单目相机和6轴机械臂手眼标定。本人吃饭的主职是linux下6轴机械臂相关应用开发。但对于机械臂运动学、相机应用等都非常感兴趣&#xff0c;所以对一些线性代数基础薄弱又想深入了解机械臂内部运算的同志比较有体会。由于是探索性学习&a…

基于Spring Boot的在线学习系统的设计与实现

基于Spring Boot的在线学习系统的设计与实现 摘 要 在线学习系统是以大学传统线下教学方式不适应信息技术的迅速发展为背景&#xff0c;提高学习效率&#xff0c;解决传统教学问题&#xff0c;并且高效的实现教学信息化的一款软件系统。为了更好的实现对于教学和学生的管理&a…

Dockerfile:自定义镜像

Dockerfile 是一个文本文件&#xff0c;其中包含了一系列用于自动化构建Docker镜像的指令。通过编写Dockerfile&#xff0c;开发者能够明确地定义一个软件应用及其运行环境应该如何被封装进一个可移植、可重复构建的Docker镜像中。 第一步&#xff1a;在/tmp文件下新建docker…

使用itext-core生成PDF

1、添加引用依赖包 <dependency><groupId>com.itextpdf</groupId><artifactId>itext-core</artifactId><version>8.0.3</version><type>pom</type></dependency> 2、上代码 package com.student.demo.pdf;impor…

CUDA版本支持的pytorch版本

PyTorch 1.0.x - 支持 CUDA 7.5 PyTorch 1.1.x - 支持 CUDA 8.0 PyTorch 1.2.x - 支持 CUDA 9.0 PyTorch 1.3.x - 支持 CUDA 9.2 PyTorch 1.4.x - 支持 CUDA 10.1 PyTorch 1.5.x - 支持 CUDA 10.2 PyTorch 1.6.x - 支持 CUDA 11.0 PyTorch 1.7.x - 支持 CUDA 11.0/11.1 PyTorch…

数字身份的革命:解锁 Web3 的身份验证技术

引言 随着数字化时代的到来&#xff0c;个人身份认证成为了日常生活和商业活动中不可或缺的一部分。传统的身份验证方式存在着安全性低、易伪造、不便利等问题&#xff0c;因此&#xff0c;人们迫切需要一种更安全、更便捷的身份验证技术。在这样的背景下&#xff0c;Web3的身…

【C语言】Infiniband驱动init_dev_assign函数

一、注释 一个内核模块的初始化函数&#xff0c;用于分配和初始化某些资源。以下是对代码块的逐行中文注释&#xff1a; // 定义一个初始化设备分配的函数 static void init_dev_assign(void) {int i 1;spin_lock_init(&dev_num_str_lock); // 初始化自旋锁if (mlx4_fil…

超级会员卡积分收银系统源码:积分+收银+商城三合一小程序 带完整的安装代码包以及搭建教程

信息技术的迅猛发展&#xff0c;移动支付和线上购物已经成为现代人生活的常态。在这样的背景下&#xff0c;商家对于能够整合收银、积分管理和在线商城的综合性系统的需求日益强烈。下面&#xff0c;罗峰给大家分享一款超级会员卡积分收银系统源码&#xff0c;它集积分、收银、…

pyecharts操作一

pyecharts 是一个用于生成Echarts图表的Python库。Echarts是百度开源的一个数据可视化JS库&#xff0c;可以生成一些非常酷炫的图表。 环境安装 pip install pyecharts 检查版本 import pyecharts print(pyecharts.version) 2.0.3 柱状图绘制 from pyecharts.charts impor…

通过Jmeter准备压测数据-mysql示例

1、新建线程组 总共30万条数据 2、创建jdbc链接 创建jdbc连接配置 配置mysql连接 需要在jmeter安装的路径\apache-jmeter-5.6.3\lib\ext 目录下添加mysql 驱动 3、创建jdbc请求 jdbc链接名称需要与上一步中的保持一致&#xff0c;同时添加insert语句 例如 INSERT INTO test…

【tingsboard开源平台】下载数据库,IDEA编译,项目登录

一&#xff0c; PostgreSQL 下载 需要看官网的&#xff1a;点此下载直达地址&#xff1a;点此进行相关学习&#xff1a;PostgreSQL 菜鸟教程 二&#xff0c;PostgreSQL 安装 点击安装包进行安装 出现乱码错误&#xff1a; There has been an error. Error running C:\Wind…

macos下 jupyter服务安装和vscode链接密码设置 .ipynb文件

最近收到了一些后缀为.ipynb的文件&#xff0c; 这个文件就是使用jupyter编辑的&#xff0c;于是就需要安装一个jupyter服务&#xff0c; 对于最新版本的jupyter 网上很多的资料都已经过期了&#xff0c;这里以最新版本的jupyter为例。 jupyter lab安装 jupyter 这个工具包含…

HBase的Python API操作(happybase)

一、Windows下安装Python库&#xff1a;happyhbase pip install happybase -i https://pypi.tuna.tsinghua.edu.cn/simple 二、 开启HBase的Thrift服务 想要使用Python API连接HBase&#xff0c;需要开启HBase的Thrift服务。所以&#xff0c;在Linux服务器上&#xff0c;执行…

Adobe推出20多个,企业版生成式AI定制、微调服务

3月27日&#xff0c;全球多媒体领导者Adobe在拉斯维加斯召开“Summit 2024”大会&#xff0c;重磅推出了Firefly Services。 Firefly Services提供了20 多个生成式AI和创意API服务&#xff0c;支持企业自有数据对模型进行定制、微调&#xff0c;同时可以与PS、Illustrator、Ex…

循序渐进丨MogDB 对 Oracle DBLink兼容性增强

本特性自 MogDB 5.0.0版本开始引入&#xff0c;支持 Oracle DBLink语法&#xff0c;可以使用符号访问 Oracle 数据库中的表。 示 例 01 环境准备 MogDB 环境 已安装 MogDB 数据库。已安装oracle_fdw插件&#xff0c;具体安装方法参见oracle_fdw安装文档https://docs.mogdb.io/…

Spring boot2.X 配置https

背景 最近项目组说要将 http 升级成 https 访问&#xff0c;证书也给到我们这边了&#xff0c;当然我们这边用的是个二级域名&#xff0c;采用的是通配符访问的方式&#xff0c;比如一级域名是这样&#xff08;com.chinaunicom.cn&#xff09;&#xff0c;我们的则是&#xff0…

论文笔记:Retrieval-Augmented Generation forAI-Generated Content: A Survey

北大202402的RAG综述 1 intro 1.1 AICG 近年来&#xff0c;人们对人工智能生成内容&#xff08;AIGC&#xff09;的兴趣激增。各种内容生成工具已经精心设计&#xff0c;用于生产各种模态下的多样化对象 文本&代码&#xff1a;大型语言模型&#xff08;LLM&#xff09;…

第十一章:位运算符与位运算

文章目录 第十一章&#xff1a;位运算符与位运算1.按位与运算&#xff1a;&2.按位或运算&#xff1a;|3.按位异或运算&#xff1a;^4.取反运算符&#xff1a;~5.左移运算符&#xff1a;<<6.右移运算符&#xff1a;>>总结 第十一章&#xff1a;位运算符与位运算…

【爬虫基础】第4讲 GET与POST请求

GET请求 GET请求是一种HTTP方法&#xff0c;用于向服务器获取&#xff08;或读取&#xff09;数据。它是Web开发中最常用的请求方式之一。对于GET请求&#xff0c;客户端向服务器发送一个HTTP请求&#xff0c;服务器返回请求的资源。GET请求通常用于获取静态资源&#xff0c;比…