请求

请求对象

关于请求

顾名思义,意思就是请求一个“对象”

请求不到的,别想了

请求,就是使用者希望从服务器端索取一些资源,向服务器发出询问。在B/S架构中,就是客户浏览器向服务器发出询问。在JavaEE工程中,客户浏览器发出询问,要遵循HTTP协议规定。

请求对象,就是在JavaEE工程中,用于发送请求的对象。我们常用的对象就是ServletRequest和HttpServletRequest,它们的区别就是是否和HTTP协议有关。

常用请求对象

常用请求方法

请求对象的使用示例

常用方法一:请求各种路径

/*
获取路径的相关方法
*/
@WebServlet("/servletDemo01")
public class ServletDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取虚拟目录名称 getContextPath()
String contextPath = req.getContextPath();
System.out.println(contextPath); //2.获取Servlet映射路径 getServletPath()
String servletPath = req.getServletPath();
System.out.println(servletPath); //3.获取访问者ip getRemoteAddr()
String ip = req.getRemoteAddr();
System.out.println(ip); //4.获取请求消息的数据 getQueryString()
String queryString = req.getQueryString();
System.out.println(queryString); //5.获取统一资源标识符 getRequestURI() /request/servletDemo01
String requestURI = req.getRequestURI();
System.out.println(requestURI); //6.获取统一资源定位符 getRequestURL() http://localhost:8080/request/servletDemo01
StringBuffer requestURL = req.getRequestURL();
System.out.println(requestURL); } @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

常用方法二:获取请求参数以及封装(非常重要)

我们常常会使用HttpServletRequest对象获取请求参数,然后将其封装到实体类中

/*
获取请求参数信息的相关方法
*/
@WebServlet("/servletDemo03")
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.根据名称获取数据 getParameter()
String username = req.getParameter("username");
System.out.println(username);
String password = req.getParameter("password");
System.out.println(password);
System.out.println("--------------------"); //2.根据名称获取所有数据 getParameterValues()
String[] hobbies = req.getParameterValues("hobby");
for(String hobby : hobbies) {
System.out.println(hobby);
}
System.out.println("--------------------"); //3.获取所有名称 getParameterNames()
Enumeration<String> names = req.getParameterNames();
while(names.hasMoreElements()) {
String name = names.nextElement();
System.out.println(name);
}
System.out.println("--------------------"); //4.获取所有参数的键值对 getParameterMap()
Map<String, String[]> map = req.getParameterMap();
for(String key : map.keySet()) {
String[] values = map.get(key);
System.out.print(key + ":");
for(String value : values) {
System.out.print(value + " ");
}
System.out.println();
}
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

下面通过实例说明几种封装方式

需求:我们要实现从网页填写学生注册信息,然后把获取请求参数并把相应的信息封装到每一个Student类中。

第一步:编写一个页面html程序


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册页面</title>
</head>
<body>
<form action="/request/servletDemo08" method="post" autocomplete="off">
姓名:<input type="text" name="username"> <br>
密码:<input type="password" name="password"> <br>
爱好:<input type="checkbox" name="hobby" value="study">学习
<input type="checkbox" name="hobby" value="game">游戏 <br>
<button type="submit">注册</button>
</form>
</body>
</html>

第二步:编写Student的javabean类,注意其数据成员最好(必须)与html文件表单的name属性一致

public class Student {
private String username;
private String password;
private String[] hobby; public Student() {
} public Student(String username, String password, String[] hobby) {
this.username = username;
this.password = password;
this.hobby = hobby;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public String[] getHobby() {
return hobby;
} public void setHobby(String[] hobby) {
this.hobby = hobby;
} @Override
public String toString() {
return "Student{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", hobby=" + Arrays.toString(hobby) +
'}';
}
}

第三步:获取参数信息,并封装数据

法一:直接手动封装(简单粗暴)

/*
封装对象-手动方式
*/
@WebServlet("/servletDemo04")
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取所有的数据
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbies = req.getParameterValues("hobby"); //2.封装学生对象
Student stu = new Student(username,password,hobbies); //3.输出对象
System.out.println(stu); } @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

