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.rhkb.cn/news/288767.html

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

相关文章

逐步学习Go-并发通道chan(channel)

概述 Go的Routines并发模型是基于CSP&#xff0c;如果你看过七周七并发&#xff0c;那么你应该了解。 什么是CSP&#xff1f; "Communicating Sequential Processes"&#xff08;CSP&#xff09;这个词组的含义来自其英文直译以及在计算机科学中的使用环境。 CSP…

day 36 贪心算法 part05● 435. 无重叠区间 ● 763.划分字母区间 ● 56. 合并区间

一遍过。首先把区间按左端点排序&#xff0c;然后右端点有两种情况。 假设是a区间&#xff0c;b区间。。。这样排列的顺序&#xff0c;那么 假设a[1]>b[0],如果a[1]>b[1]&#xff0c;就应该以b[1]为准&#xff0c;否则以a[1]为准。 class Solution { public:static bo…

Android中运动事件的处理

1.目录 目录 1.目录 2.前言 3.程序演示 4.第二种程序示例 5.扩展 2.前言 触摸屏&#xff08;TouchScreen&#xff09;和滚动球&#xff08;TrackBall&#xff09;是 Android 中除了键盘之外的主要输入设备。如果需要使用触摸屏和滚动球&#xff0c;主要可以通过使用运动事…

渐变色x轴换行柱状图

// 系统上云率const optionBar {title: {text: 系统上云率,left: left,textStyle: {color: "#fff",fontSize: 14,fontWeight: 650,align: "center",},},color: [#32C5FF, #00F766, #EECB5F],grid: {top: 40,bottom: 0,},legend: { // 控制图例组件show: …

K8s Pod亲和性、污点、容忍度、生命周期与健康探测详解(上)

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Kubernetes航线图&#xff1a;从船长到K8s掌舵者》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 在上一章节中&#xff0c;我们详细探讨了Pod的概念、创建、…

逐步学习Go-协程goroutine

参考&#xff1a;逐步学习Go-协程goroutine – FOF编程网 什么是线程&#xff1f; 简单来说线程就是现代操作系统使用CPU的基本单元。线程基本包括了线程ID&#xff0c;程序计数器&#xff0c;寄存器和线程栈。线程共享进程的代码区&#xff0c;数据区和操作系统的资源。 线…

数据结构——排序算法

1、排序的概念 排序是指的是将一组数据&#xff08;如数字、单词、记录等&#xff09;按照某种特定的顺序&#xff08;升序或降序&#xff09;进行排列的过程。排序算法是实现排序的程序或方法&#xff0c;它们在软件开发和数据处理中扮演着至关重要的角色。 排序算法可以根据…

servlet开发详解

一、什么是servlet&#xff0c;干什么用的&#xff1f;&#xff1f;&#xff1f; tomcat作为一个web服务器&#xff0c;也称作servlet容器。servlet只有放在web服务器中才能运行&#xff0c;不能独立运行。tomcat这个容器要做三件事&#xff1a;接收请求、处理请求和响应请求。…

文生视频大模型Sora的复现经验

大家好&#xff0c;我是herosunly。985院校硕士毕业&#xff0c;现担任算法研究员一职&#xff0c;热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名&#xff0c;CCF比赛第二名&#xff0c;科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的…

java调用jacob进行文件转换ppt转pdf或者png

java调用jacob进行文件转换ppt转pdf或者png 前情提要 最近项目上&#xff0c;遇到一个复杂的ppt&#xff0c;最终要求是要将ppt每一页转成图片原本这个是不难&#xff0c;网上一搜一大堆案例&#xff0c;外加我本身也比较精通aspose&#xff0c;那还不是分分钟搞定。结果就是…

Healix Protocol 的 HLX 通证预售:医疗领域的未来展望

