07_Response

文章目录

    • 案例(请求分发案例)
  • 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 {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {process(req, resp);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {process(req, resp);}private void process(HttpServletRequest request, HttpServletResponse resp) {String operation = null;// /demo1/user/loginString 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 {@SneakyThrowspublic 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 {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {process(req, resp);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {process(req, resp);}private void process(HttpServletRequest request, HttpServletResponse resp) {String operation = null;// /demo1/user/loginString 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 {@Overrideprotected 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 {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse response)throws ServletException, IOException {// 第一个参数是key,第二个参数是valueresponse.setHeader("custom-header","aaaaaa");}
}

在这里插入图片描述


响应体

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

eg:

  • 字符流举例
@WebServlet("/body1")
public class BodyServlet1 extends HttpServlet {@Overrideprotected 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-1response.getWriter().println("hello world");}
}

在这里插入图片描述

  • 字节流举例
@WebServlet("/body2")
public class BodyServlet2 extends HttpServlet {// http://localhost:8080/demo1/body2?pic=1.jpg@Overrideprotected 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 {@Overrideprotected 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 {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse response)throws ServletException, IOException {// 指3s之后去访问demo2/hello.jspresponse.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 {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {String pic = request.getParameter("pic");String path = "D:\\test_photo";// 如果代码没有这行内容,那么就是显示该图片// 如果做下载,需要设置header content-dispositionresponse.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 {@Overrideprotected 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 {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {process(req, resp);}@Overrideprotected 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;}}@SneakyThrowsprivate void info(HttpServletRequest request, HttpServletResponse response) {Object user = request.getAttribute("user");response.getWriter().println(user);}@SneakyThrowsprivate void login(HttpServletRequest request, HttpServletResponse response) {// 1. 首先获得username和passwordString 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.hqwc.cn/news/572848.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【React】vite + react 项目,进行配置 eslint

安装与配置 eslint 1 安装 eslint babel/eslint-parser2 初始化配置 eslint3 安装 vite-plugin-eslint4 配置 vite.config.js 文件5 修改 eslint 默认配置 1 安装 eslint babel/eslint-parser npm i -D eslint babel/eslint-parser2 初始化配置 eslint npx eslint --init相关…

经典应用丨光伏行业扫码追溯新标杆,海康机器人AI智能读码器!

去年&#xff0c;光伏发电行业持续高速发展&#xff0c;我国仅在前九个月累计装机521.08GW&#xff0c;同比增长达到45.3%&#xff0c;已成为第二大电源类型超过水电。根据《2023中国与全球光伏发展白皮书》预测&#xff0c;到2030年&#xff0c;中国能够实现国家规划的风电和光…

vector类(一)

文章目录 vector介绍和使用1.vector的介绍2.vector的使用2.1 vector的定义2.2 vector iterator的使用2.3 vector空间增长问题2.4 vector增删查改2.5 vector迭代器失效问题 3.vector 在OJ中的使用 vector介绍和使用 1.vector的介绍 vector是表示 可变大小数组的 序列容器。 就…

Java面试八股文

【康康要努力】 hello&#xff0c;你好鸭&#xff0c;我是康康&#xff0c;很高兴你能来阅读&#xff0c;昵称是希望自己能不断精进&#xff0c;向着优秀程序员前行! 目前博客主要更新Java系列、数据库、项目案例、计算机基础等知识点。感谢你的阅读和关注&#xff0c;在记录的…

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

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

GitHub推送远程仓库详细教程

一、在远程新建一个仓库 二、在工作区初始化并提交到版本库 三、连接到远程仓库地址进行推送 四、推送到其他分支 4.1 新建其他分支 4.2 新建文件进行提交 4.3 将文件推送到其他分支 4.4 推送成功演示 4.5 连接远程跟踪分支&#xff0c;方便提交 4.6 直接push展示 五、其他 5…

R 生存分析3:Cox等比例风险回归及等比例风险检验

虽然Kaplan-Meier分析方法目前应用很广&#xff0c;但是该方法存在一下局限: 对于一些连续型变量&#xff0c;必须分类下可以进行生存率对比 是一种单变量分析&#xff0c;无法同时对多组变量进行分析 是一种非参数分析方法&#xff0c;必须有患者个体数据才能进行分析 英国…

队列+宽搜例题讲解!

429. N 叉树的层序遍历 题目解析&#xff1a; 根据题目分析&#xff0c;可以看出题目要我们求的是N叉数的层序遍历&#xff0c;就是把每层的放在一块&#xff0c;最后把每层都输出出来即可&#xff01; 算法分析&#xff1a; 我们可以利用队列先进先出的特性进行求解&#x…

<QT基础(2)>QScrollArea使用笔记

项目需要设置单个检查的序列图像预览窗口&#xff0c;采用QScrollArea中加入QWidget窗口&#xff0c;每个窗口里面用Qlabel实现图像预览。 过程涉及两部分内容 引入QWidget 引入label插入图像&#xff08;resize&#xff09; 引入布局 组织 scrollArea内部自带Qwidget&#…

ARMday7作业

实现三个按键的中断&#xff0c;现象和代码 do_ipr.c #include "stm32mp1xx_gic.h" #include "stm32mp1xx_exti.h" extern void printf(const char *fmt, ...); unsigned int i 0; void do_irq(void) {//获取要处理的中断的中断号unsigned int irqnoGI…

神经网络:梯度下降法更新模型参数

作者&#xff1a;CSDN _养乐多_ 在神经网络领域&#xff0c;梯度下降是一种核心的优化算法&#xff0c;本文将介绍神经网络中梯度下降法更新参数的公式&#xff0c;并通过实例演示其在模型训练中的应用。通过本博客&#xff0c;读者将能够更好地理解深度学习中的优化算法和损…

SPU赋能PSI:探秘隐私集合求交核心技术与高级调度架构实践

1.SPU实现的PSI介绍 1.PSI的定义和种类 隐私集合求交&#xff08;Private Set Intersection, PSI&#xff09;是一种在密码学和安全多方计算&#xff08;MPC&#xff09;领域中的关键技术&#xff0c;允许两个或多个参与者在不泄露各自输入集合中非交集部分的前提下&#xff…