法二:通过反射封装

PropertyDescriptor: Describes a Java Bean property hosting validation constraints

调用javabean类的有参构造函数创建对象

构造函数 PropertyDescriptor(String,class); 注意第一个参数是javabean构造函数的第一个形式参数,第二个参数是已经创建的实类的字节码。

/*
封装对象-反射方式
*/
@WebServlet("/servletDemo05")
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取所有的数据
Map<String, String[]> map = req.getParameterMap(); //2.封装学生对象
Student stu = new Student();
//2.1遍历集合
for(String name : map.keySet()) {
String[] value = map.get(name);
try {
//2.2获取Student对象的属性描述器
PropertyDescriptor pd = new PropertyDescriptor(name,stu.getClass());
//2.3获取对应的setXxx方法
Method writeMethod = pd.getWriteMethod();
//2.4执行方法
if(value.length > 1) {
writeMethod.invoke(stu,(Object)value);
}else {
writeMethod.invoke(stu,value);
}
} catch (Exception e) {
e.printStackTrace();
}
} //3.输出对象
System.out.println(stu); } @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

法三:BeanUtils工具类封装

BeanUtils.populate(stu,map);(实类,参数map)

/*
封装对象-工具类方式
*/
@WebServlet("/servletDemo06")
public class ServletDemo06 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取所有的数据
Map<String, String[]> map = req.getParameterMap(); //2.封装学生对象
Student stu = new Student();
try {
BeanUtils.populate(stu,map);
} catch (Exception e) {
e.printStackTrace();
} //3.输出对象
System.out.println(stu); } @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

用流的形式读取请求信息

/*
流对象获取数据
*/
@WebServlet("/servletDemo07")
public class ServletDemo07 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//字符流(必须是post方式)
/*BufferedReader br = req.getReader();
String line;
while((line = br.readLine()) != null) {
System.out.println(line);
}*/
//br.close(); //字节流
ServletInputStream is = req.getInputStream();
byte[] arr = new byte[1024];
int len;
while((len = is.read(arr)) != -1) {
System.out.println(new String(arr,0,len));
}
//is.close();
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

请求正文中中文编码问题

1.POST方式请求

问题:获取请求正文,会有乱码问题。是在获取的时候就已经乱码了。

解决:是request对象的编码出问题了。设置request对象的字符集

request.setCharacterEncoding("编码方式")它只能解决POST的请求方式,GET方式解决不了

/*
中文乱码
*/
@WebServlet("/servletDemo08")
public class ServletDemo08 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码格式
req.setCharacterEncoding("UTF-8");
String username = req.getParameter("username");
System.out.println(username);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

2.GET方式请求

问题:GET方式:正文在地址栏username=%D5%C5%C8%FD%D5%C5%C8%FD是已经被编过一次码了

GET方式请求的正文是在地址栏中,在Tomcat8.5版本及以后,Tomcat服务器已经帮我们解决了,所以不会有乱码问题了。

而如果我们使用的不是Tomcat服务器,或者Tomcat的版本是8.5以前,那么GET方式仍然会有乱码问题,解决方式如下:

使用正确的码表对已经编过码的数据进行解码。就是把取出的内容转成一个字节数组,但是要使用正确的码表。(ISO-8859-1)再使用正确的码表进行编码,把字节数组再转成一个字符串,需要使用正确的码表,是看浏览器当时用的是什么码表。