Healix Protocol推出 HLX 通证预售&#xff0c;将带来医疗领域的重要变革。通过其区块链技术&#xff0c;Healix Protocol致力于重新定义医疗服务的可及性与负担性&#xff0c;成为医疗行业的希望之光。该项目旨在增强透明度、可及性和效率&#xff0c;推动医疗体系向更加公平和…

Hadoop面试重点

文章目录 1. Hadoop 常用端口号2.Hadoop特点3.Hadoop1.x、2.x、3.x区别 1. Hadoop 常用端口号 hadoop2.xhadoop3.x访问HDFS 端口500709870访问 MR 执行情况端口80888088历史服务器1988819888客户端访问集群端口90008020 2.Hadoop特点 高可靠&#xff1a;Hadoop底层维护多个数…

Rust语言中Regex正则表达式,匹配和查找替换等

官方仓库&#xff1a;https://crates.io/crates/regex 文档地址&#xff1a;regex - Rust github仓库地址&#xff1a;GitHub - rust-lang/regex: An implementation of regular expressions for Rust. This implementation uses finite automata and guarantees linear tim…

LoadBalance 负载均衡服务调用

前身:Ribbon LB负载均衡(Load Balance)是什么 简单的说就是将用户的请求平摊的分配到多个服务上&#xff0c;从而达到系统的HA&#xff08;高可用&#xff09;&#xff0c;常见的负载均衡有软件Nginx&#xff0c;LVS&#xff0c;硬件 F5等 spring-cloud-starter-loadbalancer组…

OSG编程指南<二十一>:OSG视图与相机视点更新设置及OSG宽屏变形

1、概述 什么是视图?在《OpenGL 编程指南》中有下面的比喻,从笔者开始学习图形学就影响深刻,相信对读者学习场景管理也会非常有帮助。 产生目标场景视图的变换过程类似于用相机进行拍照,主要有如下的步骤: (1)把照相机固定在三脚架上,让它对准场景(视图变换)。 (2)…

【办公类-21-11】 20240327三级育婴师 多个二级文件夹的docx合并成docx有页码,转PDF

背景展示&#xff1a;有页码的操作题 背景需求&#xff1a; 实操课终于全部结束了&#xff0c;把考试内容&#xff08;docx&#xff09;都写好了 【办公类-21-10】三级育婴师 视频转文字docx&#xff08;等线小五单倍行距&#xff09;&#xff0c;批量改成“宋体小四、1.5倍行…

洛谷day3

B2053 求一元二次方程 - 洛谷 掌握printf用法&#xff1b; #include <iostream> #include <cmath> using namespace std; double a,b,c; double delta; double x1,x2;int main() {cin>>a>>b>>c;delta b*b-4*a*c;if(delta>0){x1 (-bsqrt…

从根本上优雅地解决 VSCode 中的 Python 模块导入问题

整体概述&#xff1a; 在我尝试运行 test_deal_file.py 时&#xff0c;我遇到了一个 ModuleNotFoundError 错误&#xff0c;Python告诉我找不到名为 controllers 的模块。这意味着我无法从 deal_file.py 中导入 read_excel 函数。 为了解决这个问题&#xff0c;我尝试了几种方法…

JAVA面试大全之JVM和调优篇

目录 1、类加载机制 1.1、类加载的生命周期&#xff1f; 1.2、类加载器的层次? 1.3、Class.forName()和ClassLoader.loadClass()区别? 1.4、JVM有哪些类加载机制&#xff1f; 2、内存结构 2.1、说说JVM内存整体的结构&#xff1f;线程私有还是共享的&#xff1f; 2.2…

Rust使用原始字符串字面量实现Regex双引号嵌套双引号正则匹配

rust使用Regex实现正则匹配的时候&#xff0c;如果想实现匹配双引号&#xff0c;就需要使用原始字符串字面量&#xff0c;不然无法使用双引号嵌套的。r#"..."# 就表示原始字符串字面量。 比如使用双引号匹配&#xff1a; use regex::Regex;fn main() {println!(&qu…