/**
* 在Servlet的doGet方法中添加如下代码
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { String username = request.getParameter("username");
byte[] by = username.getBytes("ISO-8859-1");
username = new String(by,"GBK"); //输出到浏览器:注意响应的乱码问题已经解决了
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write(username);
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}

请求转发(与重定向的区别)

重定向特点:两次请求,浏览器行为,地址栏改变,请求域中的数据会丢失

请求转发:一次请求,服务器行为,地址栏不变,请求域中的数据不丢失

请求域的作用范围:当前请求(一次请求),和当前请求的转发之中

请求发送方:

/*
请求转发
*/
@WebServlet("/servletDemo09")
public class ServletDemo09 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置共享数据
req.setAttribute("encoding","gbk"); //获取请求调度对象
RequestDispatcher rd = req.getRequestDispatcher("/servletDemo10");
//实现转发功能
rd.forward(req,resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

请求接收方:

/*
请求转发
*/
@WebServlet("/servletDemo10")
public class ServletDemo10 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取共享数据
Object encoding = req.getAttribute("encoding");
System.out.println(encoding); System.out.println("servletDemo10执行了...");
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

开启服务器后进入/servletDemo09之后会在控制台输出

encoding
servletDemo10执行了...

而此时浏览器的url依然是/servletDemo09,不会跳转

请求重定向

resp.sendRedirect(req.getContextPath() + "/servletDemo07");

请求发送方:

/*
请求重定向
*/
@WebServlet("/servletDemo06")
public class ServletDemo06 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求域数据
req.setAttribute("username","zhangsan"); //设置重定向
resp.sendRedirect(req.getContextPath() + "/servletDemo07"); // resp.sendRedirect("https://www.baidu.com");
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

请求接收方:

/*
请求重定向
*/
@WebServlet("/servletDemo07")
public class ServletDemo07 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servletDemo07执行了...");
Object username = req.getAttribute("username");
System.out.println(username);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

请求包含

需求:把两个Servlet的内容合并到一起来响应浏览器

问题:HTTP协议的特点是一请求,一响应的方式。所以绝对不可能出现有两个Servlet同时响应方式。

解决:把两个Servlet的响应内容合并输出。

/*
请求包含
*/
@WebServlet("/servletDemo11")
public class ServletDemo11 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servletDemo11执行了..."); //获取请求调度对象
RequestDispatcher rd = req.getRequestDispatcher("/servletDemo12");
//实现包含功能
rd.include(req,resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
/*
请求包含
*/
@WebServlet("/servletDemo12")
public class ServletDemo12 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servletDemo12执行了...");
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

控制台输出

servletDemo11执行了...

servletDemo12执行了...

而且浏览器的url依然是/servletDemo11,不会跳转

细节

请求转发的注意事项:负责转发的Servlet,转发前后的响应正文丢失,由转发目的地来响应浏览器。

请求包含的注意事项:被包含者的响应消息头丢失。因为它被包含起来了。

响应

响应对象

关于响应

服务器端收到请求,同时也已经处理完成,把处理的结果告知用户。

在B/S架构中,响应就是把结果带回浏览器。

常用响应对象

协议无关的对象标准是:ServletResponse接口

协议相关的对象标准是:HttpServletResponse接口

常用方法介绍

常用状态码:

状态码 说明
200 执行成功
302 它和307一样,都是用于重定向的状态码。只是307目前已不再使用
304 请求资源未改变,使用缓存。
400 请求错误。最常见的就是请求参数有问题
404 请求资源未找到
405 请求方式不被支持
500 服务器运行内部错误

状态码首位含义:

状态码 说明
1xx 消息
2xx 成功
3xx 重定向
4xx 客户端错误
5xx 服务器错误

响应对象的使用示例

字节流输出中文问题

项目中常用的编码格式是u8,而浏览器默认使用的编码是gbk。导致乱码!

解决方式一:修改浏览器的编码格式(不推荐,不能让用户做修改的动作)

解决方式二:通过输出流写出一个标签:response.getOutputStream().write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'>")

解决方式三:response.setHeader("Content-Type","text/html;charset=UTF-8"); 指定响应头信息

解决方式四:response.setContentType("text/html;charset=UTF-8"); (常用)

/*
字节流响应消息及乱码的解决
*/
@WebServlet("/servletDemo01")
public class ServletDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String str = "你好"; resp.setContentType("text/html;charset=UTF-8"); sos.write(str.getBytes("UTF-8"));
sos.close();
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

字符流输出中文问题

/*
字符流响应消息及乱码的解决
*/
@WebServlet("/servletDemo02")
public class ServletDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String str = "你好"; //解决中文乱码
resp.setContentType("text/html;charset=UTF-8"); //获取字符流对象
PrintWriter pw = resp.getWriter();
//pw.println(str);
pw.write(str);
pw.close();
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

响应图片到浏览器

/*
响应图片到浏览器
*/
@WebServlet("/servletDemo03")
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//通过文件的相对路径来获取文件的绝对路径
String realPath = getServletContext().getRealPath("/img/hm.png");
System.out.println(realPath);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath)); //获取字节输出流对象
ServletOutputStream sos = resp.getOutputStream(); //循环读写
byte[] arr = new byte[1024];
int len;
while((len = bis.read(arr)) != -1) {
sos.write(arr,0,len);
} bis.close();
sos.close();
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

控制缓存

resp.setDateHeader("Expires",(System.currentTimeMillis()+时间));

/*
缓存
*/
@WebServlet("/servletDemo04")
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String news = "这是一条很火爆的新闻~~"; //设置缓存时间
resp.setDateHeader("Expires",(System.currentTimeMillis()+1*60*60*1000L)); //设置编码格式
resp.setContentType("text/html;charset=UTF-8");
//写出数据
resp.getWriter().write(news);
System.out.println("aaa");
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

定时刷新

resp.setHeader("Refresh","定时时间(秒);URL=/虚拟路径/页面路径");

/*
定时刷新
*/
@WebServlet("/servletDemo05")
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String news = "您的用户名或密码错误,3秒后自动跳转到登录页面..."; //设置编码格式
resp.setContentType("text/html;charset=UTF-8");
//写出数据
resp.getWriter().write(news); //设置响应消息头定时刷新
resp.setHeader("Refresh","3;URL=/虚拟路径/login.html");
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

文件下载

/*
文件下载
*/
@WebServlet("/servletDemo08")
public class ServletDemo08 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.创建字节输入流,关联读取的文件
//获取文件的绝对路径
String realPath = getServletContext().getRealPath("/img/hm.png");
//创建字节输出流对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath)); //2.设置响应头支持的类型 应用支持的类型为字节流
/*
Content-Type 消息头名称 支持的类型
application/octet-stream 消息头参数 应用类型为字节流
*/
resp.setHeader("Content-Type","application/octet-stream"); //3.设置响应头以下载方式打开 以附件形式处理内容
/*
Content-Disposition 消息头名称 处理的形式
attachment;filename= 消息头参数 附件形式进行处理
*/
resp.setHeader("Content-Disposition","attachment;filename=" + System.currentTimeMillis() + ".png"); //4.获取字节输出流对象
ServletOutputStream sos = resp.getOutputStream(); //5.循环读写文件
byte[] arr = new byte[1024];
int len;
while((len = bis.read(arr)) != -1) {
sos.write(arr,0,len);
} //6.释放资源
bis.close();
sos.close();
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}

【JavaWeb】请求和响应Request&Response的更多相关文章

  1. JavaWeb学习笔记四 request&response

    HttpServletResponse 我们在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代表响应res ...

  2. JavaWeb请求与响应 Cookie&Session

    1.请求与响应 &Cookie&Session 1.1.请求与响应 HTTP协议 概念:英文全称:HyperText Transfer Protocol 中文全称:超文本传输协议   ...

  3. Django整理(五) - 请求与响应 - request对象

    请求对象 一.客户端传参的几种方式 1. 通过URL路径(path)传递,例如:http://127.0.0.1:8000/news/1/2,两个参数:id和page 2. 通过 query stri ...

  4. java http接口请求响应 request response

    接口类: 1 package org.sunshine.dcda.epg.wechat.controller.niao; 2 3 import javax.servlet.http.HttpServl ...

  5. Django 请求和响应 request return

    request.method 请求方法 request.get  get请求信息 request.post  post请求信息 request.path 请求路径 方法: requset.get_fu ...

  6. 过滤器中的chain.doFilter(request,response)

    Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码.做一些业务逻辑判断等.其工作原理是,只要你在web.xml文件配置好要 ...

  7. 03-【request对象获取请求的数据 & request对象存取值】

    request概述(封装了客户端所有的请求数据) request是Servlet.service()方法的一个参数,类型为javax.servlet.http.HttpServletRequest.在 ...

  8. 请求头(request headers)和响应头(response headers)解析

    *****************请求头(request headers)***************** POST /user/signin HTTP/1.1    --请求方式 文件名 http ...

  9. Scrapy爬虫入门Request和Response(请求和响应)

    开发环境:Python 3.6.0 版本 (当前最新)Scrapy 1.3.2 版本 (当前最新) 请求和响应 Scrapy的Request和Response对象用于爬网网站. 通常,Request对 ...

随机推荐

  1. 使用IDEA创建Maven项目

    一.创建一个普通的Maven项目 1.启动IDEA 2.创建一个Maven项目 3.Maven的目录结构 二.使用模板创建一个MavenWeb项目 1.启动IDEA 2.创建一个MavenWeb项目 ...

  2. 最短路径问题,BFS,408方向,思路与实现分析

    最短路径问题,BFS,408方向,思路与实现分析 继上回挖下的坑,不知道大家有没有认真看最小生成树呢?很简单,这回也讲讲正常难度的,看不懂就来这里看看,讲的很好~~ 最短路径问题 说起这个问题,先说个 ...

  3. 「题解」PA2019 Terytoria

    本文将同步发布于: 洛谷博客: csdn: 博客园: 因为简书系统升级,所以本文未在简书上发布. 题目 题目链接:洛谷 P5987.LOJ 3320.官网. 题意概述 在二维平面直角坐标系上,有一个长 ...

  4. .h5图像文件(数据集)的读取并存储 工具贴(二)

    概述 H5文件是层次数据格式第5代的版本(Hierarchical Data Format,HDF5),它是用于存储科学数据的一种文件格式和库文件.由美国超级计算中心与应用中心研发的文件格式,用以存储 ...

  5. 二、Nginx 服务器升级

      1,编译新版本的nginx 软件 [root@client lnmp_soft]# tar -xf nginx-1.12.2.tar.gz -C .. [root@client lnmp_soft ...

  6. Java Spring boot 多商户入驻 外卖|跑腿|代驾 Uniapp版本

    技术说明: 源码下载:https://www.yuanmahy.com/8357.html 开发环境:jdk1.8,mysql5.7,node 9.4,redis6.2,npm6.9 开发工具:前端使 ...

  7. 【SQLite】教程09-VBA读取SQLite数据之ODBC,及中文乱码问题

    VBA使用ODBC Driver for SQLite读SQLite 如下图有这么一个SQlite数据库,我们要读取它 需要先安装ODBC,可以从这里下载: SQLite 3 ODBC Driver ...

  8. spring boot使用@Async异步注解

    1.java的大部分接口的方法都是串行执行的,但是有些业务场景是不需要同步返回结果的,可以把结果直接返回,具体业务异步执行,也有些业务接口是需要并行获取数据,最后把数据聚合在统一返回给前端. 通常我们 ...

  9. 【题解】Luogu p2014 选课 树型dp

    题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课,每门课有个学分,每门课有一 ...

  10. Windows内核开发-Windows内部概述-1-

    Windows内部概述-1- 进程: 进程是一个程序的运行实例的控制和管理对象.一般的程序员所说进程运行,这样的说法是不对的,因为进程不能运行程序,进程只能管理该程序运行.线程才是真正的执行代码的东西 ...